diff --git a/app/integration_test/drugs_test.dart b/app/integration_test/drugs_test.dart index d90b1a61..90e1113b 100644 --- a/app/integration_test/drugs_test.dart +++ b/app/integration_test/drugs_test.dart @@ -15,6 +15,22 @@ import 'fixtures/drugs/warfarin_with_any_fallback_guideline.dart'; import 'fixtures/set_app_data.dart'; import 'mocks/drug_cubit.dart'; +class _TestCase { + _TestCase({ + required this.description, + required this.drug, + this.expectNoMappedGuidelines = false, + this.explicitNoResult, + this.explicitLookups, + }); + + final String description; + final Drug drug; + final bool expectNoMappedGuidelines; + final List? explicitNoResult; + final Map? explicitLookups; +} + void main() { final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.onlyPumps; @@ -36,15 +52,22 @@ void main() { WidgetTester tester, { required Drug drug, bool isLoading = false, - bool expectNoGuidelines = false, + bool expectNoMappedGuidelines = false, bool expectDrugToBeActive = false, bool expectNoBrandNames = false, + List? explicitNoResult, + Map? explicitLookups, Guideline? guideline, }) async { Guideline? relevantGuideline; - if (!expectNoGuidelines) { + if (guideline != null || drug.guidelines.isNotEmpty) { relevantGuideline = guideline ?? drug.guidelines.first; - setAppData(drug: drug, guideline: relevantGuideline); + setAppData( + drug: drug, + guideline: relevantGuideline, + explicitNoResult: explicitNoResult, + explicitLookups: explicitLookups, + ); } when(() => mockDrugsCubit.state) .thenReturn(isLoading ? DrugState.loading() : DrugState.loaded()); @@ -97,6 +120,7 @@ void main() { ), ) as RoundedCard; expect(find.byType(Disclaimer), findsOneWidget); + final sourcesSection = find.byKey(Key('sourceCard')); final context = tester.element(find.byType(Scaffold).first); if (expectNoBrandNames) { expect( @@ -115,20 +139,42 @@ void main() { ); } } - if (expectNoGuidelines) { + if (expectNoMappedGuidelines) { expect(card.color, WarningLevel.green.color); expect( find.byTooltip(context.l10n.drugs_page_tooltip_guideline_missing), findsOneWidget, ); - expect( - find.text(context.l10n.drugs_page_guidelines_empty(drug.name)), - findsOneWidget, - ); expect( find.text(context.l10n.drugs_page_no_guidelines_text), findsOneWidget, ); + if (drug.guidelines.isNotEmpty) { + expect(sourcesSection, findsOneWidget); + } else { + expect(sourcesSection, findsNothing); + } + if (drug.guidelines.isEmpty) { + expect( + find.text(context.l10n.drugs_page_guidelines_empty(drug.name)), + findsOneWidget, + ); + } + if (explicitNoResult != null) { + for (final noResultGene in explicitNoResult) { + final geneRowFinder = find.ancestor( + of: find.text(noResultGene), + matching: find.byType(Table), + ); + expect( + find.descendant( + of: geneRowFinder, + matching: find.textContaining(context.l10n.general_not_tested), + ), + findsOneWidget, + ); + } + } } else { expect(card.color, relevantGuideline!.annotations.warningLevel.color); expect( @@ -145,6 +191,9 @@ void main() { find.textContaining(relevantGuideline.annotations.recommendation), findsOneWidget, ); + expect(sourcesSection, findsOneWidget); + } + if (!expectNoMappedGuidelines || explicitLookups != null) { for (final genotypeKey in drug.guidelineGenotypes) { if (genotypeKey.contains(' ')) { expect( @@ -161,14 +210,10 @@ void main() { } } - Future runTestCasePerGuideline( - Map testCases, { - bool expectNoGuidelines = false, - } - ) async { - for (final (testCase) in testCases.entries) { - final description = 'test drug content with ${testCase.key}'; - final drug = testCase.value; + Future runTestCases(List<_TestCase> testCases) async { + for (final (testCase) in testCases) { + final description = 'test drug content with ${testCase.description}'; + final drug = testCase.drug; for (final (index, guideline) in drug.guidelines.indexed) { // Run per case to ensure clean setup final caseDescription = drug.guidelines.length > 1 @@ -181,7 +226,9 @@ void main() { tester, drug: drug, guideline: guideline, - expectNoGuidelines: expectNoGuidelines, + expectNoMappedGuidelines: testCase.expectNoMappedGuidelines, + explicitNoResult: testCase.explicitNoResult, + explicitLookups: testCase.explicitLookups, ); }, ); @@ -238,24 +285,47 @@ void main() { }); group('test missing guidelines', () { - final missingGuidelinesCases = { - 'for drug without guidelines': mirabegronWithoutGuidelines, - }; - runTestCasePerGuideline( - missingGuidelinesCases, - expectNoGuidelines: true, - ); + runTestCases([ + _TestCase( + description: 'no guidelines', + drug: mirabegronWithoutGuidelines, + expectNoMappedGuidelines: true, + ), + _TestCase( + description: 'no result and no explicit guideline', + drug: ibuprofenWithProperGuideline, + explicitNoResult: [ + ibuprofenWithProperGuideline.guidelines.first.lookupkey.keys.first, + ], + expectNoMappedGuidelines: true, + ), + _TestCase( + description: 'no result and no mappable lookup', + drug: ibuprofenWithProperGuideline, + explicitLookups: { + ibuprofenWithProperGuideline.guidelines.first.lookupkey.keys.first: + '0.0', + }, + expectNoMappedGuidelines: true, + ), + ]); }); group('test special guidelines', () { - final specialGuidelineTestCases = { - 'any fallback guideline': warfarinWithAnyFallbackGuideline, - 'any not handled fallback guideline': - aripiprazoleWithAnyNotHandledFallbackGuideline, - 'multiple any not handled fallback guidelines': - pazopanibWithMultipleAnyNotHandledFallbackGuidelines, - }; - runTestCasePerGuideline(specialGuidelineTestCases); + runTestCases([ + _TestCase( + description: 'any fallback guideline', + drug: warfarinWithAnyFallbackGuideline, + ), + _TestCase( + description: 'any not handled fallback guideline', + drug: aripiprazoleWithAnyNotHandledFallbackGuideline, + ), + _TestCase( + description: 'multiple any not handled fallback guidelines', + drug: pazopanibWithMultipleAnyNotHandledFallbackGuidelines, + ) + ]); }); }); } diff --git a/app/integration_test/fixtures/set_app_data.dart b/app/integration_test/fixtures/set_app_data.dart index 32c804b3..36bf3852 100644 --- a/app/integration_test/fixtures/set_app_data.dart +++ b/app/integration_test/fixtures/set_app_data.dart @@ -17,7 +17,11 @@ void setGenotypeResult(GenotypeResult genotypeResult) { UserData.instance.genotypeResults![genotypeResult.key.value] = genotypeResult; } -void setUserDataForGuideline(Guideline guideline) { +void setUserDataForGuideline( + Guideline guideline, { + List? explicitNoResult, + Map? explicitLookups, +}) { UserData.instance.labData = UserData.instance.labData ?? []; for (final gene in guideline.lookupkey.keys) { final lookupkeys = guideline.lookupkey[gene]!; @@ -28,9 +32,15 @@ void setUserDataForGuideline(Guideline guideline) { ); } var lookupkey = lookupkeys.first; - if (lookupkey == '*' || lookupkey == '~') { + if ( + lookupkey == SpecialLookup.any.value || + lookupkey == SpecialLookup.anyNotHandled.value + ) { lookupkey = 'certainly not handled lookupkey'; } + if (explicitLookups?.keys.contains(gene) ?? false) { + lookupkey = explicitLookups![gene]!; + } final userDataConfig = _UserDataConfig( gene: gene, lookupkey: lookupkey, @@ -39,24 +49,26 @@ void setUserDataForGuideline(Guideline guideline) { // 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) - UserData.instance.labData = UserData.instance.labData!.filter( - (labResult) => labResult.gene != gene - ).toList(); - UserData.instance.labData!.add( - LabResult( + if (!(explicitNoResult?.contains(gene) ?? false)) { + UserData.instance.labData = UserData.instance.labData!.filter( + (labResult) => labResult.gene != gene + ).toList(); + UserData.instance.labData!.add( + LabResult( + gene: userDataConfig.gene, + variant: userDataConfig.variant, + phenotype: userDataConfig.phenotype, + allelesTested: userDataConfig.allelesTested, + ), + ); + setGenotypeResult(GenotypeResult( gene: userDataConfig.gene, - variant: userDataConfig.variant, phenotype: userDataConfig.phenotype, - allelesTested: userDataConfig.allelesTested, - ), - ); - setGenotypeResult(GenotypeResult( - gene: userDataConfig.gene, - phenotype: userDataConfig.phenotype, - variant: userDataConfig.variant, - allelesTested: userDataConfig.variant, - lookupkey: userDataConfig.lookupkey, - )); + variant: userDataConfig.variant, + allelesTested: userDataConfig.variant, + lookupkey: userDataConfig.lookupkey, + )); + } } } @@ -69,8 +81,17 @@ void addDrugToDrugsWithGuidelines(Drug drug) { DrugsWithGuidelines.instance.drugs!.add(drug); } -void setAppData({required Drug drug, required Guideline guideline}) { +void setAppData({ + required Drug drug, + required Guideline guideline, + List? explicitNoResult, + Map? explicitLookups, +}) { addDrugToDrugsWithGuidelines(drug); initializeGenotypeResultKeys().values.forEach(setGenotypeResult); - setUserDataForGuideline(guideline); + setUserDataForGuideline( + guideline, + explicitNoResult: explicitNoResult, + explicitLookups: explicitLookups, + ); } diff --git a/app/lib/drug/widgets/annotation_cards/guideline.dart b/app/lib/drug/widgets/annotation_cards/guideline.dart index e26fa122..293f1432 100644 --- a/app/lib/drug/widgets/annotation_cards/guideline.dart +++ b/app/lib/drug/widgets/annotation_cards/guideline.dart @@ -163,6 +163,7 @@ class GuidelineAnnotationCard extends StatelessWidget { (source) => GestureDetector( onTap: () => _launchUrl(Uri.parse(source.split('|')[1])), child: RoundedCard( + key: Key('sourceCard'), radius: PharMeTheme.innerCardRadius, outerHorizontalPadding: 0, outerVerticalPadding: 0,