chore: deploy initial code base

This commit is contained in:
Thom Lamb
2026-05-12 10:34:59 -05:00
parent cbe3f6cc09
commit e826bf412b
257 changed files with 6137748 additions and 1 deletions
@@ -0,0 +1,54 @@
using Strata.RxNorm.Biz.RxNorm;
namespace Strata.RxNorm.Biz.Test.Unit.RxNorm
{
public class FlattenConso
{
public string RRxcui1 { get; set; }
public string RRxcui2 { get; set; }
public string Rxcui1 { get; set; }
public string Sab1 { get; set; }
public string Tty1 { get; set; }
public string Str1 { get; set; }
public string Rxcui2 { get; set; }
public string Sab2 { get; set; }
public string Tty2 { get; set; }
public string Str2 { get; set; }
public string Sab3 { get; set; }
public string Tty3 { get; set; }
public string Str3 { get; set; }
public string SatStype { get; set; }
public string SatAtn { get; set; }
public string SatSab { get; set; }
public string SatAtv { get; set; }
public RxnRelation RxnRelation { get; set; }
public RxnConcept[] conso { get; set; }
public RxnAttribute sat { get; set; }
public FlattenConso(RxnRelation rel, RxnConcept conso1, RxnConcept conso2, RxnConcept conso3, RxnAttribute sat)
{
RxnRelation = rel;
conso = new[] { conso1, conso2, conso3 };
this.sat = sat;
RRxcui1 = rel.Rxcui1;
RRxcui2 = rel.Rxcui2;
Rxcui1 = conso1.Rxcui;
Sab1 = conso1.Sab;
Tty1 = conso1.Tty;
Str1 = conso1.Str;
Rxcui2 = conso2?.Rxcui;
Sab2 = conso2?.Sab ?? "";
Tty2 = conso2?.Tty ?? "";
Str2 = conso2?.Str ?? "";
Sab3 = conso3?.Sab ?? "";
Tty3 = conso3?.Tty ?? "";
Str3 = conso3?.Str ?? "";
SatStype = sat?.Stype;
SatAtn = sat?.Atn;
SatSab = sat?.Sab;
SatAtv = sat?.Atv;
}
}
}
@@ -0,0 +1,141 @@
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<RxNormDbContext>()
.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<TEntity>(string fileName) where TEntity : class
{
var pharmacyUpdateService = Mock.Of<IPharmacyUpdateService>();
Mock.Get(pharmacyUpdateService)
.Setup(p => p.RunPharmacyUpdateClientJob(It.IsAny<bool>(), It.IsAny<CancellationToken>()))
.ReturnsAsync("Success");
var rxNormService = new RxNormService(_dbContext, pharmacyUpdateService, NullLogger<RxNormService>.Instance, Mock.Of<IHubContext<NotificationHub, INotificationHub>>(), 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<TEntity>(cancellationToken: TestContext.CurrentContext.CancellationToken);
var rowCount = await _dbContext.Set<TEntity>().CountAsync(TestContext.CurrentContext.CancellationToken);
// make sure we start with clean slate
Assert.That(rowCount, Is.Zero);
await rxNormService.SeedTable<TEntity>(fileStream, TestContext.CurrentContext.CancellationToken);
// assert that SOME rows were added
rowCount = await _dbContext.Set<TEntity>().CountAsync(TestContext.CurrentContext.CancellationToken);
Assert.That(rowCount, Is.GreaterThan(0));
}
}
public class StubClaimsPrincipalAccessor : IClaimsPrincipalAccessor
{
private readonly ClaimsPrincipal _principal;
/// <summary>
/// Will always return the given <see cref="ClaimsPrincipal"/>
/// </summary>
public StubClaimsPrincipalAccessor(ClaimsPrincipal principal)
{
_principal = principal;
}
/// <summary>
/// Creates a <see cref="ClaimsPrincipal"/> with the given strata specific claims values
/// and will always return that principal
/// </summary>
public StubClaimsPrincipalAccessor(
Guid? databaseGuid = null,
int? strataId = null,
string username = null,
Guid? userGuid = null,
IEnumerable<KeyValuePair<string, string>> additionalClaims = null)
{
var claims = new List<Claim>();
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;
}
}
@@ -0,0 +1,42 @@
using Strata.RxNorm.Biz.RxNorm;
using System.ComponentModel.DataAnnotations;
namespace Strata.RxNorm.Biz.Test.Unit.RxNorm
{
public class RxnComponent
{
[Key]
public int Key { get; set; }
public int AltKey { get; set; }
public string Rxcui { get; set; }
public string Rxcui2 { get; set; }
public string Description { get; set; }
public string Attribute { get; set; }
public RxnComponent()
{
}
public RxnComponent(RxnConcept concept, RxnAttribute attribute)
{
Key = int.TryParse(concept.Rxcui, out var cui) ? cui : 0;
AltKey = int.TryParse(attribute.Rxcui, out var cui2) ? cui2 : 0;
Rxcui = concept.Rxcui;
Rxcui2 = attribute.Rxcui;
Description = concept.Str;
Attribute = attribute.Atv;
}
public RxnComponent(RxnConcept concept, RxnConcept concept2)
{
Key = int.TryParse(concept.Rxcui, out var cui) ? cui : 0;
AltKey = int.TryParse(concept2.Rxcui, out var cui2) ? cui2 : 0;
Rxcui = concept.Rxcui;
Rxcui2 = concept2.Rxcui;
Description = concept.Str;
Attribute = concept2.Str;
}
}
}
@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Strata.RxNorm.Biz.Test.Unit.RxNorm
{
public class RxnComponentIngredient
{
[Key]
public int Key { get; set; }
public string ComponentRxcui { get; set; }
public string ComponentDescription { get; set; }
public string IngredientRxcui { get; set; }
public string IngredientDescription { get; set; }
public string Strength { get; set; }
}
}
@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Strata.RxNorm.Biz.Test.Unit.RxNorm
{
public class RxnGenericComponent
{
[Key]
public int Key { get; set; }
public string GenericRxcui { get; set; }
public string GenericDescription { get; set; }
public string ComponentRxcui { get; set; }
public string ComponentDescription { get; set; }
public string Strength { get; set; }
}
}
@@ -0,0 +1,30 @@
using Strata.RxNorm.Biz.RxNorm;
using System.ComponentModel.DataAnnotations;
namespace Strata.RxNorm.Biz.Test.Unit.RxNorm
{
public class Rxndata
{
[Key]
public int Key { get; set; }
public string Rxcui { get; set; }
public string Description { get; set; }
public Rxndata() { }
public Rxndata(RxnAttribute sat)
{
Key = int.TryParse(sat.Rxcui, out var cui) ? cui : 0;
Rxcui = sat.Rxcui;
Description = sat.Atv;
}
public Rxndata(RxnConcept conso)
{
Key = int.TryParse(conso.Rxcui, out var cui) ? cui : 0;
Rxcui = conso.Rxcui;
Description = conso.Str;
}
}
}
@@ -0,0 +1,402 @@
[
{
Code: 1000086,
Description: Lastacaft
},
{
Code: 1000108,
Description: Xeomin
},
{
Code: 1001473,
Description: Ecpirin
},
{
Code: 1001585,
Description: TachoSil
},
{
Code: 1001715,
Description: Zencia Wash
},
{
Code: 1005925,
Description: Ella
},
{
Code: 1006555,
Description: Clinpro 5000
},
{
Code: 1009213,
Description: Veletri
},
{
Code: 1010729,
Description: PureLax
},
{
Code: 1011084,
Description: Gas-X Prevention
},
{
Code: 1011654,
Description: Krystexxa
},
{
Code: 1011859,
Description: LMX
},
{
Code: 1011867,
Description: Thrive
},
{
Code: 1012324,
Description: Ana-Lex
},
{
Code: 1012397,
Description: Marcaine
},
{
Code: 1012462,
Description: Revonto
},
{
Code: 1012591,
Description: Regenecare
},
{
Code: 1012782,
Description: Carbocaine with NeoCobefrin
},
{
Code: 1012896,
Description: Gilenya
},
{
Code: 101306,
Description: Herceptin
},
{
Code: 1013633,
Description: Calcitrene
},
{
Code: 1013644,
Description: Cidaflex
},
{
Code: 1013931,
Description: Kapvay
},
{
Code: 1014134,
Description: SaltAire
},
{
Code: 1014606,
Description: Fisherman's Friend
},
{
Code: 1014651,
Description: Wal-Act
},
{
Code: 1014655,
Description: Wal-itin D
},
{
Code: 1020036,
Description: Sorilux
},
{
Code: 1020123,
Description: Loradamed
},
{
Code: 1037027,
Description: Doctor's Choice
},
{
Code: 1037031,
Description: Kid's Choice
},
{
Code: 1037046,
Description: Pradaxa
},
{
Code: 1037229,
Description: Hyophen
},
{
Code: 1037297,
Description: Phosphasal
},
{
Code: 1038807,
Description: Iferex
},
{
Code: 1038905,
Description: Listerine
},
{
Code: 1038918,
Description: Lantiseptic
},
{
Code: 1039035,
Description: Lantiseptic Multi-Purpose
},
{
Code: 1039066,
Description: Soothe & Cool Powder
},
{
Code: 1039169,
Description: Lanacane
},
{
Code: 1039252,
Description: Cepacol Sore Throat Plus Cough
},
{
Code: 1039270,
Description: Scalpicin Itch Relief
},
{
Code: 1039350,
Description: Vagisil Satin
},
{
Code: 1039537,
Description: Ting AF
},
{
Code: 1039547,
Description: Vagisil Wipes
},
{
Code: 1039670,
Description: Sucrets Original
},
{
Code: 1039802,
Description: Ustell
},
{
Code: 1039916,
Description: Soothe Lubricant Eye Drops
},
{
Code: 1040009,
Description: Teflaro
},
{
Code: 1040019,
Description: Acthar
},
{
Code: 1040032,
Description: Latuda
},
{
Code: 1040055,
Description: Nuedexta
},
{
Code: 1041509,
Description: Ala-Hist IR
},
{
Code: 1041513,
Description: Aloe Vesta Skin Conditioner
},
{
Code: 1041527,
Description: Ofirmev
},
{
Code: 1041531,
Description: Dendracin Neurodendraxcin
},
{
Code: 1042664,
Description: MenthoLatum
},
{
Code: 1043071,
Description: Beta-HC
},
{
Code: 1043225,
Description: Perform
},
{
Code: 1043229,
Description: Biofreeze
},
{
Code: 1043241,
Description: Head & Shoulders
},
{
Code: 1043620,
Description: Listerine Antiseptic
},
{
Code: 1044439,
Description: Luden's Drops
},
{
Code: 1044588,
Description: Egrifta
},
{
Code: 1044929,
Description: NeutrapHor
},
{
Code: 1044933,
Description: Cool bottoms
},
{
Code: 1045457,
Description: Halaven
},
{
Code: 1045538,
Description: Chloraseptic Sore Throat + Cough
},
{
Code: 1045617,
Description: Fungicure Solution
},
{
Code: 1046235,
Description: Cosamin
},
{
Code: 1046239,
Description: Schiff
},
{
Code: 1046278,
Description: Psoriasin Wash
},
{
Code: 1046284,
Description: MiniDrops
},
{
Code: 1046399,
Description: Xgeva
},
{
Code: 1047139,
Description: Axiron
},
{
Code: 1047432,
Description: Gablofen
},
{
Code: 1047505,
Description: Moxeza
},
{
Code: 1047876,
Description: Gly-Oxide
},
{
Code: 1049420,
Description: GentleLax
},
{
Code: 1050088,
Description: Boroleum
},
{
Code: 1050312,
Description: Nexiclon
},
{
Code: 1051071,
Description: Fortesta
},
{
Code: 1052413,
Description: Pamprin Max Formula
},
{
Code: 1052436,
Description: Pamprin Multi-Symptom
},
{
Code: 1052442,
Description: Pamprin Cramp Formula
},
{
Code: 1052463,
Description: Percogesic ReformuLated Jan 2011
},
{
Code: 1052617,
Description: Anbesol Cold Sore Therapy
},
{
Code: 1052638,
Description: Premsyn PMS
},
{
Code: 1052951,
Description: Aquaphor
},
{
Code: 1052997,
Description: Critic-Aid Clear Moisture
},
{
Code: 1053139,
Description: Wal-Dryl
},
{
Code: 1053143,
Description: Stye
},
{
Code: 1053155,
Description: Baza-Protect
},
{
Code: 1053197,
Description: Baza Cleanse and Protect
},
{
Code: 1053324,
Description: Stanback Headache Powder ReformuLated Jan 2011
},
{
Code: 1053336,
Description: Tanac Liquid
},
{
Code: 1053648,
Description: Abstral
},
{
Code: 1053856,
Description: Carb-O-Lac
},
{
Code: 10601,
Description: Timoptic
},
{
Code: 1085416,
Description: Active Q
}
]
@@ -0,0 +1,824 @@
using NUnit.Framework;
using NUnit.Framework.Internal;
using Strata.RxNorm.Biz.RxNorm;
using Strata.RxNorm.Biz.RxNorm.Dimensions;
using Strata.RxNorm.Biz.Test.Unit.Extensions;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using VerifyNUnit;
using VerifyTests;
namespace Strata.RxNorm.Biz.Test.Unit.RxNorm
{
[TestFixture]
public class TestRxNormBase
{
public VerifySettings VerifySetting { get; set; }
public List<RxnRelation> RxnRelations { get; set; }
public List<RxnConcept> RxnConcepts { get; set; }
public List<RxnAttribute> RxnAttributes { get; set; }
/// <summary>
/// <seealso cref="RxnConcept"/>
/// </summary>
/// <remarks>TTY == "BN"</remarks>
public IQueryable<Rxndata> BrandNames { get; set; }
/// <summary>
/// <seealso cref="RxnConcept"/>
/// </summary>
/// <remarks>TTY == "DF"</remarks>
public IQueryable<Rxndata> DoseForms { get; set; }
/// <summary>
/// <seealso cref="RxnConcept"/>
/// </summary>
/// <remarks>TTY == "DFG"</remarks>
public IQueryable<Rxndata> DoseFormGroups { get; set; }
/// <summary>
/// <seealso cref="RxnConcept"/>
/// </summary>
/// <remarks>TTY == "SCD"</remarks>
public IQueryable<Rxndata> GenericDrugs { get; set; }
/// <summary>
/// <seealso cref="RxnConcept"/>
/// </summary>
/// <remarks>TTY == "SCD"</remarks>
public IQueryable<Rxndata> SemanticBrandDrugs { get; set; }
/// <summary>
/// <seealso cref="RxnAttribute"/>
/// </summary>
/// <remarks>Atn == "NDC"</remarks>
public IQueryable<Rxndata> Ndcs { get; set; }
/// <summary>Generic Drugs</summary>
/// <remarks><see cref="RxnConcept"/> where Tty == "SCD"</remarks>
protected IEnumerable<RxnConcept> rxngenericdrugs => RxnConcepts.Where(r => r.Tty == "SCD");
/// <summary>RxnConcept where Tty == "DF"</summary>
protected IEnumerable<RxnConcept> rxndoseforms => RxnConcepts.Where(r => r.Tty == "DF");
/// <summary>RxnConcept where Tty == "DFG"</summary>
protected IEnumerable<RxnConcept> rxndoseformgroups => RxnConcepts.Where(r => r.Tty == "DFG");
/// <summary>RxnConcept where Tty == "SCDC"</summary>
protected IEnumerable<RxnConcept> rxncomponents => RxnConcepts.Where(r => r.Tty == "SCDC");
/// <summary>RxnConcept where Tty == "IN"</summary>
protected IEnumerable<RxnConcept> rxningredients => RxnConcepts.Where(r => r.Tty == "IN");
/// <summary>Brand Name</summary>
/// <remarks>RxnConcept where Tty == "BN"</remarks>
protected IEnumerable<RxnConcept> rxnbrandnames => RxnConcepts.Where(r => r.Tty == "BN");
protected IEnumerable<RxnAttribute> rxnstrengths => RxnAttributes.Where(s => s.Atn == "RXN_STRENGTH");
protected IEnumerable<RxnComponent> RxnComponents
=> from d in RxnConcepts.Where(r => r.Tty == "SCDC")
join s in RxnAttributes.Where(s => s.Atn == "RXN_STRENGTH") on d.Rxcui equals s.Rxcui
select new RxnComponent(d, s);
protected IEnumerable<RxnComponentIngredient> RxnComponentIngredients
=> from r in RxnRelations
join s in RxnAttributes.Where(s => s.Atn == "RXN_STRENGTH") on r.Rxcui1 equals s.Rxcui
join d in RxnConcepts.Where(r => r.Tty == "SCDC") on r.Rxcui1 equals d.Rxcui
into rd
from rdx in rd.DefaultIfEmpty()
join i in RxnConcepts.Where(r => r.Tty == "IN") on r.Rxcui2 equals i.Rxcui
into ri
from rix in ri.DefaultIfEmpty()
select new RxnComponentIngredient
{
Key = int.TryParse(r.Rxcui1, out var cui) ? cui : 0,
ComponentRxcui = r.Rxcui1,
IngredientRxcui = r.Rxcui2,
ComponentDescription = rdx?.Str ?? "--",
IngredientDescription = rix?.Str ?? "--",
Strength = s.Atv
};
/// <summary>SemanticBrandedDrugs, Tty == "SCD" && Tty == "SCDC"</summary>
protected IEnumerable<RxnGenericComponent> RxnGenericComponents
=> from r in RxnRelations
join g in RxnConcepts.Where(r => r.Tty == "SCD") on r.Rxcui1 equals g.Rxcui
join c in RxnConcepts.Where(r => r.Tty == "SCDC") on r.Rxcui2 equals c.Rxcui
select new RxnGenericComponent
{
Key = int.TryParse(r.Rxcui1, out var cui) ? cui : 0,
GenericRxcui = r.Rxcui1,
GenericDescription = g.Str,
ComponentRxcui = r.Rxcui2,
ComponentDescription = c.Str
};
/// <summary>SemanticBrandedDrugs, Tty == "SBD" && Tty == "SCD"</summary>
protected IEnumerable<FlattenConso> RxnSemanticBrandedDrugs
=> from r in RxnRelations
join bd in RxnConcepts.Where(r => r.Tty == "SBD") on r.Rxcui1 equals bd.Rxcui
join gd in RxnConcepts.Where(r => r.Tty == "SCD") on r.Rxcui2 equals gd.Rxcui
orderby bd.Str
select new FlattenConso(r, bd, gd, null, null);
/// <summary>BrandedDrugs, Tty == "SBD" && Tty == "BN"</summary>
protected IEnumerable<FlattenConso> BrandedDrugNames
=> from r in RxnRelations
join bd in RxnConcepts.Where(r => r.Tty == "SBD") on r.Rxcui1 equals bd.Rxcui
join bn in RxnConcepts.Where(r => r.Tty == "BN") on r.Rxcui2 equals bn.Rxcui
orderby bn.Str
select new FlattenConso(r, bn, bd, null, null);
protected IEnumerable<FlattenConso> BrandedDrugGenericDrugNames
=> from r in RxnRelations
join bd in BrandedDrugNames on r.Rxcui1 equals bd.RRxcui1
join gd in RxnConcepts.Where(r => r.Tty == "SCD") on r.Rxcui2 equals gd.Rxcui
orderby bd.Str1
select new FlattenConso(r, bd.conso[0], bd.conso[1], gd, null);
[OneTimeSetUp]
public async Task SetUpFixture()
{
VerifySetting = TestExtensions.TestSettings();
RxnConcepts = "RXNCONSO.RRF".LoadRxnConcepts().ToList();
RxnRelations = "RXNREL1A.RRF".LoadRxnRelations()
.Union("RXNREL1B.RRF".LoadRxnRelations())
.Union("RXNREL2A.RRF".LoadRxnRelations())
.Union("RXNREL2B.RRF".LoadRxnRelations())
.ToList();
RxnAttributes = "RXNSAT1A.RRF".LoadRxnAttributes()
.Union("RXNSAT1B.RRF".LoadRxnAttributes())
.Union("RXNSAT2A.RRF".LoadRxnAttributes())
.Union("RXNSAT2B.RRF".LoadRxnAttributes())
.Union("RXNSAT3A.RRF".LoadRxnAttributes())
.Union("RXNSAT3B.RRF".LoadRxnAttributes()).ToList();
BrandNames = QueryRxnConcept("BN");
DoseFormGroups = QueryRxnConcept("DFG");
DoseForms = QueryRxnConcept("DF");
SemanticBrandDrugs = QueryRxnConcept("SCD");
Ndcs = QueryRxnAttribute("NDC");
}
public IQueryable<Rxndata> QueryRxnConcept(string tty)
=> (from c in RxnConcepts
where c.Tty == tty
orderby c.Str
select new Rxndata(c)).AsQueryable();
public IQueryable<Rxndata> QueryRxnAttribute(string atn)
=> (from c in RxnAttributes
where c.Atn == atn
orderby c.Atv
select new Rxndata(c)).AsQueryable();
[TestCase("66490069110")]
public async Task TestNdc(string ndc)
{
var Relations = (from a in Ndcs.Where(n => n.Description == ndc)
//RxnAttributes.Where(ra => ra.Atn == "NDC" && ra.Atv == ndc)
join r in RxnRelations on a.Rxcui equals r.Rxcui2
join b in RxnConcepts on r.Rxcui1 equals b.Rxcui
select b);
await Verifier.Verify(Relations, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCaseSource(nameof(RxnConceptsTestCases))]
public async Task TestDimRxNormConcepts(int take, int skip, string tty)
{
IEnumerable<IRxNormConcept> concepts;
switch (tty)
{
case "BN":
concepts = RxnConcepts
.Where(c => c.Tty == tty)
.Select(x => new DimBrandName(x))
.OrderBy(x => x.Code).Skip(skip).Take(take);
break;
case "DF":
concepts = RxnConcepts
.Where(c => c.Tty == tty)
.Select(x => new DimDoseForm(x))
.OrderBy(x => x.Code).Skip(skip).Take(take);
break;
case "SBD":
concepts = RxnConcepts
.Where(c => c.Tty == tty)
.Select(x => new DimBrandedDrug(x))
.OrderBy(x => x.Code).Skip(skip).Take(take);
break;
case "SCD":
concepts = RxnConcepts
.Where(c => c.Tty == tty)
.Select(x => new DimSemanticDrug(x))
.OrderBy(x => x.Code).Skip(skip).Take(take);
break;
default:
return;
}
await Verifier.Verify(concepts, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCase(100, 0)]
public async Task TestFactNdc(int take, int skip)
{
var attributes = RxnAttributes
.Where(a => a.Atn == "NDC")
.Select(a => new FactNdc { Ndc = a.Atv })
.OrderBy(a => a.Ndc)
.Skip(skip).Take(take);
await Verifier.Verify(attributes, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCase()]
public async Task TestAdvil()
{
var dimBrandNames = RxnConcepts.Where(c => c.Tty == "BN").Select(x => new DimBrandName(x));
var brandNames = dimBrandNames.Where(c => c.Description.Contains("Advil", System.StringComparison.CurrentCultureIgnoreCase));
await Verifier.Verify(brandNames, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCase()]
public async Task TestIbuprofen()
{
var dimBrandNames = RxnConcepts.Where(c => c.Tty == "IN").Select(x => new DimBrandName(x));
var brandNames = dimBrandNames.Where(c => c.Description.Contains("Ibuprofen", System.StringComparison.CurrentCultureIgnoreCase));
await Verifier.Verify(brandNames, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCase()]
public async Task TestIbuprofenIngredients()
{
var ibuprofen = RxnConcepts
.Where(c => c.Tty == "IN" && c.Str.Contains("Ibuprofen", System.StringComparison.CurrentCultureIgnoreCase))
.ToList();
var rxcuis = ibuprofen.Select(x => x.Rxcui);
var brandNames = RxnConcepts.Where(c => c.Tty == "BN").ToList()
.Join(RxnRelations.Where(r => rxcuis.Contains(r.Rxcui2)),
b => b.Rxcui, r => r.Rxcui1, (b, r) => new { b, r })
.Join(ibuprofen,
r => r.r.Rxcui2, c => c.Rxcui, (r, b) => new DimBrandName(r.b))
.OrderBy(b => b.Description);
await Verifier.Verify(brandNames, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCase(100, 0)]
public async Task TestBrandNames(int take, int skip)
{
var dimBrandNames = RxnConcepts.Where(c => c.Tty == "BN").Select(x => new DimBrandName(x));
var brandNames = BrandNames.Skip(skip).Take(take).ToList();
await Verifier.Verify(brandNames, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCaseSource(nameof(RxnConceptsTestCases))]
public async Task TestRxcuiCode(int take, int skip, string tty)
{
if (take > 0)
{
var rxnConcepts = RxnConcepts
.Where(c => (c.Tty == tty || string.IsNullOrEmpty(tty)) && c.Code != c.Rxcui)
.Skip(skip).Take(take).ToList();
await Verifier.Verify(rxnConcepts, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
return;
}
var concepts = RxnConcepts
.Where(c => c.Code != c.Rxcui)
.GroupBy(c => c.Tty, (TTY, concepts) => new ConceptGroup
{
Tty = TTY,
Concepts = concepts.Select(c => new ConceptDump(c))
.OrderBy(c => c.Code)
.ThenBy(c => c.Rxcui)
});
await Verifier.Verify(concepts, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
internal class ConceptGroup
{
public string Tty { get; set; }
public IEnumerable<ConceptDump> Concepts { get; set; }
}
internal class ConceptDump
{
public string Rxcui { get; set; }
public string Code { get; set; }
public ConceptDump(RxnConcept concept)
{
Rxcui = concept.Rxcui;
Code = concept.Code;
}
}
public static IEnumerable<TestCaseData> RxnConceptsTestCases()
{
yield return new TestCaseData(0, 0, "")
.SetName("{m} Generic");
yield return new TestCaseData(100, 0, "BN")
.SetName("{m} " + nameof(DimBrandName));
yield return new TestCaseData(100, 0, "DF")
.SetName("{m} " + nameof(DimDoseForm));
yield return new TestCaseData(100, 0, "SBD")
.SetName("{m} " + nameof(DimBrandedDrug));
yield return new TestCaseData(100, 0, "SCD")
.SetName("{m} " + nameof(DimSemanticDrug));
}
[TestCase(100, 0)]
public async Task TestNdcs(int take, int skip)
{
var ndcs = Ndcs.Skip(skip).Take(take).ToList();
await Verifier.Verify(ndcs, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCase()]
public async Task TestConceptTypes()
{
var conceptTypes = RxnConcepts
.GroupBy(c => c.Tty, (Tty, d) => new { Tty, Count = d.Count() })
.OrderBy(c => c.Tty).ToList();
await Verifier.Verify(conceptTypes, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCase()]
/// <summary>
/// Populate the rxngenericdrugs table:
/// - Extract Generic Drug Descriptions
/// -- Identify all Semantic Clinical Drug Terms in the concepts table by looking for TTY(Term Type) SCD
/// -- Extract these rows, interpreting Rxcui as GenericRxcui and Description as GenericDrugDescription
/// - Extract Dose Forms
/// -- Identify all Dose Form Terms in the concepts table by looking for TTY(Tevarrm Type) DF
/// -- Extract these rows, interpreting Rxcui as DoseFormRxcui and Description as DoseFormDescription
/// - Complete Generic Drugs table by adding dose form
/// -- Limit CUI Relations table to rows where Rxcui1 has type SCD and Rxcui2 has type DF
/// -- Extract these rows, intepreting Rxcui1 as GenericRxcui and Rxcui2 as DoseFormRxcui
/// -- Join the above to Generic Drug Descriptions, keeping GenericRxcui, GenericDrugDescription, and DoseFormRxcui
/// </summary>
public async Task Populate_the_rxngenericdrugs_table()
{
var genericDrugDescriptions = rxngenericdrugs.Select(r => new Rxndata(r)).OrderBy(r => r.Description);
var doseForms = rxndoseforms.Select(r => new Rxndata(r)).OrderBy(r => r.Description);
var genericDrugs =
from r in RxnRelations
join gd in rxngenericdrugs on r.Rxcui1 equals gd.Rxcui
join df in rxndoseforms on r.Rxcui2 equals df.Rxcui
select new
{
GenericRxcui = gd.Rxcui,
GernericDrugDescription = gd.Str,
DoseFormRxcui = df.Rxcui,
DoseForm = df.Str
};
await Verifier.Verify(genericDrugDescriptions.ToList(), VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName(nameof(genericDrugDescriptions)));
await Verifier.Verify(doseForms.ToList(), VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName(nameof(doseForms)));
await Verifier.Verify(genericDrugs.ToList(), VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName(nameof(genericDrugs)));
}
[TestCase()]
/// <summary>
/// Populate Components and Ingredients
/// - Populate Ingredients Table
/// -- Identify all <c>RxnConcept</c>s with TTY(Term Type) IN
/// -- Extract these rows, interpreting Rxcui as IngredientRxcui and Description as IngredientDescription
/// - Populate Components Table
/// -- Get Component Descriptions
/// --- Identify all concepts with TTY(Term Type) SCDC(Semantic Clinical Drug Component)
/// --- Extract these rows, interpreting Rxcui as ComponentRxcui and Description as ComponentDescription
/// -- Get Component Strengths
/// --- Identify all attribute rows the Rxcui has TTY SCDC and where Atn(Attribute Name) is RXN_STRENGTH
/// --- Extract these rows, interpreting Rxcui as ComponentRxcui and Atv(Attribute Value) as Strength
/// -- Get Component Ingredients
/// --- Identify all rows in cui_Relations where Rxcui1 has TTY SCDC and Rxcui2 has TTY IN
/// --- Extract these rows, interpreting Rxcui1 as ComponentRxcui and Rxcui2 as IngredientRxcui
/// -- Complete Components Table
/// --- Every ComponentRxcui should have one ComponentDescription, one Strength, and one IngredientRxcui.
/// --- The table should have these four columns
/// </summary>
public async Task Populate_Components_and_Ingrediaents()
{
var ingredients = rxningredients.Select(r => new Rxndata(r)).OrderBy(r => r.Description);
var componentDescriptions = rxncomponents.Select(r => new Rxndata(r)).OrderBy(r => r.Description);
var strengths = rxnstrengths.Select(r => new Rxndata(r)).OrderBy(r => r.Description);
var componentStrengths =
from r in RxnRelations
join c in rxncomponents on r.Rxcui1 equals c.Rxcui
join s in rxnstrengths on r.Rxcui2 equals s.Rxcui
select new RxnComponent(c, s);
var componentIngredients =
from r in RxnRelations
join c in rxncomponents on r.Rxcui1 equals c.Rxcui
join s in rxningredients on r.Rxcui2 equals s.Rxcui
select new RxnComponent(c, s);
var components =
from c in componentDescriptions
join s in componentStrengths on c.Key equals s.Key into cs
from csx in cs.DefaultIfEmpty()
join i in componentIngredients on c.Key equals i.Key into ci
from cix in ci.DefaultIfEmpty()
orderby (cix?.Rxcui2 == null ? 1 : 0), csx?.Attribute
select new
{
c.Key,
ComponentRxcui = c?.Rxcui,
ComponentDescription = c?.Description,
IngredientRxcui = cix?.Rxcui2,
Strength = csx?.Attribute
};
await Verifier.Verify(ingredients, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName(nameof(ingredients)));
await Verifier.Verify(componentDescriptions, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName(nameof(componentDescriptions)));
await Verifier.Verify(componentStrengths, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName(nameof(componentStrengths)));
await Verifier.Verify(componentIngredients, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName(nameof(componentIngredients)));
await Verifier.Verify(components, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName(nameof(components)));
}
[TestCase()]
/// <summary>
/// Populate Generic Drug Components Table
/// - Limit CUI Relations to rows where Rxcui1 has TTY SCD and Rxcui2 has TTY SCDC
/// - Extract these rows, interpreting Rxcui1 as GenericRxcui and Rxcui2 as ComponentRxcui
/// </summary>
public async Task Populate_Generic_Drug_Components_Table()
{
var genericDrugDescriptions = rxngenericdrugs.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList();
var doseForms = rxndoseforms.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList();
var genericDrugs =
from r in RxnRelations
join gd in rxngenericdrugs on r.Rxcui1 equals gd.Rxcui
join df in rxndoseforms on r.Rxcui2 equals df.Rxcui
select new RxnComponent(gd, df);
var ingredients = rxningredients.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList();
var componentDescriptions = rxncomponents.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList();
var strengths = rxnstrengths.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList();
var componentStrengths =
from s in rxnstrengths
join c in rxncomponents on s.Rxcui equals c.Rxcui
select new RxnComponent(c, s);
var componentIngredients =
from r in RxnRelations
join c in rxncomponents on r.Rxcui1 equals c.Rxcui
join i in rxningredients on r.Rxcui2 equals i.Rxcui
select new RxnComponent(c, i);
var components =
from c in componentDescriptions
join s in componentStrengths on c.Key equals s.Key into cs
from csx in cs.DefaultIfEmpty()
join i in componentIngredients on c.Key equals i.Key into ci
from cix in ci.DefaultIfEmpty()
select new { c, csx, cix };
var genericComponents =
from r in RxnRelations
join g in genericDrugs on r.Rxcui1 equals g.Rxcui
join c in components on r.Rxcui2 equals c.c.Rxcui
select new
{
ComponentRxcui = r.Rxcui2,
GenericRxcui = r.Rxcui1
};
await Verifier.Verify(genericComponents, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCase()]
/// <summary>
/// Populate Branded Drug Tables
/// - Populate Brand Names
/// -- Limit concepts to terms with TTY(Term Type) BN(Brand Name)
/// -- Extract these rows, interpreting Rxcui as BrandNameRxcui and Description as BrandName
/// - Populate Branded Drugs
/// -- Get Branded Drug Descriptions
/// --- Limit concepts to terms with TTY(Term Type) SBD(Semantic Branded Drug)
/// --- Extract these rows, interpreting Rxcui as BrandedDrugRxcui and Description as BrandedDrugDescription
/// -- Get Branded Drug Generic Drugs
/// --- Limit CUI Relations to rows where Rxcui1 has TTY SBD and Rxcui2 has TTY SCD
/// --- Extract these rows, interpreting Rxcui1 as BrandedDrugRxcui and Rxcui2 as GenericRxcui
/// -- Get Branded Drug Brand Names
/// --- Limit CUI Relations to rows where Rxcui has TTY SBD and Rxcui2 as TTY BN
/// --- Extract these rows, interpreting Rxcui1 as BrandedDrugRxcui and Rxcui2 as BrandNameRxcui
/// -- Get Branded Drug Dose Forms
/// --- Join Branded Drug Generic Drugs to Generic Drugs on GenericRxcui
/// --- Get DoseFormRxcui for each BrandedDrugRxcui
/// -- Combine Information to get columns
/// --- BrandedDrugRxcui
/// --- BrandedDrugDescription
/// --- GenericRxcui
/// --- GenericDrugDescription
/// --- BrandNameRxcui
/// --- DoseFormRxcui
/// </summary>
public async Task Populate_Branded_Drug_Tables()
{
var Bn = (from c in RxnConcepts where c.Tty == "BN" select new { BrandName = c.Str, BrandNameRxcui = c.Rxcui });
var Bdd = (from c in RxnConcepts where c.Tty == "SBD" select new { BrandedDrugName = c.Str, BrandedDrugRxcui = c.Rxcui });
var BdGd = (from r in RxnRelations
join c1 in RxnConcepts.Where(c => c.Tty == "SBD") on r.Rxcui1 equals c1.Rxcui
join c2 in RxnConcepts.Where(c => c.Tty == "SCD") on r.Rxcui2 equals c2.Rxcui
select new
{
BrandedDrugRxcui = r.Rxcui1,
BrandedDrugName = c1.Str,
GenericRxcui = r.Rxcui2,
GenericDrugName = c2.Str
});
var Gdd = (from c in RxnConcepts where c.Tty == "SCD" select new { GenericDrugName = c.Str, GenericRxcui = c.Rxcui });
var Df = (from c in RxnConcepts where c.Tty == "DF" select new { DoseFormDescription = c.Str, DoseFormRxcui = c.Rxcui });
var Gd = (from r in RxnRelations
join gd in Gdd on r.Rxcui1 equals gd.GenericRxcui
join df in Df on r.Rxcui2 equals df.DoseFormRxcui
select new
{
gd.GenericRxcui,
gd.GenericDrugName,
df.DoseFormRxcui,
DoseForm = df.DoseFormDescription
});
var BdBn = (from r in RxnRelations
join c1 in RxnConcepts.Where(c => c.Tty == "SBD") on r.Rxcui1 equals c1.Rxcui
join c2 in RxnConcepts.Where(c => c.Tty == "BN") on r.Rxcui2 equals c2.Rxcui
select new
{
BrandedDrugRxcui = r.Rxcui1,
BrandedDrugName = c1.Str,
BrandNameRxcui = r.Rxcui2,
BrandName = c2.Str
});
var BrandedDrugDoseForms = (
from bdgd in BdGd
join bn in BdBn on bdgd.BrandedDrugRxcui equals bn.BrandedDrugRxcui into bnj
from bnji in bnj.DefaultIfEmpty()
join g in Gd on bdgd.GenericRxcui equals g.GenericRxcui into gj
from gji in gj.DefaultIfEmpty()
join n in Ndcs on bdgd.BrandedDrugRxcui equals n.Rxcui into nj
from nji in nj.DefaultIfEmpty()
//where bnji == null
orderby bnji?.BrandName, bdgd.BrandedDrugName, gji?.DoseForm
select new
{
Ndc = nji?.Description,
BrandName = bnji?.BrandName ?? "Generic",
bdgd.BrandedDrugName,
gji?.GenericDrugName,
gji?.DoseForm,
bnji?.BrandNameRxcui,
bdgd.BrandedDrugRxcui,
gji?.GenericRxcui,
gji?.DoseFormRxcui,
//Strength = s.Description
});
await Verifier.Verify(BrandedDrugDoseForms, VerifySetting)
.UseFileName(TestContext.CurrentContext.TestName());
}
[TestCase(10, 0)]
public async Task PublishFactRxNorm(int take, int skip)
{
var ndcDoseForms =
from rel in RxnRelations
join ndc in RxnAttributes.Where(a => a.Atn == "NDC") on rel.Rxcui1 equals ndc.Rxcui
join df in RxnConcepts.Where(c => c.Tty == "DF") on rel.Rxcui2 equals df.Rxcui
select new
{
NDC = ndc.Atv,
NdcCode = ndc.Code,
DoseForm = df.Str,
DoseFormCode = df.Code,
NdcRxcui = rel.Rxcui1,
DoseFormRxcui = rel.Rxcui2,
rel.Rel
};
var SemanticClinicalDrugName =
from r in RxnRelations
join c1 in RxnConcepts.Where(c => c.Tty == "SCD") on r.Rxcui1 equals c1.Rxcui
join c2 in RxnConcepts.Where(c => c.Tty == "SBD") on r.Rxcui2 equals c2.Rxcui
select new
{
SemanticClinicalDrugRxcui = r.Rxcui1,
SemanticClinicalDrugName = c1.Str,
SemanticClinicalDrugCode = c1.Code,
SemanticClinicalNameRxcui = r.Rxcui2,
SemanticClinicalName = c2.Str,
SemanticClinicalCode = c2.Code
};
var SemanticBrandBrandName =
from r in RxnRelations
join c1 in RxnConcepts.Where(c => c.Tty == "SBD") on r.Rxcui1 equals c1.Rxcui
join c2 in RxnConcepts.Where(c => c.Tty == "BN") on r.Rxcui2 equals c2.Rxcui
select new
{
BrandedDrugRxcui = r.Rxcui1,
BrandedDrugName = c1.Str,
BrandedDrugCode = c1.Code,
BrandNameRxcui = r.Rxcui2,
BrandName = c2.Str,
BrandCode = c2.Code
};
var ndcDoseFormBrands =
from rel in RxnRelations
join ndc in ndcDoseForms on rel.Rxcui1 equals ndc.NdcRxcui
join b in RxnConcepts.Where(c => c.Tty == "BN") on rel.Rxcui2 equals b.Rxcui into ndcb
from ndcj in ndcb.DefaultIfEmpty()
join sbd in SemanticBrandBrandName on rel.Rxcui2 equals sbd.BrandedDrugRxcui into sbds
from sbdj in sbds.DefaultIfEmpty()
select new
{
ndc.NDC,
ndc.NdcCode,
ndc.DoseForm,
ndc.DoseFormCode,
Brand = ndcj?.Str ?? "Not Specified",
BrandCode = ndcj?.Code ?? "Not Specified",
ndc.NdcRxcui,
ndc.DoseFormRxcui,
BrandRxcui = ndcj?.Rxcui ?? "",
};
var ndcDFBSBD =
from rel in RxnRelations
join ndc in ndcDoseFormBrands on rel.Rxcui1 equals ndc.NdcRxcui
join sbd in SemanticBrandBrandName on rel.Rxcui2 equals sbd.BrandedDrugRxcui into ndcs
from ndcj in ndcs.DefaultIfEmpty()
select new
{
ndc.NDC,
ndc.NdcCode,
ndc.DoseForm,
ndc.DoseFormCode,
ndc.Brand,
ndc.BrandCode,
SemanticBrand = ndcj?.BrandedDrugName ?? "Not Specified",
SemanticBrandCode = ndcj?.BrandedDrugCode ?? "Not Specified",
SemanticBrandName = ndcj?.BrandName ?? "Not Specified",
SemanticBrandNameCode = ndcj?.BrandCode ?? "Not Specified",
ndc.NdcRxcui,
ndc.DoseFormRxcui,
ndc.BrandRxcui,
SemanticBrandRxcui = ndcj?.BrandedDrugRxcui ?? "",
SemanticBrandNameRxcui = ndcj?.BrandNameRxcui ?? "",
};
var ndcDFBSBDSCD =
from rel in RxnRelations
join ndc in ndcDFBSBD on rel.Rxcui1 equals ndc.NdcRxcui
join sbd in SemanticClinicalDrugName on rel.Rxcui2 equals sbd.SemanticClinicalDrugRxcui
select new
{
ndc.NDC,
ndc.NdcCode,
ndc.DoseForm,
ndc.DoseFormCode,
ndc.Brand,
ndc.BrandCode,
ndc.SemanticBrand,
ndc.SemanticBrandCode,
ndc.SemanticBrandName,
ndc.SemanticBrandNameCode,
SemanticClinicalBrand = sbd.SemanticClinicalDrugName,
SemanticClinicalBrandCode = sbd.SemanticClinicalDrugCode,
SemanticClinicalBrandName = sbd.SemanticClinicalName,
SemanticClinicalBrandNameCode = sbd.SemanticClinicalCode,
ndc.NdcRxcui,
ndc.DoseFormRxcui,
ndc.BrandRxcui,
ndc.SemanticBrandRxcui,
ndc.SemanticBrandNameRxcui,
SemanticClinicalBrandRxcui = sbd.SemanticClinicalDrugRxcui,
SemanticClinicalBrandNameRxcui = sbd.SemanticClinicalNameRxcui,
};
await Verifier.Verify(ndcDFBSBDSCD
.Where(b => b.Brand != "Not Specified" && b.SemanticBrand != "Not Specified")
.OrderBy(b => b.NDC)
.ThenBy(b => b.DoseFormCode)
.ThenBy(b => b.BrandCode)
.Distinct()
.Skip(skip).Take(take), VerifySetting)
.UseFileName(TestContext.CurrentContext?.TestName());
}
internal class CheckForDuplicate
{
public string Code { get; set; }
public IEnumerable<string> Names { get; set; }
public CheckForDuplicate(string code, IEnumerable<string> names)
{
Code = code;
Names = names;
}
}
internal class DuplicateCheck
{
public IEnumerable<CheckForDuplicate> Duplicates { get; set; }
public int DuplicateCount { get; set; }
public DuplicateCheck(IEnumerable<CheckForDuplicate> items)
{
DuplicateCount = items.Count(x => x.Names.Count() > 1);
Duplicates = items.Where(x => x.Names.Count() > 1);
}
}
[TestCase()]
public async Task CheckForDuplicateBrands()
{
var items = RxnConcepts.Where(b => b.Tty == "BN")
.GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Str)))
.OrderBy(x => x.Code)
.ToList();
var check = new DuplicateCheck(items);
await Verifier.Verify(check, VerifySetting)
.UseFileName(TestContext.CurrentContext?.TestName());
}
[TestCase()]
public async Task CheckForDuplicateDoseForms()
{
var items = RxnConcepts.Where(b => b.Tty == "DF")
.GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Str)))
.OrderBy(x => x.Code)
.ToList();
var check = new DuplicateCheck(items);
await Verifier.Verify(check, VerifySetting)
.UseFileName(TestContext.CurrentContext?.TestName());
}
[TestCase()]
public async Task CheckForDuplicateSemanticClinicalDrugs()
{
var items = RxnConcepts.Where(b => b.Tty == "SCD")
.GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Str)))
.OrderBy(x => x.Code)
.ToList();
var check = new DuplicateCheck(items);
await Verifier.Verify(check, VerifySetting)
.UseFileName(TestContext.CurrentContext?.TestName());
}
[TestCase()]
public async Task CheckForDuplicateSemanticBrandedDrugs()
{
var items = RxnConcepts.Where(b => b.Tty == "SBD")
.GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Str)))
.OrderBy(x => x.Code)
.ToList();
var check = new DuplicateCheck(items);
await Verifier.Verify(check, VerifySetting)
.UseFileName(TestContext.CurrentContext?.TestName());
}
[TestCase(100, 0)]
public async Task CheckForDuplicateNDCs(int take, int skip)
{
var items = RxnAttributes.Where(b => b.Atn == "NDC")
.GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Atv)))
.OrderBy(x => x.Code)
.Skip(skip).Take(take)
.ToList();
var check = new DuplicateCheck(items);
await Verifier.Verify(check, VerifySetting)
.UseFileName(TestContext.CurrentContext?.TestName());
}
}
}