diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml index 09d66edf1e..54bd3e48c5 100644 --- a/.github/workflows/unit_test.yml +++ b/.github/workflows/unit_test.yml @@ -26,7 +26,7 @@ jobs: FILE_FIREBASE_IOS_PRODUCTION: ${{ secrets.FILE_FIREBASE_IOS_PRODUCTION }} - uses: subosito/flutter-action@v1 with: - flutter-version: '2.8.1' + flutter-version: '2.10.0' - run: flutter pub get - name: Run iOS run: flutter build ios --debug --no-codesign --flavor development --target lib/main.dev.dart --no-sound-null-safety @@ -45,7 +45,7 @@ jobs: FILE_FIREBASE_ANDROID_PRODUCTION: ${{ secrets.FILE_FIREBASE_ANDROID_PRODUCTION }} - uses: subosito/flutter-action@v1 with: - flutter-version: '2.8.1' + flutter-version: '2.10.0' - run: flutter pub get - run: flutter build apk --debug --flavor development --target lib/main.dev.dart --no-sound-null-safety test: @@ -58,6 +58,6 @@ jobs: java-version: '12.x' - uses: subosito/flutter-action@v1 with: - flutter-version: '2.8.1' + flutter-version: '2.10.0' - run: flutter pub get - run: flutter test diff --git a/android/app/build.gradle b/android/app/build.gradle index b8a30d4a78..3850082f27 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -33,7 +33,7 @@ if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } android { - compileSdkVersion 30 + compileSdkVersion 31 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -47,7 +47,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.mizuki.Ohashi.Pilll" minSdkVersion 23 - targetSdkVersion 30 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 23a6c82bc9..721642ef2a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -6,12 +6,13 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> { _decideScreenType() async { const minimumSupportedAppVersionKey = "minimum_supported_app_version"; - final remoteConfig = RemoteConfig.instance; + final remoteConfig = FirebaseRemoteConfig.instance; await remoteConfig.setConfigSettings( RemoteConfigSettings( minimumFetchInterval: Duration(seconds: 0), diff --git a/lib/domain/settings/reminder_times_page.dart b/lib/domain/settings/reminder_times_page.dart index 5e91c1ed89..1a2923d3a4 100644 --- a/lib/domain/settings/reminder_times_page.dart +++ b/lib/domain/settings/reminder_times_page.dart @@ -15,7 +15,7 @@ class ReminderTimesPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final store = ref.watch(settingStoreProvider.notifier); - final state = ref.watch(settingStoreProvider); + final state = ref.watch(settingStateProvider); final setting = state.setting; if (setting == null) { diff --git a/lib/domain/settings/setting_page.dart b/lib/domain/settings/setting_page.dart index 8ad5bd8f44..3803b14f50 100644 --- a/lib/domain/settings/setting_page.dart +++ b/lib/domain/settings/setting_page.dart @@ -19,6 +19,7 @@ import 'package:pilll/domain/settings/components/rows/update_from_132.dart'; import 'package:pilll/domain/settings/components/setting_section_title.dart'; import 'package:pilll/domain/settings/setting_page_state.dart'; import 'package:pilll/error/universal_error_page.dart'; +import 'package:pilll/hooks/automatic_keep_alive_client_mixin.dart'; import 'package:pilll/inquiry/inquiry.dart'; import 'package:pilll/domain/settings/setting_page_store.dart'; import 'package:pilll/components/atoms/color.dart'; @@ -44,6 +45,12 @@ class SettingPage extends HookConsumerWidget { final store = ref.watch(settingStoreProvider.notifier); final state = ref.watch(settingStoreProvider); + useAutomaticKeepAlive(wantKeepAlive: true); + useEffect(() { + store.setup(); + return store.cancel; + }, const []); + return Scaffold( backgroundColor: PilllColors.background, appBar: AppBar( diff --git a/lib/domain/settings/setting_page_state.dart b/lib/domain/settings/setting_page_state.dart index fb42353277..432c6bb710 100644 --- a/lib/domain/settings/setting_page_state.dart +++ b/lib/domain/settings/setting_page_state.dart @@ -8,7 +8,7 @@ part 'setting_page_state.freezed.dart'; class SettingState with _$SettingState { const SettingState._(); const factory SettingState({ - required Setting? setting, + Setting? setting, PillSheetGroup? latestPillSheetGroup, @Default(false) bool userIsUpdatedFrom132, @Default(false) bool isPremium, diff --git a/lib/domain/settings/setting_page_state.freezed.dart b/lib/domain/settings/setting_page_state.freezed.dart index 4840b15ffb..6af3995ac7 100644 --- a/lib/domain/settings/setting_page_state.freezed.dart +++ b/lib/domain/settings/setting_page_state.freezed.dart @@ -19,7 +19,7 @@ class _$SettingStateTearOff { const _$SettingStateTearOff(); _SettingState call( - {required Setting? setting, + {Setting? setting, PillSheetGroup? latestPillSheetGroup, bool userIsUpdatedFrom132 = false, bool isPremium = false, @@ -221,7 +221,7 @@ class __$SettingStateCopyWithImpl<$Res> extends _$SettingStateCopyWithImpl<$Res> class _$_SettingState extends _SettingState { const _$_SettingState( - {required this.setting, + {this.setting, this.latestPillSheetGroup, this.userIsUpdatedFrom132 = false, this.isPremium = false, @@ -289,7 +289,7 @@ class _$_SettingState extends _SettingState { abstract class _SettingState extends SettingState { const factory _SettingState( - {required Setting? setting, + {Setting? setting, PillSheetGroup? latestPillSheetGroup, bool userIsUpdatedFrom132, bool isPremium, diff --git a/lib/domain/settings/setting_page_store.dart b/lib/domain/settings/setting_page_store.dart index 2f966f9e25..7bc76fa6b0 100644 --- a/lib/domain/settings/setting_page_store.dart +++ b/lib/domain/settings/setting_page_store.dart @@ -40,28 +40,26 @@ class SettingStateStore extends StateNotifier { this._userService, this._pillSheetModifiedHistoryService, this._pillSheetGroupService, - ) : super(SettingState(setting: null)) { - reset(); + ) : super(SettingState()); + + void reset() { + state = SettingState(); + setup(); } - void reset() async { + setup() { try { - state = state.copyWith(exception: null); - final storage = await SharedPreferences.getInstance(); - final userIsMigratedFrom132 = - storage.containsKey(StringKey.salvagedOldStartTakenDate) && - storage.containsKey(StringKey.salvagedOldLastTakenDate); - final setting = await _settingService.fetch(); - final pillSheetGroup = await _pillSheetGroupService.fetchLatest(); - final user = await _userService.fetch(); - this.state = SettingState( - setting: setting, - userIsUpdatedFrom132: userIsMigratedFrom132, - latestPillSheetGroup: pillSheetGroup, - isPremium: user.isPremium, - isTrial: user.isTrial, - trialDeadlineDate: user.trialDeadlineDate, - ); + Future(() async { + final storage = await SharedPreferences.getInstance(); + final userIsMigratedFrom132 = + storage.containsKey(StringKey.salvagedOldStartTakenDate) && + storage.containsKey(StringKey.salvagedOldLastTakenDate); + + state = SettingState( + userIsUpdatedFrom132: userIsMigratedFrom132, + ); + }); + _subscribe(); } catch (exception) { state = state.copyWith(exception: exception); @@ -72,16 +70,15 @@ class SettingStateStore extends StateNotifier { StreamSubscription? _pillSheetGroupCanceller; StreamSubscription? _userSubscribeCanceller; void _subscribe() { - _settingCanceller?.cancel(); + cancel(); + _settingCanceller = _settingService.stream().listen((event) { state = state.copyWith(setting: event); }); - _pillSheetGroupCanceller?.cancel(); _pillSheetGroupCanceller = _pillSheetGroupService.streamForLatest().listen((event) { state = state.copyWith(latestPillSheetGroup: event); }); - _userSubscribeCanceller?.cancel(); _userSubscribeCanceller = _userService.stream().listen((event) { state = state.copyWith( isPremium: event.isPremium, @@ -91,11 +88,15 @@ class SettingStateStore extends StateNotifier { }); } - @override - void dispose() { + void cancel() { _settingCanceller?.cancel(); _pillSheetGroupCanceller?.cancel(); _userSubscribeCanceller?.cancel(); + } + + @override + void dispose() { + cancel(); super.dispose(); } diff --git a/lib/hooks/automatic_keep_alive_client_mixin.dart b/lib/hooks/automatic_keep_alive_client_mixin.dart new file mode 100644 index 0000000000..29b22f7762 --- /dev/null +++ b/lib/hooks/automatic_keep_alive_client_mixin.dart @@ -0,0 +1,70 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; + +// Ref: https://github.com/rrousselGit/flutter_hooks/issues/101#issuecomment-762121053 +// Re implement useAutomaticKeepAlive with NNDB +void useAutomaticKeepAlive({ + bool? wantKeepAlive, +}) => + use(_AutomaticKeepAliveHook( + wantKeepAlive: wantKeepAlive ?? true, + )); + +class _AutomaticKeepAliveHook extends Hook { + final bool wantKeepAlive; + + _AutomaticKeepAliveHook({required this.wantKeepAlive}); + + @override + HookState createState() => + _AutomaticKeepAliveHookState(); +} + +class _AutomaticKeepAliveHookState + extends HookState { + KeepAliveHandle? _keepAliveHandle; + + void _ensureKeepAlive() { + assert(_keepAliveHandle == null); + final keepAliveHandle = KeepAliveHandle(); + _keepAliveHandle = keepAliveHandle; + KeepAliveNotification(keepAliveHandle).dispatch(context); + } + + void _releaseKeepAlive() { + _keepAliveHandle?.release(); + _keepAliveHandle = null; + } + + void updateKeepAlive() { + if (hook.wantKeepAlive) { + if (_keepAliveHandle == null) _ensureKeepAlive(); + } else { + if (_keepAliveHandle != null) _releaseKeepAlive(); + } + } + + @override + void initHook() { + super.initHook(); + if (hook.wantKeepAlive) _ensureKeepAlive(); + } + + @override + void build(BuildContext context) { + if (hook.wantKeepAlive && _keepAliveHandle == null) _ensureKeepAlive(); + return null; + } + + @override + void deactivate() { + if (_keepAliveHandle != null) _releaseKeepAlive(); + super.deactivate(); + } + + @override + Object get debugValue => _keepAliveHandle ?? "NULL"; + + @override + String get debugLabel => 'useAutomaticKeepAlive'; +} diff --git a/lib/util/version/version.dart b/lib/util/version/version.dart index 1505a98f5f..1942603d74 100644 --- a/lib/util/version/version.dart +++ b/lib/util/version/version.dart @@ -1,4 +1,5 @@ import 'package:package_info/package_info.dart'; +import 'package:pilll/util/environment.dart'; class Version { final int major; @@ -13,7 +14,12 @@ class Version { factory Version.parse(String str) { final splited = str.split("."); - assert(splited.length <= 3, "unexpected version format $str"); + if (Environment.isDevelopment) { + assert( + splited.length <= 3 || + (splited.last == "last" && splited.length == 4), + "unexpected version format $str"); + } final versions = List.filled(3, 0); for (int i = 0; i < splited.length; i++) { diff --git a/pubspec.lock b/pubspec.lock index 598f596feb..ce01e5bfff 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -280,14 +280,14 @@ packages: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.2.3" + version: "4.2.4" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted - version: "1.5.3" + version: "1.5.4" firebase_crashlytics: dependency: "direct main" description: @@ -329,21 +329,21 @@ packages: name: firebase_remote_config url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "2.0.0" firebase_remote_config_platform_interface: dependency: transitive description: name: firebase_remote_config_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.5" firebase_remote_config_web: dependency: transitive description: name: firebase_remote_config_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.5" fixnum: dependency: transitive description: @@ -541,6 +541,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -853,7 +860,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.8" timing: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b64efecba9..6ac11a6272 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -53,7 +53,7 @@ dependencies: sign_in_with_apple: ^3.0.0 google_sign_in: ^5.0.4 purchases_flutter: ^3.2.2 - firebase_remote_config: ^1.0.3 + firebase_remote_config: ^2.0.0 dev_dependencies: flutter_test: diff --git a/test/domain/calendar/widget/calendar_test.dart b/test/domain/calendar/widget/calendar_test.dart index bd8fac5160..73014737fb 100644 --- a/test/domain/calendar/widget/calendar_test.dart +++ b/test/domain/calendar/widget/calendar_test.dart @@ -15,7 +15,7 @@ void main() { setUp(() { TestWidgetsFlutterBinding.ensureInitialized(); SharedPreferences.setMockInitialValues({}); - WidgetsBinding.instance!.renderView.configuration = + WidgetsBinding.instance?.renderView.configuration = new TestViewConfiguration(size: const Size(375.0, 667.0)); }); group("Appearance Next Sheet Label", () { diff --git a/test/domain/menstruation/menstruation_store_test.dart b/test/domain/menstruation/menstruation_store_test.dart index 03a8cc2ff6..b5cb9625dc 100644 --- a/test/domain/menstruation/menstruation_store_test.dart +++ b/test/domain/menstruation/menstruation_store_test.dart @@ -17,10 +17,15 @@ import '../../helper/mock.mocks.dart'; class _FakeUser extends Fake implements User { _FakeUser({ +// ignore: unused_element this.fakeIsPremium = false, +// ignore: unused_element this.fakeIsTrial = false, +// ignore: unused_element this.fakeTrialDeadlineDate, +// ignore: unused_element this.fakeDiscountEntitlementDeadlineDate, +// ignore: unused_element this.fakeIsExpiredDiscountEntitlements = false, }); final DateTime? fakeTrialDeadlineDate; diff --git a/test/domain/premium_introduction/premium_introduction_sheet_test.dart b/test/domain/premium_introduction/premium_introduction_sheet_test.dart index 0632e678b8..6877b4aad5 100644 --- a/test/domain/premium_introduction/premium_introduction_sheet_test.dart +++ b/test/domain/premium_introduction/premium_introduction_sheet_test.dart @@ -62,7 +62,7 @@ void main() { initializeDateFormatting('ja_JP'); Environment.isTest = true; analytics = MockAnalytics(); - WidgetsBinding.instance!.renderView.configuration = + WidgetsBinding.instance?.renderView.configuration = new TestViewConfiguration(size: const Size(375.0, 667.0)); }); group('#PremiumIntroductionSheet', () { diff --git a/test/domain/record/notification_bar/notification_bar_test.dart b/test/domain/record/notification_bar/notification_bar_test.dart index 6d37aa0431..9b8968aafd 100644 --- a/test/domain/record/notification_bar/notification_bar_test.dart +++ b/test/domain/record/notification_bar/notification_bar_test.dart @@ -40,7 +40,7 @@ void main() { initializeDateFormatting('ja_JP'); Environment.isTest = true; analytics = MockAnalytics(); - WidgetsBinding.instance!.renderView.configuration = + WidgetsBinding.instance?.renderView.configuration = new TestViewConfiguration(size: const Size(375.0, 667.0)); }); group('notification bar appearance content type', () { diff --git a/test/domain/record/record_page_button_state_test.dart b/test/domain/record/record_page_button_state_test.dart index 1cb1f2c12f..db8ab188d6 100644 --- a/test/domain/record/record_page_button_state_test.dart +++ b/test/domain/record/record_page_button_state_test.dart @@ -24,7 +24,7 @@ void main() { initializeDateFormatting('ja_JP'); Environment.isTest = true; analytics = MockAnalytics(); - WidgetsBinding.instance!.renderView.configuration = + WidgetsBinding.instance?.renderView.configuration = new TestViewConfiguration(size: const Size(375.0, 667.0)); }); group('appearance taken button type', () { diff --git a/test/domain/record/record_page_state_test.dart b/test/domain/record/record_page_state_test.dart index cf0d4bd3a5..cac10adc36 100644 --- a/test/domain/record/record_page_state_test.dart +++ b/test/domain/record/record_page_state_test.dart @@ -18,10 +18,15 @@ import '../../helper/mock.mocks.dart'; class _FakeUser extends Fake implements User { _FakeUser({ +// ignore: unused_element this.fakeIsPremium = false, +// ignore: unused_element this.fakeIsTrial = false, +// ignore: unused_element this.fakeTrialDeadlineDate, +// ignore: unused_element this.fakeDiscountEntitlementDeadlineDate, +// ignore: unused_element this.fakeIsExpiredDiscountEntitlements = false, }); final DateTime? fakeTrialDeadlineDate; @@ -107,7 +112,8 @@ void main() { ); await waitForResetStoreState(); - expect(state.pillSheetGroup?.pillSheets.first.todayPillIsAlreadyTaken, isTrue); + expect(state.pillSheetGroup?.pillSheets.first.todayPillIsAlreadyTaken, + isTrue); expect( store.markFor(pillNumberIntoPillSheet: 1, pillSheet: pillSheetEntity), PillMarkType.done); @@ -180,7 +186,8 @@ void main() { ); await waitForResetStoreState(); - expect(state.pillSheetGroup?.pillSheets.first.todayPillIsAlreadyTaken, isFalse); + expect(state.pillSheetGroup?.pillSheets.first.todayPillIsAlreadyTaken, + isFalse); expect( store.markFor(pillNumberIntoPillSheet: 1, pillSheet: pillSheetEntity), PillMarkType.done); @@ -255,7 +262,8 @@ void main() { ); await waitForResetStoreState(); - expect(state.pillSheetGroup?.pillSheets.first.todayPillIsAlreadyTaken, isTrue); + expect(state.pillSheetGroup?.pillSheets.first.todayPillIsAlreadyTaken, + isTrue); for (int i = 1; i <= pillSheetEntity.pillSheetType.totalCount; i++) { expect( store.shouldPillMarkAnimation( @@ -325,7 +333,8 @@ void main() { ); await waitForResetStoreState(); - expect(state.pillSheetGroup?.pillSheets.first.todayPillIsAlreadyTaken, isFalse); + expect(state.pillSheetGroup?.pillSheets.first.todayPillIsAlreadyTaken, + isFalse); expect( store.shouldPillMarkAnimation( pillNumberIntoPillSheet: 3, diff --git a/test/domain/settings/reminder_times_widget_test.dart b/test/domain/settings/reminder_times_widget_test.dart index c6fc706d59..86f84e0a0f 100644 --- a/test/domain/settings/reminder_times_widget_test.dart +++ b/test/domain/settings/reminder_times_widget_test.dart @@ -1,3 +1,4 @@ +import 'package:pilll/domain/settings/setting_page_state.dart'; import 'package:pilll/entity/pill_sheet.dart'; import 'package:pilll/entity/pill_sheet_group.dart'; import 'package:pilll/entity/pill_sheet_type.dart'; @@ -19,9 +20,13 @@ import '../../helper/supported_device.dart'; class _FakeUser extends Fake implements User { _FakeUser({ +// ignore: unused_element this.fakeIsPremium = false, +// ignore: unused_element this.fakeIsTrial = false, +// ignore: unused_element this.fakeIsExpiredDiscountEntitlements = false, +// ignore: unused_element this.fakeIsTrialDeadlineDate, }); final bool fakeIsPremium; @@ -61,27 +66,23 @@ void main() { ReminderTime(hour: 10, minute: 0), ], ); - when(settingService.fetch()) - .thenAnswer((realInvocation) => Future.value(entity)); when(settingService.stream()) - .thenAnswer((realInvocation) => Stream.value(entity)); + .thenAnswer((realInvocation) => Stream.fromIterable([entity])); - final batchFactory = MockBatchFactory(); + final pillSheetService = MockPillSheetService(); + final userService = MockUserService(); + when(userService.stream()) + .thenAnswer((realInvocation) => Stream.fromIterable([_FakeUser()])); + + final pillSheetGroupService = MockPillSheetGroupService(); final pillSheet = PillSheet.create(PillSheetType.pillsheet_21); final pillSheetGroup = PillSheetGroup( pillSheetIDs: ["1"], pillSheets: [pillSheet], createdAt: now()); + when(pillSheetGroupService.streamForLatest()).thenAnswer( + (realInvocation) => Stream.fromIterable([pillSheetGroup])); - final pillSheetService = MockPillSheetService(); - final userService = MockUserService(); - when(userService.fetch()) - .thenAnswer((realInvocation) => Future.value(_FakeUser())); - when(userService.stream()).thenAnswer((realInvocation) => Stream.empty()); + final batchFactory = MockBatchFactory(); final pillSheetModifiedService = MockPillSheetModifiedHistoryService(); - final pillSheetGroupService = MockPillSheetGroupService(); - when(pillSheetGroupService.fetchLatest()) - .thenAnswer((realInvocation) => Future.value(pillSheetGroup)); - when(pillSheetGroupService.streamForLatest()) - .thenAnswer((realInvocation) => Stream.empty()); final store = SettingStateStore( batchFactory, @@ -91,10 +92,21 @@ void main() { pillSheetModifiedService, pillSheetGroupService, ); + store.setup(); + + final fakeUser = _FakeUser(); + final state = SettingState( + setting: entity, + isPremium: fakeUser.isPremium, + isTrial: fakeUser.isTrial, + latestPillSheetGroup: pillSheetGroup, + trialDeadlineDate: fakeUser.trialDeadlineDate, + ); await tester.pumpWidget( ProviderScope( overrides: [ + settingStateProvider.overrideWithValue(state), settingStoreProvider.overrideWithProvider( StateNotifierProvider( (ref) => store, @@ -126,27 +138,23 @@ void main() { ReminderTime(hour: 12, minute: 0) ], ); - when(settingService.fetch()) - .thenAnswer((realInvocation) => Future.value(entity)); when(settingService.stream()) .thenAnswer((realInvocation) => Stream.value(entity)); - final batchFactory = MockBatchFactory(); + final userService = MockUserService(); + when(userService.stream()) + .thenAnswer((realInvocation) => Stream.value(_FakeUser())); + final pillSheet = PillSheet.create(PillSheetType.pillsheet_21); final pillSheetGroup = PillSheetGroup( pillSheetIDs: ["1"], pillSheets: [pillSheet], createdAt: now()); + final pillSheetGroupService = MockPillSheetGroupService(); + when(pillSheetGroupService.streamForLatest()) + .thenAnswer((realInvocation) => Stream.value(pillSheetGroup)); + final batchFactory = MockBatchFactory(); final pillSheetService = MockPillSheetService(); - final userService = MockUserService(); - when(userService.fetch()) - .thenAnswer((realInvocation) => Future.value(_FakeUser())); - when(userService.stream()).thenAnswer((realInvocation) => Stream.empty()); final pillSheetModifiedService = MockPillSheetModifiedHistoryService(); - final pillSheetGroupService = MockPillSheetGroupService(); - when(pillSheetGroupService.fetchLatest()) - .thenAnswer((realInvocation) => Future.value(pillSheetGroup)); - when(pillSheetGroupService.streamForLatest()) - .thenAnswer((realInvocation) => Stream.empty()); final store = SettingStateStore( batchFactory, @@ -156,10 +164,21 @@ void main() { pillSheetModifiedService, pillSheetGroupService, ); + store.setup(); + + final fakeUser = _FakeUser(); + final state = SettingState( + setting: entity, + isPremium: fakeUser.isPremium, + isTrial: fakeUser.isTrial, + latestPillSheetGroup: pillSheetGroup, + trialDeadlineDate: fakeUser.trialDeadlineDate, + ); await tester.pumpWidget( ProviderScope( overrides: [ + settingStateProvider.overrideWithValue(state), settingStoreProvider.overrideWithProvider( StateNotifierProvider( (ref) => store, diff --git a/test/domain/settings/store_test.dart b/test/domain/settings/store_test.dart index 1d4ada6ce7..4960fe2b1e 100644 --- a/test/domain/settings/store_test.dart +++ b/test/domain/settings/store_test.dart @@ -14,9 +14,13 @@ import '../../helper/mock.mocks.dart'; class _FakeUser extends Fake implements User { _FakeUser({ +// ignore: unused_element this.fakeIsPremium = false, +// ignore: unused_element this.fakeIsTrial = false, +// ignore: unused_element this.fakeIsExpiredDiscountEntitlements = false, +// ignore: unused_element this.fakeIsTrialDeadlineDate, }); final bool fakeIsPremium;