using EFCore.BulkExtensions; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging.Abstractions; using Moq; using Npgsql; using NUnit.Framework; using Strata.CoreLib.Claims; using Strata.RxNorm.Biz.DbContexts; using Strata.RxNorm.Biz.Notification; using Strata.RxNorm.Biz.Pharmacy; using Strata.RxNorm.Biz.RxNorm; using System; using System.Collections.Generic; using System.IO; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; namespace Strata.RxNorm.Biz.Test.Unit.RxNorm; [TestFixture] internal class RxNormServiceTests { private RxNormDbContext _dbContext; [SetUp] public void Setup() { var builder = new NpgsqlConnectionStringBuilder() { Database = "rxnorm", Host = "localhost", Port = 5555, Username = "postgres", Password = "postgres", WriteBufferSize = 1024 * 1024 * 16 }; var options = new DbContextOptionsBuilder() .UseNpgsql(builder.ToString()) .UseSnakeCaseNamingConvention() .Options; _dbContext = new RxNormDbContext(options); } [Explicit("Make sure local database is up before running tests")] [TestCase("RXNSAT1A.RRF", TypeArgs = [typeof(RxnAttribute)], TestName = "RxnAttribute Small 50MB")] [TestCase("RXNSAT.RRF", TypeArgs = [typeof(RxnAttribute)], TestName = "RxnAttribute Big 250MB")] [TestCase("RXNCONSO.RRF", TypeArgs = [typeof(RxnConcept)], TestName = "RxnConcept 30MB")] [TestCase("RXNREL1A.RRF", TypeArgs = [typeof(RxnRelation)], TestName = "RxnRelation 50MB")] public async Task SeedTableTests(string fileName) where TEntity : class { var pharmacyUpdateService = Mock.Of(); Mock.Get(pharmacyUpdateService) .Setup(p => p.RunPharmacyUpdateClientJob(It.IsAny(), It.IsAny())) .ReturnsAsync("Success"); var rxNormService = new RxNormService(_dbContext, pharmacyUpdateService, NullLogger.Instance, Mock.Of>(), new StubClaimsPrincipalAccessor(username: "user")); const string testFileDirectory = "../../../Rrf_Files"; var fullFilePath = Path.Combine(testFileDirectory, fileName); await using var fileStream = File.OpenRead(fullFilePath); var fileSizeInMb = Math.Round(fileStream.Length / 1024.0 / 1024.0, 1); TestContext.WriteLine($"{fileName} is {fileSizeInMb} MB"); await _dbContext.TruncateAsync(cancellationToken: TestContext.CurrentContext.CancellationToken); var rowCount = await _dbContext.Set().CountAsync(TestContext.CurrentContext.CancellationToken); // make sure we start with clean slate Assert.That(rowCount, Is.Zero); await rxNormService.SeedTable(fileStream, TestContext.CurrentContext.CancellationToken); // assert that SOME rows were added rowCount = await _dbContext.Set().CountAsync(TestContext.CurrentContext.CancellationToken); Assert.That(rowCount, Is.GreaterThan(0)); } } public class StubClaimsPrincipalAccessor : IClaimsPrincipalAccessor { private readonly ClaimsPrincipal _principal; /// /// Will always return the given /// public StubClaimsPrincipalAccessor(ClaimsPrincipal principal) { _principal = principal; } /// /// Creates a with the given strata specific claims values /// and will always return that principal /// public StubClaimsPrincipalAccessor( Guid? databaseGuid = null, int? strataId = null, string username = null, Guid? userGuid = null, IEnumerable> additionalClaims = null) { var claims = new List(); if (databaseGuid.HasValue) { claims.Add(new Claim(StrataClaims.DatabaseGuid, databaseGuid.ToString())); } if (strataId.HasValue) { claims.Add(new Claim(StrataClaims.StrataId, strataId.ToString())); } if (!string.IsNullOrWhiteSpace(username)) { claims.Add(new Claim(StrataClaims.Username, username)); } if (userGuid.HasValue) { claims.Add(new Claim(StrataClaims.UserGuid, userGuid.ToString())); } if (additionalClaims != null) { foreach (var (key, value) in additionalClaims) { claims.Add(new Claim(key, value)); } } var claimsIdentity = new ClaimsIdentity(claims, "IntegrationTest"); _principal = new ClaimsPrincipal(claimsIdentity); } public ClaimsPrincipal GetCurrentClaimsPrincipal() { return _principal; } }