Skip to content

Commit

Permalink
test(app): improve report test
Browse files Browse the repository at this point in the history
  • Loading branch information
tamslo committed Sep 25, 2024
1 parent 80cfdce commit d72ecec
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:app/common/models/drug/drug.dart';
import 'package:app/common/models/drug/guideline.dart';
import 'package:app/common/models/drug/warning_level.dart';

import '../guidelines/ibuprofen_cyp2c9_normal.dart';

final ibuprofenWithProperGuideline = Drug(
id: '6407768b92a4868065b6c466',
Expand All @@ -19,26 +19,6 @@ final ibuprofenWithProperGuideline = Drug(
'Vicoprofen',
]),
guidelines: [
Guideline(
id: '64552859a1b68082babc8c31',
version: 1,
lookupkey: {
'CYP2C9': ['2.0']
},
externalData: [
GuidelineExtData(
source: 'CPIC',
guidelineName: 'CYP2C9 and NSAIDs',
guidelineUrl: 'https://cpicpgx.org/guidelines/cpic-guideline-for-nsaids-based-on-cyp2c9-genotype/',
implications: {'CYP2C9': 'Normal metabolism'},
recommendation: 'Initiate therapy with recommended starting dose. In accordance with the prescribing information, use the lowest effective dosage for shortest duration consistent with individual patient treatment goals.',
comments: 'n/a')
],
annotations: GuidelineAnnotations(
implication: 'You break down ibuprofen as expected.',
recommendation: 'You can use ibuprofen at standard dose. Consult your pharmacist or doctor for more information.',
warningLevel: WarningLevel.green,
),
),
ibuprofenCyp2c9NormalGuideline,
],
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'package:app/common/models/drug/drug.dart';
import 'package:app/common/models/drug/guideline.dart';
import 'package:app/common/models/drug/warning_level.dart';

final oxcarbazepineWithHlab1502Guideline = Drug(
id: '6407768c92a4868065b6ceb6',
version: 1,
name: 'oxcarbazepine',
rxNorm: 'RxNorm:32624',
annotations: DrugAnnotations(
drugclass: 'Anti-seizure',
indication: 'Oxcarbazepine is an anti-epileptic used to prevent seizures.',
brandNames: ['Oxtellar', 'Trileptal'],
),
guidelines: [
Guideline(
id: '64552859a1b68082babc8dc6',
version: 1,
lookupkey: {
'HLA-B': ['*15:02 negative'],
},
externalData: [
GuidelineExtData(
source: 'CPIC',
guidelineName: 'HLA-A, HLA-B and Carbamazepine and Oxcarbazepine',
guidelineUrl: 'https://cpicpgx.org/guidelines/guideline-for-carbamazepine-and-hla-b/',
implications: {
'HLA-B': 'Normal risk of oxcarbazepine-induced SJS/TEN',
},
recommendation: 'Use oxcarbazepine per standard dosing guidelines.',
comments: 'n/a',
),
],
annotations: GuidelineAnnotations(
implication: 'You have a normal risk for side effects.',
recommendation: 'You can use oxcarbazepine at standard dose. Consult your pharmacist or doctor for more information.',
warningLevel: WarningLevel.green,
),
),
],
);
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:app/common/models/drug/drug.dart';
import 'package:app/common/models/drug/guideline.dart';
import 'package:app/common/models/drug/warning_level.dart';

import '../guidelines/pazopanib_hlab5701_positive_ugt1a1_poor_guideline.dart';
import '../guidelines/pazopanib_hlab5701_positive_ugt1a1_poor.dart';

final pazopanibWithMultipleAnyNotHandledFallbackGuidelines = Drug(
id: '6686a865826414ec5b05c44e',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:app/common/models/drug/guideline.dart';
import 'package:app/common/models/drug/warning_level.dart';

final ibuprofenCyp2c9NormalGuideline = Guideline(
id: '64552859a1b68082babc8c31',
version: 1,
lookupkey: {
'CYP2C9': ['2.0']
},
externalData: [
GuidelineExtData(
source: 'CPIC',
guidelineName: 'CYP2C9 and NSAIDs',
guidelineUrl: 'https://cpicpgx.org/guidelines/cpic-guideline-for-nsaids-based-on-cyp2c9-genotype/',
implications: {'CYP2C9': 'Normal metabolism'},
recommendation: 'Initiate therapy with recommended starting dose. In accordance with the prescribing information, use the lowest effective dosage for shortest duration consistent with individual patient treatment goals.',
comments: 'n/a')
],
annotations: GuidelineAnnotations(
implication: 'You break down ibuprofen as expected.',
recommendation: 'You can use ibuprofen at standard dose. Consult your pharmacist or doctor for more information.',
warningLevel: WarningLevel.green,
),
);
29 changes: 19 additions & 10 deletions app/integration_test/fixtures/set_app_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ void setUserDataForGuideline(
Guideline guideline, {
List<String>? explicitNoResult,
Map<String, String>? explicitLookups,
bool missingLookup = false,
}) {
UserData.instance.labData = UserData.instance.labData ?? [];
for (final gene in guideline.lookupkey.keys) {
Expand Down Expand Up @@ -49,9 +50,9 @@ void setUserDataForGuideline(
// multiple HLA-B variants in the tests or overwrite a specific HLA-B
// variant, we will need to check for the genotype key (which is in the
// current setup not possible without the proper variant)
final lookupIsMissing = lookupkey == SpecialLookup.noResult.value ||
final resultIsMissing = lookupkey == SpecialLookup.noResult.value ||
(explicitNoResult?.contains(gene) ?? false);
if (!lookupIsMissing) {
if (!resultIsMissing) {
UserData.instance.labData = UserData.instance.labData!.filter(
(labResult) => labResult.gene != gene
).toList();
Expand All @@ -68,7 +69,7 @@ void setUserDataForGuideline(
phenotype: userDataConfig.phenotype,
variant: userDataConfig.variant,
allelesTested: userDataConfig.variant,
lookupkey: userDataConfig.lookupkey,
lookupkey: missingLookup ? null : userDataConfig.lookupkey,
));
}
}
Expand All @@ -85,15 +86,23 @@ void addDrugToDrugsWithGuidelines(Drug drug) {

void setAppData({
required Drug drug,
required Guideline guideline,
Guideline? guideline,
List<String>? explicitNoResult,
Map<String, String>? explicitLookups,
bool missingLookup = false,
}) {
addDrugToDrugsWithGuidelines(drug);
initializeGenotypeResultKeys().values.forEach(setGenotypeResult);
setUserDataForGuideline(
guideline,
explicitNoResult: explicitNoResult,
explicitLookups: explicitLookups,
);
for (final noResultGenotypeResult in initializeGenotypeResultKeys().values) {
if (drug.guidelineGenotypes.contains(noResultGenotypeResult.key.value)) {
setGenotypeResult(noResultGenotypeResult);
}
}
if (guideline != null) {
setUserDataForGuideline(
guideline,
explicitNoResult: explicitNoResult,
explicitLookups: explicitLookups,
missingLookup: missingLookup,
);
}
}
117 changes: 99 additions & 18 deletions app/integration_test/report_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:provider/provider.dart';

import 'fixtures/drugs/aripiprazole_with_any_not_handled_guideline.dart';
import 'fixtures/drugs/ibuprofen_with_proper_guideline.dart';
import 'fixtures/drugs/oxcarbazepine_with_hlab1502_guideline.dart';
import 'fixtures/drugs/pazopanib_with_multiple_any_not_handled_fallback_guidelines.dart';
import 'fixtures/guidelines/aripiprazole_cyp2d6_poor.dart';
import 'fixtures/guidelines/pazopanib_hlab5701_positive_ugt1a1_poor_guideline.dart';
import 'fixtures/guidelines/ibuprofen_cyp2c9_normal.dart';
import 'fixtures/guidelines/pazopanib_hlab5701_positive_ugt1a1_poor.dart';
import 'fixtures/set_app_data.dart';

void main() {
Expand Down Expand Up @@ -42,19 +47,50 @@ void main() {
);
}

Finder findGeneCard(String gene) {
return find.ancestor(
of: find.textContaining(gene, skipOffstage: false),
matching: find.byType(GeneCard, skipOffstage: false),
);
}

Future<void> testReportContent(
WidgetTester tester, {
required List<Guideline> expectedGuidelines,
required List<GenotypeResult> missingResults,
required Map<Drug, Guideline?> testData,
Map<Drug, Guideline>? missingLookupData,
}) async {
expectedGuidelines.forEach(setUserDataForGuideline);
missingResults.forEach(setGenotypeResult);
for (final drug in testData.keys) {
setAppData(drug: drug, guideline: testData[drug]);
}
if (missingLookupData != null) {
for (final drug in missingLookupData.keys) {
setAppData(
drug: drug,
guideline: missingLookupData[drug],
missingLookup: true,
);
}
}
await loadReportPage(tester);
final expectedGenes = [
...expectedGuidelines.flatMap(
final expectedGenesWithGuidelines = testData.values.filterNotNull().flatMap(
(guideline) => guideline.lookupkey.keys
);
final expectedGenesWithUnmappableGuideline =
missingLookupData?.values.flatMap(
(guideline) => guideline.lookupkey.keys
),
...missingResults.map((genotypeResult) => genotypeResult.gene),
) ?? [];
final expectedNotTestedGenes = testData.keys.filter(
(drug) => testData[drug] == null
).map(
(drug) => UserData.instance.genotypeResults![GenotypeKey(
drug.guidelines.first.lookupkey.keys.first,
drug.guidelines.first.lookupkey.values.first.first,
).value]?.gene
).filterNotNull();
final expectedGenes = <String>[
...expectedGenesWithGuidelines,
...expectedGenesWithUnmappableGuideline,
...expectedNotTestedGenes,
];
expect(
find.byType(GeneCard, skipOffstage: false),
Expand All @@ -68,23 +104,68 @@ void main() {
findsNWidgets(expectedGeneOccurrences),
);
}
if (missingLookupData != null) {
for (final guideline in missingLookupData.values) {
for (final lookup in guideline.lookupkey.entries) {
final gene = lookup.key;
final testPhenotype = lookup.value.first;
final geneCard = findGeneCard(gene);
expect(
find.descendant(
of: geneCard,
matching: find.text(testPhenotype, skipOffstage: false)
),
findsOneWidget,
);
}
}
}
final context = tester.element(find.byType(Scaffold).first);
if (expectedNotTestedGenes.isNotEmpty) {
expect(
find.text(context.l10n.report_no_result_genes, skipOffstage: false),
findsOneWidget,
);
for (final gene in expectedNotTestedGenes) {
final geneCardsFinder = findGeneCard(gene);
expect(
find.descendant(
of: geneCardsFinder,
matching:
find.text(context.l10n.general_not_tested, skipOffstage: false),
skipOffstage: false,
),
findsOneWidget,
);
final geneCard = tester.widgetList(geneCardsFinder).last as GeneCard;
expect(geneCard.color, PharMeTheme.onSurfaceColor);
}
} else {
expect(
find.text(context.l10n.report_no_result_genes, skipOffstage: false),
findsNothing,
);
}
}

group('integration test for the report page', () {
testWidgets(
'tests that genes for drugs with guidelines are shown',
(tester) async {
final expectedGuidelines = [
aripiprazoleCyp2d6PoorGuideline,
pazopanibHlab5701PositiveUgt1a1PoorGuideline,
];
final missingResults = [
GenotypeResult.missingResult('HLA-B', variant: '*15:02'),
];
final testData = {
aripiprazoleWithAnyNotHandledFallbackGuideline:
aripiprazoleCyp2d6PoorGuideline,
pazopanibWithMultipleAnyNotHandledFallbackGuidelines:
pazopanibHlab5701PositiveUgt1a1PoorGuideline,
oxcarbazepineWithHlab1502Guideline: null,
};
final missingLookupData = {
ibuprofenWithProperGuideline: ibuprofenCyp2c9NormalGuideline,
};
await testReportContent(
tester,
expectedGuidelines: expectedGuidelines,
missingResults: missingResults,
testData: testData,
missingLookupData: missingLookupData,
);
},
);
Expand Down
7 changes: 6 additions & 1 deletion app/lib/report/pages/report.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ class GeneCard extends StatelessWidget {
final GenotypeResult genotypeResult;
final WarningLevelCounts warningLevelCounts;

@visibleForTesting
Color? get color => _hasNoResult(genotypeResult)
? PharMeTheme.onSurfaceColor
: _getHighestSeverityColor(warningLevelCounts);

Color? _getHighestSeverityColor(WarningLevelCounts warningLevelCounts) {
final sortedWarningLevels = WarningLevel.values.sortedByDescending(
(warningLevel) => warningLevel.severity
Expand All @@ -138,7 +143,7 @@ class GeneCard extends StatelessWidget {
GeneRoute(genotypeResult: genotypeResult)
),
radius: 16,
color: _hasNoResult(genotypeResult) ? PharMeTheme.onSurfaceColor : _getHighestSeverityColor(warningLevelCounts),
color: color,
child: IntrinsicHeight(child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expand Down
5 changes: 5 additions & 0 deletions pharme.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"Backupper",
"brandnames",
"bupropion",
"Carbamazepine",
"cinacalcet",
"citalopram",
"clopidogrel",
Expand Down Expand Up @@ -89,6 +90,8 @@
"noto",
"NSAID",
"omeprazole",
"oxcarbazepine",
"Oxtellar",
"pantoprazole",
"paroxetine",
"pazopanib",
Expand Down Expand Up @@ -118,6 +121,8 @@
"tacrolimus",
"terbinafine",
"tramadol",
"Trileptal",
"Unmappable",
"unscrollable",
"unstage",
"unstaged",
Expand Down

0 comments on commit d72ecec

Please sign in to comment.