From 9706efab3385522cf96127b010084cbb82fbb88a Mon Sep 17 00:00:00 2001 From: Tamara Slosarek Date: Thu, 19 Sep 2024 19:51:56 +0200 Subject: [PATCH] test(app): refactor mocks and fixtures --- app/integration_test/drugs_test.dart | 173 ++++++------------ .../drugs/with_any_fallback_guideline.dart | 47 +++++ .../fixtures/drugs/with_proper_guideline.dart | 44 +++++ .../fixtures/drugs/without_guidelines.dart | 13 ++ .../fixtures/set_user_data_for_drug.dart | 41 +++++ app/integration_test/login_test.dart | 4 +- app/integration_test/mocks/drug_cubit.dart | 4 + .../mocks/drug_list_cubit.dart | 7 + app/integration_test/mocks/login_cubit.dart | 4 + app/integration_test/search_test.dart | 43 +---- pharme.code-workspace | 6 + 11 files changed, 235 insertions(+), 151 deletions(-) create mode 100644 app/integration_test/fixtures/drugs/with_any_fallback_guideline.dart create mode 100644 app/integration_test/fixtures/drugs/with_proper_guideline.dart create mode 100644 app/integration_test/fixtures/drugs/without_guidelines.dart create mode 100644 app/integration_test/fixtures/set_user_data_for_drug.dart create mode 100644 app/integration_test/mocks/drug_cubit.dart create mode 100644 app/integration_test/mocks/drug_list_cubit.dart create mode 100644 app/integration_test/mocks/login_cubit.dart diff --git a/app/integration_test/drugs_test.dart b/app/integration_test/drugs_test.dart index 5d5b1ae9..49f1752a 100644 --- a/app/integration_test/drugs_test.dart +++ b/app/integration_test/drugs_test.dart @@ -1,16 +1,72 @@ -// ignore_for_file: cast_nullable_to_non_nullable - import 'package:app/common/module.dart'; import 'package:app/drug/module.dart'; import 'package:app/drug/widgets/annotation_cards/disclaimer.dart'; -import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:provider/provider.dart'; -class MockDrugsCubit extends MockCubit implements DrugCubit {} +import 'fixtures/drugs/with_proper_guideline.dart'; +import 'fixtures/drugs/without_guidelines.dart'; +import 'fixtures/set_user_data_for_drug.dart'; +import 'mocks/drug_cubit.dart'; + +void main() { + final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.onlyPumps; + + late MockDrugsCubit mockDrugsCubit; + + setUp(() { + UserData.instance.activeDrugNames = []; + UserData.instance.labData = null; + UserData.instance.genotypeResults = null; + setUserDataForDrug(drugWithProperGuideline); + mockDrugsCubit = MockDrugsCubit(); + }); + + group('integration test for the drugs page', () { + testWidgets( + 'test that activity selection is disabled when loading', + (tester) async { + await _expectDrugContent( + tester, + mockDrugsCubit, + drug: drugWithProperGuideline, + isLoading: true, + ); + }, + ); + + testWidgets('test drug content with proper guideline', (tester) async { + await _expectDrugContent( + tester, + mockDrugsCubit, + drug: drugWithProperGuideline, + ); + }); + + testWidgets('test active drug content', (tester) async { + UserData.instance.activeDrugNames = ['ibuprofen']; + await _expectDrugContent( + tester, + mockDrugsCubit, + drug: drugWithProperGuideline, + expectDrugToBeActive: true, + ); + }); + + testWidgets('test drug content without guidelines', (tester) async { + await _expectDrugContent( + tester, + mockDrugsCubit, + drug: drugWithoutGuidelines, + expectNoGuidelines: true, + ); + }); + }); +} Future _expectDrugContent( WidgetTester tester, @@ -106,112 +162,3 @@ Future _expectDrugContent( findsOneWidget, ); } - -void main() { - final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - final mockDrugsCubit = MockDrugsCubit(); - - binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.onlyPumps; - - final drugWithProperGuideline = Drug( - id: '6407768b92a4868065b6c466', - version: 1, - name: 'ibuprofen', - rxNorm: 'RxNorm:5640', - annotations: DrugAnnotations( - drugclass: 'Non-steroidal anti-inflammatory drug (NSAID)', - indication: 'Ibuprofen is used to treat pain, fever, and inflammation.', - brandNames: ['Advil', 'Motrin']), - 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)) - ]); - UserData.instance.labData = [ - LabResult( - gene: 'CYP2C9', - phenotype: 'Normal Metabolizer', - variant: '*1/*1', - allelesTested: '"*2.*3.*5.*11"', - ), - ]; - UserData.instance.genotypeResults = { - 'CYP2C9': GenotypeResult( - gene: UserData.instance.labData![0].gene, - phenotype: UserData.instance.labData![0].phenotype, - variant: UserData.instance.labData![0].variant, - allelesTested: UserData.instance.labData![0].variant, - lookupkey: '2.0', - ), - }; - final drugWithoutGuidelines = Drug( - id: '64c187431006f51bc6e24959', - version: 2, - name: 'mirabegron', - rxNorm: 'RxNorm:1300786', - annotations: DrugAnnotations( - drugclass: 'Urology drug', - indication: 'Mirabegron is used to treat overactive bladder.', - brandNames: ['Myrbetriq']), - guidelines: [], - ); - - setUp(() => UserData.instance.activeDrugNames = []); - - group('integration test for the drugs page', () { - testWidgets( - 'test that activity selection is disabled when loading', - (tester) async { - await _expectDrugContent( - tester, - mockDrugsCubit, - drug: drugWithProperGuideline, - isLoading: true, - ); - }, - ); - - testWidgets('test drug content with proper guideline', (tester) async { - await _expectDrugContent( - tester, - mockDrugsCubit, - drug: drugWithProperGuideline, - ); - }); - - testWidgets('test active drug content', (tester) async { - UserData.instance.activeDrugNames = ['ibuprofen']; - await _expectDrugContent( - tester, - mockDrugsCubit, - drug: drugWithProperGuideline, - expectDrugToBeActive: true, - ); - }); - - testWidgets('test drug content without guidelines', (tester) async { - await _expectDrugContent( - tester, - mockDrugsCubit, - drug: drugWithoutGuidelines, - expectNoGuidelines: true, - ); - }); - }); -} diff --git a/app/integration_test/fixtures/drugs/with_any_fallback_guideline.dart b/app/integration_test/fixtures/drugs/with_any_fallback_guideline.dart new file mode 100644 index 00000000..90e930f7 --- /dev/null +++ b/app/integration_test/fixtures/drugs/with_any_fallback_guideline.dart @@ -0,0 +1,47 @@ +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 drugWithAnyFallbackGuideline = Drug( + id: '658df37b3aa92cbd80bbe352', + version: 1, + name: 'warfarin', + rxNorm: 'RxNorm:11289', + annotations: DrugAnnotations( + drugclass: 'Blood thinner', + indication: 'Warfarin is used to prevent and treat blood clots.', + brandNames: ['Coumadin', 'Jantoven'], + ), + guidelines: [ + Guideline( + id: '66b50b2433cbe5c07ee3101d', + version: 4, + lookupkey: { + 'CYP2C9': ['*'], + 'VKORC1': ['*'], + 'CYP4F2': ['*'], + 'CYP2C': ['*'], + }, + externalData: [ + GuidelineExtData( + source: 'CPIC', + guidelineName: 'CPIC® Guideline for Pharmacogenetics-Guided Warfarin Dosing', + guidelineUrl: 'https://cpicpgx.org/guidelines/guideline-for-warfarin-and-cyp2c9-and-vkorc1/', + implications: { + 'CYP2C9': 'No implication', + 'VKORC1': 'No implication', + 'CYP4F2': 'No implication', + 'CYP2C': 'No implication', + }, + recommendation: 'No recommendation', + comments: null, + ), + ], + annotations: GuidelineAnnotations( + implication: 'More information is needed to calculate your warfarin dose.', + recommendation: 'Consult your pharmacist or doctor for more information.', + warningLevel: WarningLevel.yellow, + ), + ), + ], +); \ No newline at end of file diff --git a/app/integration_test/fixtures/drugs/with_proper_guideline.dart b/app/integration_test/fixtures/drugs/with_proper_guideline.dart new file mode 100644 index 00000000..4fd27129 --- /dev/null +++ b/app/integration_test/fixtures/drugs/with_proper_guideline.dart @@ -0,0 +1,44 @@ +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 drugWithProperGuideline = Drug( + id: '6407768b92a4868065b6c466', + version: 1, + name: 'ibuprofen', + rxNorm: 'RxNorm:5640', + annotations: DrugAnnotations( + drugclass: 'Non-steroidal anti-inflammatory drug (NSAID)', + indication: 'Ibuprofen is used to treat pain, fever, and inflammation.', + brandNames: [ + 'Advil', + 'Ibutab', + 'Motrin', + 'Neoprofen', + 'Proprinal', + '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, + ), + ), + ], +); diff --git a/app/integration_test/fixtures/drugs/without_guidelines.dart b/app/integration_test/fixtures/drugs/without_guidelines.dart new file mode 100644 index 00000000..307d4d54 --- /dev/null +++ b/app/integration_test/fixtures/drugs/without_guidelines.dart @@ -0,0 +1,13 @@ +import 'package:app/common/models/drug/drug.dart'; + +final drugWithoutGuidelines = Drug( + id: '64c187431006f51bc6e24959', + version: 2, + name: 'mirabegron', + rxNorm: 'RxNorm:1300786', + annotations: DrugAnnotations( + drugclass: 'Urology drug', + indication: 'Mirabegron is used to treat overactive bladder.', + brandNames: ['Myrbetriq']), + guidelines: [], +); diff --git a/app/integration_test/fixtures/set_user_data_for_drug.dart b/app/integration_test/fixtures/set_user_data_for_drug.dart new file mode 100644 index 00000000..90571519 --- /dev/null +++ b/app/integration_test/fixtures/set_user_data_for_drug.dart @@ -0,0 +1,41 @@ +import 'package:app/common/models/drug/drug.dart'; +import 'package:app/common/models/userdata/genotype_result.dart'; +import 'package:app/common/models/userdata/lab_result.dart'; +import 'package:app/common/models/userdata/userdata.dart'; + +class _UserDataConfig { + _UserDataConfig({ + required this.gene, + required this.lookupkey, + }); + final String gene; + final String lookupkey; + final String phenotype = 'phenotype does not matter for test'; + final String variant = 'variant does not matter for test'; + final String allelesTested = 'allelesTested does not matter for test'; +} + +void setUserDataForDrug(Drug drug) { + UserData.instance.labData = UserData.instance.labData ?? []; + UserData.instance.genotypeResults = UserData.instance.genotypeResults ?? {}; + final userDataConfig = _UserDataConfig( + gene: drug.guidelines.first.lookupkey.keys.first, + lookupkey: + drug.guidelines.first.lookupkey.values.first.first, + ); + UserData.instance.labData!.add( + LabResult( + gene: userDataConfig.gene, + variant: userDataConfig.variant, + phenotype: userDataConfig.phenotype, + allelesTested: userDataConfig.allelesTested, + ), + ); + UserData.instance.genotypeResults![userDataConfig.gene] = GenotypeResult( + gene: userDataConfig.gene, + phenotype: userDataConfig.phenotype, + variant: userDataConfig.variant, + allelesTested: userDataConfig.variant, + lookupkey: userDataConfig.lookupkey, + ); +} \ No newline at end of file diff --git a/app/integration_test/login_test.dart b/app/integration_test/login_test.dart index 192f15bc..e4b1a73e 100644 --- a/app/integration_test/login_test.dart +++ b/app/integration_test/login_test.dart @@ -1,15 +1,13 @@ import 'package:app/common/module.dart'; import 'package:app/login/models/lab.dart'; import 'package:app/login/module.dart'; -import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:provider/provider.dart'; -class MockLoginCubit extends MockCubit - implements LoginCubit {} +import 'mocks/login_cubit.dart'; void main() { final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/app/integration_test/mocks/drug_cubit.dart b/app/integration_test/mocks/drug_cubit.dart new file mode 100644 index 00000000..52c56b44 --- /dev/null +++ b/app/integration_test/mocks/drug_cubit.dart @@ -0,0 +1,4 @@ +import 'package:app/drug/cubit.dart'; +import 'package:bloc_test/bloc_test.dart'; + +class MockDrugsCubit extends MockCubit implements DrugCubit {} \ No newline at end of file diff --git a/app/integration_test/mocks/drug_list_cubit.dart b/app/integration_test/mocks/drug_list_cubit.dart new file mode 100644 index 00000000..8769e408 --- /dev/null +++ b/app/integration_test/mocks/drug_list_cubit.dart @@ -0,0 +1,7 @@ +import 'package:app/common/widgets/drug_list/cubit.dart'; +import 'package:bloc_test/bloc_test.dart'; + +class MockDrugListCubit extends MockCubit implements DrugListCubit { + @override + FilterState get filter => FilterState.initial(); +} \ No newline at end of file diff --git a/app/integration_test/mocks/login_cubit.dart b/app/integration_test/mocks/login_cubit.dart new file mode 100644 index 00000000..ac214ad7 --- /dev/null +++ b/app/integration_test/mocks/login_cubit.dart @@ -0,0 +1,4 @@ +import 'package:app/login/cubit.dart'; +import 'package:bloc_test/bloc_test.dart'; + +class MockLoginCubit extends MockCubit implements LoginCubit {} \ No newline at end of file diff --git a/app/integration_test/search_test.dart b/app/integration_test/search_test.dart index a1397622..094770c8 100644 --- a/app/integration_test/search_test.dart +++ b/app/integration_test/search_test.dart @@ -1,53 +1,26 @@ import 'package:app/common/module.dart'; import 'package:app/search/module.dart'; -import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:provider/provider.dart'; -class MockDrugListCubit extends MockCubit implements DrugListCubit { - @override - FilterState get filter => FilterState.initial(); -} +import 'fixtures/drugs/with_any_fallback_guideline.dart'; +import 'fixtures/drugs/with_proper_guideline.dart'; +import 'fixtures/drugs/without_guidelines.dart'; +import 'mocks/drug_list_cubit.dart'; void main() { final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); final mockDrugListCubit = MockDrugListCubit(); + UserData.instance.labData = []; binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.onlyPumps; final loadedDrugs = [ - Drug( - id: '1', - version: 1, - name: 'Ibuprofen', - rxNorm: 'rxnorm', - annotations: DrugAnnotations( - drugclass: 'NSAID', - indication: 'indication', - brandNames: ['brand name', 'another brand name']), - guidelines: []), - Drug( - id: '2', - version: 1, - name: 'Codeine', - rxNorm: 'rxnorm', - annotations: DrugAnnotations( - drugclass: 'Pain killer', - indication: 'indication', - brandNames: ['brand name', 'another brand name']), - guidelines: []), - Drug( - id: '3', - version: 1, - name: 'Amitryptiline', - rxNorm: 'rxnorm', - annotations: DrugAnnotations( - drugclass: 'Antidepressant', - indication: 'indication', - brandNames: ['brand name', 'another brand name']), - guidelines: []), + drugWithProperGuideline, + drugWithoutGuidelines, + drugWithAnyFallbackGuideline, ]; group('integration test for the search page', () { testWidgets('test search page in loading state', (tester) async { diff --git a/pharme.code-workspace b/pharme.code-workspace index 9354f15e..d0139c9b 100644 --- a/pharme.code-workspace +++ b/pharme.code-workspace @@ -40,6 +40,7 @@ "cinacalcet", "citalopram", "clopidogrel", + "Coumadin", "CPIC", "Cupertino", "dartx", @@ -55,9 +56,11 @@ "haplotypes", "Hasso", "horiz", + "Ibutab", "ilike", "inhibitable", "irinotecan", + "Jantoven", "Keycloak", "lookupkey", "lookupkeys", @@ -69,6 +72,7 @@ "mirabegron", "mocktail", "Myrbetriq", + "Neoprofen", "noto", "NSAID", "omeprazole", @@ -81,6 +85,7 @@ "PharMe", "phenoconversion", "Plattner", + "Proprinal", "RGBO", "rxnorm", "sertraline", @@ -92,6 +97,7 @@ "unstage", "unstaged", "userdata", + "Vicoprofen", "voriconazole" ] }