mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-21 15:00:40 +00:00
fixed tests
This commit is contained in:
parent
4d02e71736
commit
fce8d0bb6a
16 changed files with 265 additions and 320 deletions
|
@ -48,7 +48,7 @@ void testE2E(String description) {
|
|||
description,
|
||||
(tester) async {
|
||||
await tester.pumpApplication(
|
||||
equipmentProfiles: [],
|
||||
equipmentProfiles: {},
|
||||
predefinedFilms: mockFilms.toFilmsMap(isUsed: true),
|
||||
customFilms: {},
|
||||
);
|
||||
|
@ -58,7 +58,7 @@ void testE2E(String description) {
|
|||
await tester.tapDescendantTextOf<SettingsScreen>(S.current.equipmentProfiles);
|
||||
await tester.tap(find.byIcon(Icons.add_outlined).first);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.setProfileName(mockEquipmentProfiles[0].name);
|
||||
await tester.selectProfileName(mockEquipmentProfiles[0].name);
|
||||
await tester.expandEquipmentProfileContainer(mockEquipmentProfiles[0].name);
|
||||
await tester.setIsoValues(0, mockEquipmentProfiles[0].isoValues);
|
||||
await tester.setNdValues(0, mockEquipmentProfiles[0].ndValues);
|
||||
|
@ -72,7 +72,7 @@ void testE2E(String description) {
|
|||
/// Create Praktica + Jupiter profile from Zenitar profile
|
||||
await tester.tap(find.byIcon(Icons.copy_outlined).first);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.setProfileName(mockEquipmentProfiles[1].name);
|
||||
await tester.selectProfileName(mockEquipmentProfiles[1].name);
|
||||
await tester.expandEquipmentProfileContainer(mockEquipmentProfiles[1].name);
|
||||
await tester.setApertureValues(1, mockEquipmentProfiles[1].apertureValues);
|
||||
await tester.setZoomValue(1, mockEquipmentProfiles[1].lensZoom);
|
||||
|
@ -152,7 +152,7 @@ extension EquipmentProfileActions on WidgetTester {
|
|||
await pump(Dimens.durationM);
|
||||
}
|
||||
|
||||
Future<void> setProfileName(String name) async {
|
||||
Future<void> selectProfileName(String name) async {
|
||||
await enterText(find.byType(TextField), name);
|
||||
await pump();
|
||||
await tapSaveButton();
|
||||
|
|
|
@ -5,12 +5,12 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
|||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class _MockIAPStorageService extends Mock implements IAPStorageService {}
|
||||
class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProfilesStorageService {}
|
||||
|
||||
class _MockFilmsStorageService extends Mock implements FilmsStorageService {}
|
||||
|
||||
class MockIAPProviders extends StatefulWidget {
|
||||
final List<EquipmentProfile>? equipmentProfiles;
|
||||
final Map<String, EquipmentProfile> equipmentProfiles;
|
||||
final String selectedEquipmentProfileId;
|
||||
final Map<String, SelectableFilm<Film>> predefinedFilms;
|
||||
final Map<String, SelectableFilm<FilmExponential>> customFilms;
|
||||
|
@ -18,14 +18,15 @@ class MockIAPProviders extends StatefulWidget {
|
|||
final Widget child;
|
||||
|
||||
MockIAPProviders({
|
||||
this.equipmentProfiles = const [],
|
||||
Map<String, EquipmentProfile>? equipmentProfiles,
|
||||
this.selectedEquipmentProfileId = '',
|
||||
Map<String, SelectableFilm<Film>>? predefinedFilms,
|
||||
Map<String, SelectableFilm<FilmExponential>>? customFilms,
|
||||
String? selectedFilmId,
|
||||
required this.child,
|
||||
super.key,
|
||||
}) : predefinedFilms = predefinedFilms ?? mockFilms.toFilmsMap(),
|
||||
}) : equipmentProfiles = equipmentProfiles ?? mockEquipmentProfiles.toProfilesMap(),
|
||||
predefinedFilms = predefinedFilms ?? mockFilms.toFilmsMap(),
|
||||
customFilms = customFilms ?? mockFilms.toFilmsMap(),
|
||||
selectedFilmId = selectedFilmId ?? const FilmStub().id;
|
||||
|
||||
|
@ -34,15 +35,18 @@ class MockIAPProviders extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _MockIAPProvidersState extends State<MockIAPProviders> {
|
||||
late final _MockIAPStorageService mockIAPStorageService;
|
||||
late final _MockEquipmentProfilesStorageService mockEquipmentProfilesStorageService;
|
||||
late final _MockFilmsStorageService mockFilmsStorageService;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
mockIAPStorageService = _MockIAPStorageService();
|
||||
when(() => mockIAPStorageService.equipmentProfiles).thenReturn(widget.equipmentProfiles ?? mockEquipmentProfiles);
|
||||
when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn(widget.selectedEquipmentProfileId);
|
||||
mockEquipmentProfilesStorageService = _MockEquipmentProfilesStorageService();
|
||||
when(() => mockEquipmentProfilesStorageService.init()).thenAnswer((_) async {});
|
||||
when(() => mockEquipmentProfilesStorageService.getProfiles())
|
||||
.thenAnswer((_) => Future.value(widget.equipmentProfiles));
|
||||
when(() => mockEquipmentProfilesStorageService.selectedEquipmentProfileId)
|
||||
.thenReturn(widget.selectedEquipmentProfileId);
|
||||
|
||||
mockFilmsStorageService = _MockFilmsStorageService();
|
||||
when(() => mockFilmsStorageService.init()).thenAnswer((_) async {});
|
||||
|
@ -53,10 +57,10 @@ class _MockIAPProvidersState extends State<MockIAPProviders> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return EquipmentProfileProvider(
|
||||
storageService: mockIAPStorageService,
|
||||
return EquipmentProfilesProvider(
|
||||
storageService: mockEquipmentProfilesStorageService,
|
||||
child: FilmsProvider(
|
||||
filmsStorageService: mockFilmsStorageService,
|
||||
storageService: mockFilmsStorageService,
|
||||
child: widget.child,
|
||||
),
|
||||
);
|
||||
|
@ -142,6 +146,10 @@ const mockFilms = [
|
|||
_FilmMultiplying(id: '4', name: 'Mock film 4', iso: 1200, reciprocityMultiplier: 1.5),
|
||||
];
|
||||
|
||||
extension EquipmentProfileMapper on List<EquipmentProfile> {
|
||||
Map<String, EquipmentProfile> toProfilesMap() => Map.fromEntries(map((e) => MapEntry(e.id, e)));
|
||||
}
|
||||
|
||||
extension FilmMapper on List<Film> {
|
||||
Map<String, ({T film, bool isUsed})> toFilmsMap<T extends Film>({bool isUsed = true}) =>
|
||||
Map.fromEntries(map((e) => MapEntry(e.id, (film: e as T, isUsed: isUsed))));
|
||||
|
|
|
@ -20,7 +20,7 @@ const mockPhotoEv100 = 8.3;
|
|||
extension WidgetTesterCommonActions on WidgetTester {
|
||||
Future<void> pumpApplication({
|
||||
IAPProductStatus productStatus = IAPProductStatus.purchased,
|
||||
List<EquipmentProfile>? equipmentProfiles,
|
||||
Map<String, EquipmentProfile>? equipmentProfiles,
|
||||
String selectedEquipmentProfileId = '',
|
||||
Map<String, SelectableFilm<Film>>? predefinedFilms,
|
||||
Map<String, SelectableFilm<FilmExponential>>? customFilms,
|
||||
|
|
|
@ -72,7 +72,7 @@ class _ApplicationWrapperState extends State<ApplicationWrapper> {
|
|||
volumeEventsService: const VolumeEventsService(LocalPlatform()),
|
||||
child: RemoteConfigProvider(
|
||||
remoteConfigService: remoteConfigService,
|
||||
child: EquipmentProfileProvider(
|
||||
child: EquipmentProfilesProvider(
|
||||
storageService: equipmentProfilesStorageService,
|
||||
onInitialized: equipmentProfilesStorageServiceCompleter.complete,
|
||||
child: FilmsProvider(
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
enum NavigationRoutes {
|
||||
meteringScreen,
|
||||
settingsScreen,
|
||||
filmsListScreen,
|
||||
filmEditScreen,
|
||||
equipmentProfilesListScreen,
|
||||
equipmentProfileEditScreen,
|
||||
filmsListScreen,
|
||||
filmEditScreen,
|
||||
proFeaturesScreen,
|
||||
timerScreen,
|
||||
}
|
||||
|
|
|
@ -1,31 +1,11 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/utils/context_utils.dart';
|
||||
import 'package:lightmeter/utils/selectable_provider.dart';
|
||||
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
|
||||
class EquipmentProfileProvider extends StatefulWidget {
|
||||
final EquipmentProfilesStorageService storageService;
|
||||
final VoidCallback? onInitialized;
|
||||
final Widget child;
|
||||
|
||||
const EquipmentProfileProvider({
|
||||
required this.storageService,
|
||||
this.onInitialized,
|
||||
required this.child,
|
||||
super.key,
|
||||
});
|
||||
|
||||
static EquipmentProfileProviderState of(BuildContext context) {
|
||||
return context.findAncestorStateOfType<EquipmentProfileProviderState>()!;
|
||||
}
|
||||
|
||||
@override
|
||||
State<EquipmentProfileProvider> createState() => EquipmentProfileProviderState();
|
||||
}
|
||||
|
||||
class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
||||
static const EquipmentProfile _defaultProfile = EquipmentProfile(
|
||||
class EquipmentProfilesProvider extends StatefulWidget {
|
||||
static const EquipmentProfile defaultProfile = EquipmentProfile(
|
||||
id: '',
|
||||
name: '',
|
||||
apertureValues: ApertureValue.values,
|
||||
|
@ -34,10 +14,30 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
|||
isoValues: IsoValue.values,
|
||||
);
|
||||
|
||||
final EquipmentProfilesStorageService storageService;
|
||||
final VoidCallback? onInitialized;
|
||||
final Widget child;
|
||||
|
||||
const EquipmentProfilesProvider({
|
||||
required this.storageService,
|
||||
this.onInitialized,
|
||||
required this.child,
|
||||
super.key,
|
||||
});
|
||||
|
||||
static EquipmentProfilesProviderState of(BuildContext context) {
|
||||
return context.findAncestorStateOfType<EquipmentProfilesProviderState>()!;
|
||||
}
|
||||
|
||||
@override
|
||||
State<EquipmentProfilesProvider> createState() => EquipmentProfilesProviderState();
|
||||
}
|
||||
|
||||
class EquipmentProfilesProviderState extends State<EquipmentProfilesProvider> {
|
||||
final Map<String, EquipmentProfile> _customProfiles = {};
|
||||
String _selectedId = '';
|
||||
|
||||
EquipmentProfile get _selectedProfile => _customProfiles[_selectedId] ?? _defaultProfile;
|
||||
EquipmentProfile get _selectedProfile => _customProfiles[_selectedId] ?? EquipmentProfilesProvider.defaultProfile;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -48,11 +48,8 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return EquipmentProfiles(
|
||||
values: [
|
||||
_defaultProfile,
|
||||
if (context.isPro) ..._customProfiles.values,
|
||||
],
|
||||
selected: context.isPro ? _selectedProfile : _defaultProfile,
|
||||
profiles: context.isPro ? _customProfiles : {},
|
||||
selected: context.isPro ? _selectedProfile : EquipmentProfilesProvider.defaultProfile,
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
|
@ -64,15 +61,6 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
|||
widget.onInitialized?.call();
|
||||
}
|
||||
|
||||
void setProfile(EquipmentProfile data) {
|
||||
if (_selectedId != data.id) {
|
||||
setState(() {
|
||||
_selectedId = data.id;
|
||||
});
|
||||
widget.storageService.selectedEquipmentProfileId = _selectedProfile.id;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> addProfile(EquipmentProfile profile) async {
|
||||
await widget.storageService.addProfile(profile);
|
||||
_customProfiles[profile.id] = profile;
|
||||
|
@ -98,32 +86,58 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
|||
Future<void> deleteProfile(EquipmentProfile profile) async {
|
||||
await widget.storageService.deleteProfile(profile.id);
|
||||
if (profile.id == _selectedId) {
|
||||
_selectedId = _defaultProfile.id;
|
||||
widget.storageService.selectedEquipmentProfileId = _defaultProfile.id;
|
||||
_selectedId = EquipmentProfilesProvider.defaultProfile.id;
|
||||
widget.storageService.selectedEquipmentProfileId = EquipmentProfilesProvider.defaultProfile.id;
|
||||
}
|
||||
_customProfiles.remove(profile.id);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void selectProfile(EquipmentProfile data) {
|
||||
if (_selectedId != data.id) {
|
||||
setState(() {
|
||||
_selectedId = data.id;
|
||||
});
|
||||
widget.storageService.selectedEquipmentProfileId = _selectedProfile.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EquipmentProfiles extends SelectableInheritedModel<EquipmentProfile> {
|
||||
enum _EquipmentProfilesModelAspect {
|
||||
profiles,
|
||||
selected,
|
||||
}
|
||||
|
||||
class EquipmentProfiles extends InheritedModel<_EquipmentProfilesModelAspect> {
|
||||
final Map<String, EquipmentProfile> profiles;
|
||||
final EquipmentProfile selected;
|
||||
|
||||
const EquipmentProfiles({
|
||||
super.key,
|
||||
required super.values,
|
||||
required super.selected,
|
||||
required this.profiles,
|
||||
required this.selected,
|
||||
required super.child,
|
||||
});
|
||||
|
||||
/// [_defaultProfile] + profiles created by the user
|
||||
/// _default + profiles create by the user
|
||||
static List<EquipmentProfile> of(BuildContext context) {
|
||||
return InheritedModel.inheritFrom<EquipmentProfiles>(context, aspect: SelectableAspect.list)!.values;
|
||||
final model =
|
||||
InheritedModel.inheritFrom<EquipmentProfiles>(context, aspect: _EquipmentProfilesModelAspect.profiles)!;
|
||||
return List.from([EquipmentProfilesProvider.defaultProfile, ...model.profiles.values]);
|
||||
}
|
||||
|
||||
static EquipmentProfile selectedOf(BuildContext context) {
|
||||
return InheritedModel.inheritFrom<EquipmentProfiles>(
|
||||
context,
|
||||
aspect: SelectableAspect.selected,
|
||||
)!
|
||||
return InheritedModel.inheritFrom<EquipmentProfiles>(context, aspect: _EquipmentProfilesModelAspect.selected)!
|
||||
.selected;
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(EquipmentProfiles _) => true;
|
||||
|
||||
@override
|
||||
bool updateShouldNotifyDependent(EquipmentProfiles oldWidget, Set<_EquipmentProfilesModelAspect> dependencies) {
|
||||
return (dependencies.contains(_EquipmentProfilesModelAspect.selected) && oldWidget.selected != selected) ||
|
||||
((dependencies.contains(_EquipmentProfilesModelAspect.profiles) ||
|
||||
dependencies.contains(_EquipmentProfilesModelAspect.profiles)) &&
|
||||
const DeepCollectionEquality().equals(oldWidget.profiles, profiles));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,22 +6,13 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
|||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class EquipmentProfileEditBloc extends Bloc<EquipmentProfileEditEvent, EquipmentProfileEditState> {
|
||||
static const EquipmentProfile _defaultProfile = EquipmentProfile(
|
||||
id: '',
|
||||
name: '',
|
||||
apertureValues: ApertureValue.values,
|
||||
ndValues: NdValue.values,
|
||||
shutterSpeedValues: ShutterSpeedValue.values,
|
||||
isoValues: IsoValue.values,
|
||||
);
|
||||
|
||||
final EquipmentProfileProviderState profilesProvider;
|
||||
final EquipmentProfilesProviderState profilesProvider;
|
||||
final EquipmentProfile _originalEquipmentProfile;
|
||||
EquipmentProfile _newEquipmentProfile;
|
||||
final bool _isEdit;
|
||||
|
||||
factory EquipmentProfileEditBloc(
|
||||
EquipmentProfileProviderState profilesProvider, {
|
||||
EquipmentProfilesProviderState profilesProvider, {
|
||||
required EquipmentProfile? profile,
|
||||
required bool isEdit,
|
||||
}) =>
|
||||
|
@ -33,7 +24,7 @@ class EquipmentProfileEditBloc extends Bloc<EquipmentProfileEditEvent, Equipment
|
|||
)
|
||||
: EquipmentProfileEditBloc._(
|
||||
profilesProvider,
|
||||
_defaultProfile,
|
||||
EquipmentProfilesProvider.defaultProfile,
|
||||
isEdit,
|
||||
);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class EquipmentProfileEditFlow extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (_) => EquipmentProfileEditBloc(
|
||||
EquipmentProfileProvider.of(context),
|
||||
EquipmentProfilesProvider.of(context),
|
||||
profile: args.profile,
|
||||
isEdit: args.profile != null,
|
||||
),
|
||||
|
|
|
@ -16,7 +16,7 @@ class EquipmentProfilePicker extends StatelessWidget {
|
|||
selectedValue: EquipmentProfiles.selectedOf(context),
|
||||
values: EquipmentProfiles.of(context),
|
||||
itemTitleBuilder: (_, value) => Text(value.id.isEmpty ? S.of(context).none : value.name),
|
||||
onChanged: EquipmentProfileProvider.of(context).setProfile,
|
||||
onChanged: EquipmentProfilesProvider.of(context).selectProfile,
|
||||
closedChild: ReadingValueContainer.singleValue(
|
||||
value: ReadingValue(
|
||||
label: S.of(context).equipmentProfile,
|
||||
|
|
|
@ -36,7 +36,7 @@ class MeteringScreenLayoutListTile extends StatelessWidget {
|
|||
},
|
||||
onSave: (value) {
|
||||
if (!value[MeteringScreenLayoutFeature.equipmentProfiles]!) {
|
||||
EquipmentProfileProvider.of(context).setProfile(EquipmentProfiles.of(context).first);
|
||||
EquipmentProfilesProvider.of(context).selectProfile(EquipmentProfiles.of(context).first);
|
||||
}
|
||||
if (!value[MeteringScreenLayoutFeature.filmPicker]!) {
|
||||
FilmsProvider.of(context).selectFilm(const FilmStub());
|
||||
|
|
|
@ -108,7 +108,6 @@ class _GoldenTestApplicationMockState extends State<GoldenTestApplicationMock> {
|
|||
],
|
||||
child: _MockApplicationWrapper(
|
||||
child: MockIAPProviders(
|
||||
equipmentProfiles: mockEquipmentProfiles,
|
||||
selectedEquipmentProfileId: mockEquipmentProfiles.first.id,
|
||||
selectedFilmId: mockFilms.first.id,
|
||||
child: Builder(
|
||||
|
|
|
@ -5,14 +5,29 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
|||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class _MockIAPStorageService extends Mock implements IAPStorageService {}
|
||||
import '../../integration_test/mocks/paid_features_mock.dart';
|
||||
|
||||
class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProfilesStorageService {}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
late _MockIAPStorageService storageService;
|
||||
late _MockEquipmentProfilesStorageService storageService;
|
||||
|
||||
setUpAll(() {
|
||||
storageService = _MockIAPStorageService();
|
||||
storageService = _MockEquipmentProfilesStorageService();
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
registerFallbackValue(_customProfiles.first);
|
||||
when(() => storageService.addProfile(any<EquipmentProfile>())).thenAnswer((_) async {});
|
||||
when(
|
||||
() => storageService.updateProfile(
|
||||
id: any<String>(named: 'id'),
|
||||
name: any<String>(named: 'name'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(() => storageService.deleteProfile(any<String>())).thenAnswer((_) async {});
|
||||
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toProfilesMap()));
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
|
@ -29,35 +44,36 @@ void main() {
|
|||
price: '0.0\$',
|
||||
),
|
||||
],
|
||||
child: EquipmentProfileProvider(
|
||||
child: EquipmentProfilesProvider(
|
||||
storageService: storageService,
|
||||
child: const _Application(),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
void expectEquipmentProfilesCount(int count) {
|
||||
expect(find.text('Equipment profiles count: $count'), findsOneWidget);
|
||||
expect(find.text(_EquipmentProfilesCount.text(count)), findsOneWidget);
|
||||
}
|
||||
|
||||
void expectSelectedEquipmentProfileName(String name) {
|
||||
expect(find.text('Selected equipment profile: $name'), findsOneWidget);
|
||||
expect(find.text(_SelectedEquipmentProfile.text(name)), findsOneWidget);
|
||||
}
|
||||
|
||||
group(
|
||||
'EquipmentProfileProvider dependency on IAPProductStatus',
|
||||
'EquipmentProfilesProvider dependency on IAPProductStatus',
|
||||
() {
|
||||
setUp(() {
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles.first.id);
|
||||
when(() => storageService.equipmentProfiles).thenReturn(_customProfiles);
|
||||
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toProfilesMap()));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'IAPProductStatus.purchased - show all saved profiles',
|
||||
(tester) async {
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectEquipmentProfilesCount(3);
|
||||
expectEquipmentProfilesCount(_customProfiles.length + 1);
|
||||
expectSelectedEquipmentProfileName(_customProfiles.first.name);
|
||||
},
|
||||
);
|
||||
|
@ -82,203 +98,105 @@ void main() {
|
|||
},
|
||||
);
|
||||
|
||||
group('EquipmentProfileProvider CRUD', () {
|
||||
testWidgets(
|
||||
'Add',
|
||||
(tester) async {
|
||||
when(() => storageService.equipmentProfiles).thenReturn([]);
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||
testWidgets(
|
||||
'EquipmentProfilesProvider CRUD',
|
||||
(tester) async {
|
||||
when(() => storageService.getProfiles()).thenAnswer((_) async => {});
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectEquipmentProfilesCount(1);
|
||||
expectSelectedEquipmentProfileName('');
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectEquipmentProfilesCount(1);
|
||||
expectSelectedEquipmentProfileName('');
|
||||
|
||||
await tester.tap(find.byKey(_Application.addProfileButtonKey));
|
||||
await tester.pump();
|
||||
expectEquipmentProfilesCount(2);
|
||||
expectSelectedEquipmentProfileName('');
|
||||
/// Add first profile and verify
|
||||
await tester.equipmentProfilesProvider.addProfile(_customProfiles.first);
|
||||
await tester.pump();
|
||||
expectEquipmentProfilesCount(2);
|
||||
expectSelectedEquipmentProfileName('');
|
||||
verify(() => storageService.addProfile(any<EquipmentProfile>())).called(1);
|
||||
|
||||
verifyNever(() => storageService.selectedEquipmentProfileId = '');
|
||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
||||
},
|
||||
);
|
||||
/// Add the other profiles and select the 1st one
|
||||
for (final profile in _customProfiles.skip(1)) {
|
||||
await tester.equipmentProfilesProvider.addProfile(profile);
|
||||
}
|
||||
tester.equipmentProfilesProvider.selectProfile(_customProfiles.first);
|
||||
await tester.pump();
|
||||
expectEquipmentProfilesCount(1 + _customProfiles.length);
|
||||
expectSelectedEquipmentProfileName(_customProfiles.first.name);
|
||||
|
||||
testWidgets(
|
||||
'Add from',
|
||||
(tester) async {
|
||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||
/// Edit the selected profile
|
||||
final updatedName = "${_customProfiles.first} updated";
|
||||
await tester.equipmentProfilesProvider.updateProfile(_customProfiles.first.copyWith(name: updatedName));
|
||||
await tester.pump();
|
||||
expectEquipmentProfilesCount(1 + _customProfiles.length);
|
||||
expectSelectedEquipmentProfileName(updatedName);
|
||||
verify(() => storageService.updateProfile(id: _customProfiles.first.id, name: updatedName)).called(1);
|
||||
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectEquipmentProfilesCount(3);
|
||||
expectSelectedEquipmentProfileName('');
|
||||
/// Delete a non-selected profile
|
||||
await tester.equipmentProfilesProvider.deleteProfile(_customProfiles.last);
|
||||
await tester.pump();
|
||||
expectEquipmentProfilesCount(1 + _customProfiles.length - 1);
|
||||
expectSelectedEquipmentProfileName(updatedName);
|
||||
verifyNever(() => storageService.selectedEquipmentProfileId = '');
|
||||
verify(() => storageService.deleteProfile(_customProfiles.last.id)).called(1);
|
||||
|
||||
await tester.tap(find.byKey(_Application.addFromProfileButtonKey(_customProfiles[0].id)));
|
||||
await tester.pump();
|
||||
expectEquipmentProfilesCount(4);
|
||||
expectSelectedEquipmentProfileName('');
|
||||
/// Delete the selected profile
|
||||
await tester.equipmentProfilesProvider.deleteProfile(_customProfiles.first);
|
||||
await tester.pump();
|
||||
expectEquipmentProfilesCount(1 + _customProfiles.length - 2);
|
||||
expectSelectedEquipmentProfileName('');
|
||||
verify(() => storageService.selectedEquipmentProfileId = '').called(1);
|
||||
verify(() => storageService.deleteProfile(_customProfiles.first.id)).called(1);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
verifyNever(() => storageService.selectedEquipmentProfileId = '');
|
||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'Edit selected',
|
||||
(tester) async {
|
||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
||||
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
|
||||
/// Change the name & limit ISO values of the both added profiles
|
||||
await tester.tap(find.byKey(_Application.updateProfileButtonKey(_customProfiles[0].id)));
|
||||
await tester.pumpAndSettle();
|
||||
expectEquipmentProfilesCount(3);
|
||||
expectSelectedEquipmentProfileName("${_customProfiles[0].name} updated");
|
||||
|
||||
verifyNever(() => storageService.selectedEquipmentProfileId = _customProfiles[0].id);
|
||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'Delete selected',
|
||||
(tester) async {
|
||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
||||
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectEquipmentProfilesCount(3);
|
||||
expectSelectedEquipmentProfileName(_customProfiles[0].name);
|
||||
|
||||
/// Delete the selected profile
|
||||
await tester.tap(find.byKey(_Application.deleteProfileButtonKey(_customProfiles[0].id)));
|
||||
await tester.pumpAndSettle();
|
||||
expectEquipmentProfilesCount(2);
|
||||
expectSelectedEquipmentProfileName('');
|
||||
|
||||
verify(() => storageService.selectedEquipmentProfileId = '').called(1);
|
||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'Delete not selected',
|
||||
(tester) async {
|
||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
||||
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectEquipmentProfilesCount(3);
|
||||
expectSelectedEquipmentProfileName(_customProfiles[0].name);
|
||||
|
||||
/// Delete the not selected profile
|
||||
await tester.tap(find.byKey(_Application.deleteProfileButtonKey(_customProfiles[1].id)));
|
||||
await tester.pumpAndSettle();
|
||||
expectEquipmentProfilesCount(2);
|
||||
expectSelectedEquipmentProfileName(_customProfiles[0].name);
|
||||
|
||||
verifyNever(() => storageService.selectedEquipmentProfileId = '');
|
||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'Select',
|
||||
(tester) async {
|
||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectEquipmentProfilesCount(3);
|
||||
expectSelectedEquipmentProfileName('');
|
||||
|
||||
/// Select the 1st custom profile
|
||||
await tester.tap(find.byKey(_Application.setProfileButtonKey(_customProfiles[0].id)));
|
||||
await tester.pumpAndSettle();
|
||||
expectEquipmentProfilesCount(3);
|
||||
expectSelectedEquipmentProfileName(_customProfiles[0].name);
|
||||
|
||||
verify(() => storageService.selectedEquipmentProfileId = _customProfiles[0].id).called(1);
|
||||
verifyNever(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>());
|
||||
},
|
||||
);
|
||||
});
|
||||
extension on WidgetTester {
|
||||
EquipmentProfilesProviderState get equipmentProfilesProvider {
|
||||
final BuildContext context = element(find.byType(_Application));
|
||||
return EquipmentProfilesProvider.of(context);
|
||||
}
|
||||
}
|
||||
|
||||
class _Application extends StatelessWidget {
|
||||
const _Application();
|
||||
|
||||
static ValueKey get addProfileButtonKey => const ValueKey('addProfileButtonKey');
|
||||
static ValueKey addFromProfileButtonKey(String id) => ValueKey('addFromProfileButtonKey$id');
|
||||
static ValueKey setProfileButtonKey(String id) => ValueKey('setProfileButtonKey$id');
|
||||
static ValueKey updateProfileButtonKey(String id) => ValueKey('updateProfileButtonKey$id');
|
||||
static ValueKey deleteProfileButtonKey(String id) => ValueKey('deleteProfileButtonKey$id');
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
return const MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('IAPProviders test')),
|
||||
body: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Text("Equipment profiles count: ${EquipmentProfiles.of(context).length}"),
|
||||
Text("Selected equipment profile: ${EquipmentProfiles.selectedOf(context).name}"),
|
||||
ElevatedButton(
|
||||
key: addProfileButtonKey,
|
||||
onPressed: () {
|
||||
EquipmentProfileProvider.of(context).addProfile('Test added');
|
||||
},
|
||||
child: const Text("Add"),
|
||||
),
|
||||
...EquipmentProfiles.of(context).map((e) => _equipmentProfilesCrudRow(context, e)),
|
||||
_EquipmentProfilesCount(),
|
||||
_SelectedEquipmentProfile(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _equipmentProfilesCrudRow(BuildContext context, EquipmentProfile profile) {
|
||||
return Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
key: setProfileButtonKey(profile.id),
|
||||
onPressed: () {
|
||||
EquipmentProfileProvider.of(context).setProfile(profile);
|
||||
},
|
||||
child: const Text("Set"),
|
||||
),
|
||||
ElevatedButton(
|
||||
key: addFromProfileButtonKey(profile.id),
|
||||
onPressed: () {
|
||||
EquipmentProfileProvider.of(context).addProfile('Test from ${profile.name}', profile);
|
||||
},
|
||||
child: const Text("Add from"),
|
||||
),
|
||||
ElevatedButton(
|
||||
key: updateProfileButtonKey(profile.id),
|
||||
onPressed: () {
|
||||
EquipmentProfileProvider.of(context).updateProfile(
|
||||
profile.copyWith(
|
||||
name: '${profile.name} updated',
|
||||
isoValues: _customProfiles.first.isoValues,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text("Update"),
|
||||
),
|
||||
ElevatedButton(
|
||||
key: deleteProfileButtonKey(profile.id),
|
||||
onPressed: () {
|
||||
EquipmentProfileProvider.of(context).deleteProfile(profile);
|
||||
},
|
||||
child: const Text("Delete"),
|
||||
),
|
||||
],
|
||||
);
|
||||
class _EquipmentProfilesCount extends StatelessWidget {
|
||||
static String text(int count) => "Profiles count: $count";
|
||||
|
||||
const _EquipmentProfilesCount();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(text(EquipmentProfiles.of(context).length));
|
||||
}
|
||||
}
|
||||
|
||||
class _SelectedEquipmentProfile extends StatelessWidget {
|
||||
static String text(String name) => "Selected profile: $name}";
|
||||
|
||||
const _SelectedEquipmentProfile();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(text(EquipmentProfiles.selectedOf(context).name));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,25 +9,24 @@ class _MockFilmsStorageService extends Mock implements FilmsStorageService {}
|
|||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
late _MockFilmsStorageService mockFilmsStorageService;
|
||||
late _MockFilmsStorageService storageService;
|
||||
|
||||
setUpAll(() {
|
||||
mockFilmsStorageService = _MockFilmsStorageService();
|
||||
storageService = _MockFilmsStorageService();
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
registerFallbackValue(mockCustomFilms.first);
|
||||
when(() => mockFilmsStorageService.toggleFilm(any<Film>(), any<bool>())).thenAnswer((_) async {});
|
||||
when(() => mockFilmsStorageService.addFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
||||
when(() => mockFilmsStorageService.updateFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
||||
when(() => mockFilmsStorageService.deleteFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
||||
when(() => mockFilmsStorageService.getPredefinedFilms())
|
||||
.thenAnswer((_) => Future.value(mockPredefinedFilms.toFilmsMap()));
|
||||
when(() => mockFilmsStorageService.getCustomFilms()).thenAnswer((_) => Future.value(mockCustomFilms.toFilmsMap()));
|
||||
when(() => storageService.toggleFilm(any<Film>(), any<bool>())).thenAnswer((_) async {});
|
||||
when(() => storageService.addFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
||||
when(() => storageService.updateFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
||||
when(() => storageService.deleteFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
||||
when(() => storageService.getPredefinedFilms()).thenAnswer((_) => Future.value(mockPredefinedFilms.toFilmsMap()));
|
||||
when(() => storageService.getCustomFilms()).thenAnswer((_) => Future.value(mockCustomFilms.toFilmsMap()));
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
reset(mockFilmsStorageService);
|
||||
reset(storageService);
|
||||
});
|
||||
|
||||
Future<void> pumpTestWidget(WidgetTester tester, IAPProductStatus productStatus) async {
|
||||
|
@ -41,7 +40,7 @@ void main() {
|
|||
),
|
||||
],
|
||||
child: FilmsProvider(
|
||||
filmsStorageService: mockFilmsStorageService,
|
||||
storageService: storageService,
|
||||
child: const _Application(),
|
||||
),
|
||||
),
|
||||
|
@ -69,11 +68,10 @@ void main() {
|
|||
'FilmsProvider dependency on IAPProductStatus',
|
||||
() {
|
||||
setUp(() {
|
||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn(mockPredefinedFilms.first.id);
|
||||
when(() => mockFilmsStorageService.getPredefinedFilms())
|
||||
when(() => storageService.selectedFilmId).thenReturn(mockPredefinedFilms.first.id);
|
||||
when(() => storageService.getPredefinedFilms())
|
||||
.thenAnswer((_) => Future.value(mockPredefinedFilms.toFilmsMap()));
|
||||
when(() => mockFilmsStorageService.getCustomFilms())
|
||||
.thenAnswer((_) => Future.value(mockCustomFilms.toFilmsMap()));
|
||||
when(() => storageService.getCustomFilms()).thenAnswer((_) => Future.value(mockCustomFilms.toFilmsMap()));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
|
@ -117,7 +115,7 @@ void main() {
|
|||
testWidgets(
|
||||
'toggle predefined film',
|
||||
(tester) async {
|
||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn(mockPredefinedFilms.first.id);
|
||||
when(() => storageService.selectedFilmId).thenReturn(mockPredefinedFilms.first.id);
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectPredefinedFilmsCount(mockPredefinedFilms.length);
|
||||
expectCustomFilmsCount(mockCustomFilms.length);
|
||||
|
@ -131,15 +129,15 @@ void main() {
|
|||
expectFilmsInUseCount(mockPredefinedFilms.length - 1 + mockCustomFilms.length + 1);
|
||||
expectSelectedFilmName('');
|
||||
|
||||
verify(() => mockFilmsStorageService.toggleFilm(mockPredefinedFilms.first, false)).called(1);
|
||||
verify(() => mockFilmsStorageService.selectedFilmId = '').called(1);
|
||||
verify(() => storageService.toggleFilm(mockPredefinedFilms.first, false)).called(1);
|
||||
verify(() => storageService.selectedFilmId = '').called(1);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'toggle custom film',
|
||||
(tester) async {
|
||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn(mockCustomFilms.first.id);
|
||||
when(() => storageService.selectedFilmId).thenReturn(mockCustomFilms.first.id);
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectPredefinedFilmsCount(mockPredefinedFilms.length);
|
||||
expectCustomFilmsCount(mockCustomFilms.length);
|
||||
|
@ -153,8 +151,8 @@ void main() {
|
|||
expectFilmsInUseCount(mockPredefinedFilms.length - 1 + mockCustomFilms.length + 1);
|
||||
expectSelectedFilmName('');
|
||||
|
||||
verify(() => mockFilmsStorageService.toggleFilm(mockCustomFilms.first, false)).called(1);
|
||||
verify(() => mockFilmsStorageService.selectedFilmId = '').called(1);
|
||||
verify(() => storageService.toggleFilm(mockCustomFilms.first, false)).called(1);
|
||||
verify(() => storageService.selectedFilmId = '').called(1);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
@ -163,7 +161,7 @@ void main() {
|
|||
testWidgets(
|
||||
'selectFilm',
|
||||
(tester) async {
|
||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn('');
|
||||
when(() => storageService.selectedFilmId).thenReturn('');
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectSelectedFilmName('');
|
||||
|
||||
|
@ -175,16 +173,16 @@ void main() {
|
|||
await tester.pump();
|
||||
expectSelectedFilmName(mockCustomFilms.first.name);
|
||||
|
||||
verify(() => mockFilmsStorageService.selectedFilmId = mockPredefinedFilms.first.id).called(1);
|
||||
verify(() => mockFilmsStorageService.selectedFilmId = mockCustomFilms.first.id).called(1);
|
||||
verify(() => storageService.selectedFilmId = mockPredefinedFilms.first.id).called(1);
|
||||
verify(() => storageService.selectedFilmId = mockCustomFilms.first.id).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'Custom film CRUD',
|
||||
(tester) async {
|
||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn('');
|
||||
when(() => mockFilmsStorageService.getCustomFilms()).thenAnswer((_) => Future.value({}));
|
||||
when(() => storageService.selectedFilmId).thenReturn('');
|
||||
when(() => storageService.getCustomFilms()).thenAnswer((_) => Future.value({}));
|
||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||
expectPredefinedFilmsCount(mockPredefinedFilms.length);
|
||||
expectCustomFilmsCount(0);
|
||||
|
@ -199,16 +197,16 @@ void main() {
|
|||
expectCustomFilmsCount(1);
|
||||
expectFilmsInUseCount(mockPredefinedFilms.length + 1 + 1);
|
||||
expectSelectedFilmName(mockCustomFilms.first.name);
|
||||
verify(() => mockFilmsStorageService.addFilm(mockCustomFilms.first)).called(1);
|
||||
verify(() => mockFilmsStorageService.toggleFilm(mockCustomFilms.first, true)).called(1);
|
||||
verify(() => mockFilmsStorageService.selectedFilmId = mockCustomFilms.first.id).called(1);
|
||||
verify(() => storageService.addFilm(mockCustomFilms.first)).called(1);
|
||||
verify(() => storageService.toggleFilm(mockCustomFilms.first, true)).called(1);
|
||||
verify(() => storageService.selectedFilmId = mockCustomFilms.first.id).called(1);
|
||||
|
||||
const editedFilmName = 'Edited custom film 2x';
|
||||
final editedFilm = mockCustomFilms.first.copyWith(name: editedFilmName);
|
||||
await tester.filmsProvider.updateCustomFilm(editedFilm);
|
||||
await tester.pump();
|
||||
expectSelectedFilmName(editedFilm.name);
|
||||
verify(() => mockFilmsStorageService.updateFilm(editedFilm)).called(1);
|
||||
verify(() => storageService.updateFilm(editedFilm)).called(1);
|
||||
|
||||
await tester.filmsProvider.deleteCustomFilm(editedFilm);
|
||||
await tester.pump();
|
||||
|
@ -216,8 +214,8 @@ void main() {
|
|||
expectCustomFilmsCount(0);
|
||||
expectFilmsInUseCount(mockPredefinedFilms.length + 0 + 1);
|
||||
expectSelectedFilmName('');
|
||||
verify(() => mockFilmsStorageService.deleteFilm(editedFilm)).called(1);
|
||||
verify(() => mockFilmsStorageService.selectedFilmId = '').called(1);
|
||||
verify(() => storageService.deleteFilm(editedFilm)).called(1);
|
||||
verify(() => storageService.selectedFilmId = '').called(1);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,18 +7,19 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
|||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import '../../../../../../integration_test/mocks/paid_features_mock.dart';
|
||||
import '../../../../../application_mock.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
class _MockIAPStorageService extends Mock implements IAPStorageService {}
|
||||
class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProfilesStorageService {}
|
||||
|
||||
void main() {
|
||||
late final _MockIAPStorageService mockIAPStorageService;
|
||||
late final _MockEquipmentProfilesStorageService storageService;
|
||||
|
||||
setUpAll(() {
|
||||
mockIAPStorageService = _MockIAPStorageService();
|
||||
when(() => mockIAPStorageService.equipmentProfiles).thenReturn(_mockEquipmentProfiles);
|
||||
when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn('');
|
||||
storageService = _MockEquipmentProfilesStorageService();
|
||||
when(() => storageService.getProfiles()).thenAnswer((_) async => _mockEquipmentProfiles.toProfilesMap());
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||
});
|
||||
|
||||
Future<void> pumpApplication(WidgetTester tester) async {
|
||||
|
@ -31,8 +32,8 @@ void main() {
|
|||
price: '0.0\$',
|
||||
),
|
||||
],
|
||||
child: EquipmentProfileProvider(
|
||||
storageService: mockIAPStorageService,
|
||||
child: EquipmentProfilesProvider(
|
||||
storageService: storageService,
|
||||
child: const WidgetTestApplicationMock(
|
||||
child: Row(children: [Expanded(child: EquipmentProfilePicker())]),
|
||||
),
|
||||
|
@ -59,7 +60,7 @@ void main() {
|
|||
testWidgets(
|
||||
'None',
|
||||
(tester) async {
|
||||
when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn('');
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||
await pumpApplication(tester);
|
||||
expectReadingValueContainerText(S.current.none);
|
||||
await tester.openAnimatedPicker<EquipmentProfilePicker>();
|
||||
|
@ -70,7 +71,7 @@ void main() {
|
|||
testWidgets(
|
||||
'Praktica + Zenitar',
|
||||
(tester) async {
|
||||
when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn(_mockEquipmentProfiles.first.id);
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_mockEquipmentProfiles.first.id);
|
||||
await pumpApplication(tester);
|
||||
expectReadingValueContainerText(_mockEquipmentProfiles.first.name);
|
||||
await tester.openAnimatedPicker<EquipmentProfilePicker>();
|
||||
|
|
|
@ -36,7 +36,7 @@ void main() {
|
|||
),
|
||||
],
|
||||
child: FilmsProvider(
|
||||
filmsStorageService: mockFilmsStorageService,
|
||||
storageService: mockFilmsStorageService,
|
||||
child: const WidgetTestApplicationMock(
|
||||
child: Row(
|
||||
children: [
|
||||
|
|
|
@ -6,16 +6,29 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
|||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import '../../../../integration_test/mocks/paid_features_mock.dart';
|
||||
import '../../../function_mock.dart';
|
||||
|
||||
class _MockIAPStorageService extends Mock implements IAPStorageService {}
|
||||
class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProfilesStorageService {}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
final storageService = _MockIAPStorageService();
|
||||
final equipmentProfileProviderKey = GlobalKey<EquipmentProfileProviderState>();
|
||||
final storageService = _MockEquipmentProfilesStorageService();
|
||||
final onDidChangeDependencies = MockValueChanged<EquipmentProfile>();
|
||||
|
||||
setUp(() {
|
||||
registerFallbackValue(_customProfiles.first);
|
||||
when(() => storageService.addProfile(any<EquipmentProfile>())).thenAnswer((_) async {});
|
||||
when(
|
||||
() => storageService.updateProfile(
|
||||
id: any<String>(named: 'id'),
|
||||
name: any<String>(named: 'name'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(() => storageService.deleteProfile(any<String>())).thenAnswer((_) async {});
|
||||
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toProfilesMap()));
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
reset(onDidChangeDependencies);
|
||||
reset(storageService);
|
||||
|
@ -31,8 +44,7 @@ void main() {
|
|||
price: '0.0\$',
|
||||
),
|
||||
],
|
||||
child: EquipmentProfileProvider(
|
||||
key: equipmentProfileProviderKey,
|
||||
child: EquipmentProfilesProvider(
|
||||
storageService: storageService,
|
||||
child: MaterialApp(
|
||||
home: EquipmentProfileListener(
|
||||
|
@ -48,11 +60,10 @@ void main() {
|
|||
testWidgets(
|
||||
'Trigger `onDidChangeDependencies` by selecting a new profile',
|
||||
(tester) async {
|
||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||
await pumpTestWidget(tester);
|
||||
|
||||
equipmentProfileProviderKey.currentState!.setProfile(_customProfiles[0]);
|
||||
tester.equipmentProfilesProvider.selectProfile(_customProfiles[0]);
|
||||
await tester.pump();
|
||||
verify(() => onDidChangeDependencies.onChanged(_customProfiles[0])).called(1);
|
||||
},
|
||||
|
@ -61,18 +72,17 @@ void main() {
|
|||
testWidgets(
|
||||
'Trigger `onDidChangeDependencies` by updating the selected profile',
|
||||
(tester) async {
|
||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
||||
await pumpTestWidget(tester);
|
||||
|
||||
final updatedProfile1 = _customProfiles[0].copyWith(name: 'Test 1 updated');
|
||||
equipmentProfileProviderKey.currentState!.updateProfile(updatedProfile1);
|
||||
await tester.equipmentProfilesProvider.updateProfile(updatedProfile1);
|
||||
await tester.pump();
|
||||
verify(() => onDidChangeDependencies.onChanged(updatedProfile1)).called(1);
|
||||
|
||||
/// Verify that updating the not selected profile doesn't trigger the callback
|
||||
final updatedProfile2 = _customProfiles[1].copyWith(name: 'Test 2 updated');
|
||||
equipmentProfileProviderKey.currentState!.updateProfile(updatedProfile2);
|
||||
await tester.equipmentProfilesProvider.updateProfile(updatedProfile2);
|
||||
await tester.pump();
|
||||
verifyNever(() => onDidChangeDependencies.onChanged(updatedProfile2));
|
||||
},
|
||||
|
@ -81,18 +91,24 @@ void main() {
|
|||
testWidgets(
|
||||
"Don't trigger `onDidChangeDependencies` by updating the unselected profile",
|
||||
(tester) async {
|
||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
||||
await pumpTestWidget(tester);
|
||||
|
||||
final updatedProfile2 = _customProfiles[1].copyWith(name: 'Test 2 updated');
|
||||
equipmentProfileProviderKey.currentState!.updateProfile(updatedProfile2);
|
||||
await tester.equipmentProfilesProvider.updateProfile(updatedProfile2);
|
||||
await tester.pump();
|
||||
verifyNever(() => onDidChangeDependencies.onChanged(updatedProfile2));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
extension on WidgetTester {
|
||||
EquipmentProfilesProviderState get equipmentProfilesProvider {
|
||||
final BuildContext context = element(find.byType(MaterialApp));
|
||||
return EquipmentProfilesProvider.of(context);
|
||||
}
|
||||
}
|
||||
|
||||
final List<EquipmentProfile> _customProfiles = [
|
||||
const EquipmentProfile(
|
||||
id: '1',
|
||||
|
|
Loading…
Reference in a new issue