Skip to content

Commit dbdec5c

Browse files
committed
Add tests for db cache
1 parent b1a4921 commit dbdec5c

9 files changed

+110
-56
lines changed

lib/database/ingredients/ingredients_database.g.dart

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/providers/nutrition.dart

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class NutritionPlansProvider with ChangeNotifier {
4646
final WgerBaseProvider baseProvider;
4747
late IngredientDatabase database;
4848
List<NutritionalPlan> _plans = [];
49-
List<Ingredient> _ingredients = [];
49+
List<Ingredient> ingredients = [];
5050

5151
NutritionPlansProvider(this.baseProvider, List<NutritionalPlan> entries,
5252
{IngredientDatabase? database})
@@ -58,14 +58,10 @@ class NutritionPlansProvider with ChangeNotifier {
5858
return [..._plans];
5959
}
6060

61-
set ingredients(items) {
62-
_ingredients = items;
63-
}
64-
6561
/// Clears all lists
6662
void clear() {
6763
_plans = [];
68-
_ingredients = [];
64+
ingredients = [];
6965
}
7066

7167
/// Returns the current active nutritional plan. At the moment this is just
@@ -299,11 +295,12 @@ class NutritionPlansProvider with ChangeNotifier {
299295
/// Fetch and return an ingredient
300296
///
301297
/// If the ingredient is not known locally, it is fetched from the server
302-
Future<Ingredient> fetchIngredient(int ingredientId) async {
298+
Future<Ingredient> fetchIngredient(int ingredientId, {IngredientDatabase? database}) async {
299+
database ??= this.database;
303300
Ingredient ingredient;
304301

305302
try {
306-
ingredient = _ingredients.firstWhere((e) => e.id == ingredientId);
303+
ingredient = ingredients.firstWhere((e) => e.id == ingredientId);
307304
} on StateError {
308305
final ingredientDb = await (database.select(database.ingredients)
309306
..where((e) => e.id.equals(ingredientId)))
@@ -312,6 +309,7 @@ class NutritionPlansProvider with ChangeNotifier {
312309
// Try to fetch from local db
313310
if (ingredientDb != null) {
314311
ingredient = Ingredient.fromJson(jsonDecode(ingredientDb.data));
312+
ingredients.add(ingredient);
315313
log("Loaded ingredient '${ingredient.name}' from db cache");
316314

317315
// Prune old entries
@@ -324,7 +322,7 @@ class NutritionPlansProvider with ChangeNotifier {
324322
baseProvider.makeUrl(_ingredientInfoPath, id: ingredientId),
325323
);
326324
ingredient = Ingredient.fromJson(data);
327-
_ingredients.add(ingredient);
325+
ingredients.add(ingredient);
328326

329327
database.into(database.ingredients).insert(
330328
IngredientsCompanion.insert(

test/core/settings_test.mocks.dart

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -422,16 +422,6 @@ class MockExercisesProvider extends _i1.Mock implements _i9.ExercisesProvider {
422422
)),
423423
) as _i10.Future<_i4.Exercise>);
424424

425-
@override
426-
_i10.Future<void> checkExerciseCacheVersion() => (super.noSuchMethod(
427-
Invocation.method(
428-
#checkExerciseCacheVersion,
429-
[],
430-
),
431-
returnValue: _i10.Future<void>.value(),
432-
returnValueForMissingStub: _i10.Future<void>.value(),
433-
) as _i10.Future<void>);
434-
435425
@override
436426
_i10.Future<void> initCacheTimesLocalPrefs({dynamic forceInit = false}) =>
437427
(super.noSuchMethod(

test/exercises/exercise_provider_db_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ void main() {
381381
});
382382
});
383383

384-
group('Exercises', () {
384+
group('Exercise cache DB', () {
385385
test('that if there is already valid data in the DB, the API is not hit', () async {
386386
// Arrange
387387
final prefs = await SharedPreferences.getInstance();

test/nutrition/nutrition_provider_test.dart

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,26 @@ import '../measurements/measurement_provider_test.mocks.dart';
1313
void main() {
1414
late NutritionPlansProvider nutritionProvider;
1515
late MockWgerBaseProvider mockWgerBaseProvider;
16+
late IngredientDatabase database;
17+
late Map<String, dynamic> ingredient59887Response;
18+
19+
// Needs to be configured here, setUp runs on every test, setUpAll only once
20+
setUpAll(() {
21+
database = IngredientDatabase.inMemory(NativeDatabase.memory());
22+
});
1623

1724
setUp(() {
1825
mockWgerBaseProvider = MockWgerBaseProvider();
1926
nutritionProvider = NutritionPlansProvider(
2027
mockWgerBaseProvider,
2128
[],
22-
database: IngredientDatabase.inMemory(NativeDatabase.memory()),
29+
database: database,
2330
);
2431

2532
const String planInfoUrl = 'nutritionplaninfo';
2633
const String planUrl = 'nutritionplan';
2734
const String diaryUrl = 'nutritiondiary';
35+
const String ingredientInfoUrl = 'ingredientinfo';
2836

2937
final Map<String, dynamic> nutritionalPlanInfoResponse = jsonDecode(
3038
fixture('nutrition/nutritional_plan_info_detail_response.json'),
@@ -35,7 +43,7 @@ void main() {
3543
final List<dynamic> nutritionDiaryResponse = jsonDecode(
3644
fixture('nutrition/nutrition_diary_response.json'),
3745
)['results'];
38-
final Map<String, dynamic> ingredient59887Response = jsonDecode(
46+
ingredient59887Response = jsonDecode(
3947
fixture('nutrition/ingredientinfo_59887.json'),
4048
);
4149
final Map<String, dynamic> ingredient10065Response = jsonDecode(
@@ -68,9 +76,16 @@ void main() {
6876
host: 'localhost',
6977
path: 'api/v2/$diaryUrl',
7078
);
79+
final Uri ingredientUri = Uri(
80+
scheme: 'http',
81+
host: 'localhost',
82+
path: 'api/v2/$ingredientInfoUrl',
83+
);
7184
when(mockWgerBaseProvider.makeUrl(planInfoUrl, id: anyNamed('id'))).thenReturn(planInfoUri);
7285
when(mockWgerBaseProvider.makeUrl(planUrl, id: anyNamed('id'))).thenReturn(planUri);
7386
when(mockWgerBaseProvider.makeUrl(diaryUrl, query: anyNamed('query'))).thenReturn(diaryUri);
87+
when(mockWgerBaseProvider.makeUrl(ingredientInfoUrl, id: anyNamed('id')))
88+
.thenReturn(ingredientUri);
7489
when(mockWgerBaseProvider.fetch(planInfoUri)).thenAnswer(
7590
(realInvocation) => Future.value(nutritionalPlanInfoResponse),
7691
);
@@ -80,6 +95,9 @@ void main() {
8095
when(mockWgerBaseProvider.fetchPaginated(diaryUri)).thenAnswer(
8196
(realInvocation) => Future.value(nutritionDiaryResponse),
8297
);
98+
when(mockWgerBaseProvider.fetch(ingredientUri)).thenAnswer(
99+
(realInvocation) => Future.value(ingredient10065Response),
100+
);
83101
});
84102

85103
group('fetchAndSetPlanFull', () {
@@ -91,4 +109,48 @@ void main() {
91109
expect(nutritionProvider.items.isEmpty, false);
92110
});
93111
});
112+
113+
group('Ingredient cache DB', () {
114+
test('that if there is already valid data in the DB, the API is not hit', () async {
115+
// Arrange
116+
nutritionProvider.ingredients = [];
117+
await database.into(database.ingredients).insert(
118+
IngredientsCompanion.insert(
119+
id: ingredient59887Response['id'],
120+
data: json.encode(ingredient59887Response),
121+
lastFetched: DateTime.now(),
122+
),
123+
);
124+
125+
// Act
126+
await nutritionProvider.fetchIngredient(59887, database: database);
127+
128+
// Assert
129+
expect(nutritionProvider.ingredients.length, 1);
130+
expect(nutritionProvider.ingredients.first.id, 59887);
131+
expect(nutritionProvider.ingredients.first.name, 'Baked Beans');
132+
verifyNever(mockWgerBaseProvider.fetchPaginated(any));
133+
});
134+
135+
test('fetching an ingredient not present in the DB, the API is hit', () async {
136+
// Arrange
137+
nutritionProvider.ingredients = [];
138+
await database.into(database.ingredients).insert(
139+
IngredientsCompanion.insert(
140+
id: ingredient59887Response['id'],
141+
data: json.encode(ingredient59887Response),
142+
lastFetched: DateTime.now(),
143+
),
144+
);
145+
146+
// Act
147+
await nutritionProvider.fetchIngredient(10065, database: database);
148+
149+
// Assert
150+
expect(nutritionProvider.ingredients.length, 1);
151+
expect(nutritionProvider.ingredients.first.id, 10065);
152+
expect(nutritionProvider.ingredients.first.name, "'Old Times' Orange Fine Cut Marmalade");
153+
verify(mockWgerBaseProvider.fetch(any));
154+
});
155+
});
94156
}

test/nutrition/nutritional_meal_form_test.mocks.dart

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,26 @@ class MockNutritionPlansProvider extends _i1.Mock
129129
);
130130

131131
@override
132-
List<_i4.NutritionalPlan> get items => (super.noSuchMethod(
133-
Invocation.getter(#items),
134-
returnValue: <_i4.NutritionalPlan>[],
135-
) as List<_i4.NutritionalPlan>);
132+
List<_i7.Ingredient> get ingredients => (super.noSuchMethod(
133+
Invocation.getter(#ingredients),
134+
returnValue: <_i7.Ingredient>[],
135+
) as List<_i7.Ingredient>);
136136

137137
@override
138-
set ingredients(dynamic items) => super.noSuchMethod(
138+
set ingredients(List<_i7.Ingredient>? _ingredients) => super.noSuchMethod(
139139
Invocation.setter(
140140
#ingredients,
141-
items,
141+
_ingredients,
142142
),
143143
returnValueForMissingStub: null,
144144
);
145145

146+
@override
147+
List<_i4.NutritionalPlan> get items => (super.noSuchMethod(
148+
Invocation.getter(#items),
149+
returnValue: <_i4.NutritionalPlan>[],
150+
) as List<_i4.NutritionalPlan>);
151+
146152
@override
147153
bool get hasListeners => (super.noSuchMethod(
148154
Invocation.getter(#hasListeners),
@@ -367,17 +373,22 @@ class MockNutritionPlansProvider extends _i1.Mock
367373
) as _i9.Future<void>);
368374

369375
@override
370-
_i9.Future<_i7.Ingredient> fetchIngredient(int? ingredientId) =>
376+
_i9.Future<_i7.Ingredient> fetchIngredient(
377+
int? ingredientId, {
378+
_i3.IngredientDatabase? database,
379+
}) =>
371380
(super.noSuchMethod(
372381
Invocation.method(
373382
#fetchIngredient,
374383
[ingredientId],
384+
{#database: database},
375385
),
376386
returnValue: _i9.Future<_i7.Ingredient>.value(_FakeIngredient_5(
377387
this,
378388
Invocation.method(
379389
#fetchIngredient,
380390
[ingredientId],
391+
{#database: database},
381392
),
382393
)),
383394
) as _i9.Future<_i7.Ingredient>);

test/nutrition/nutritional_plan_form_test.mocks.dart

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,26 @@ class MockNutritionPlansProvider extends _i1.Mock
129129
);
130130

131131
@override
132-
List<_i4.NutritionalPlan> get items => (super.noSuchMethod(
133-
Invocation.getter(#items),
134-
returnValue: <_i4.NutritionalPlan>[],
135-
) as List<_i4.NutritionalPlan>);
132+
List<_i7.Ingredient> get ingredients => (super.noSuchMethod(
133+
Invocation.getter(#ingredients),
134+
returnValue: <_i7.Ingredient>[],
135+
) as List<_i7.Ingredient>);
136136

137137
@override
138-
set ingredients(dynamic items) => super.noSuchMethod(
138+
set ingredients(List<_i7.Ingredient>? _ingredients) => super.noSuchMethod(
139139
Invocation.setter(
140140
#ingredients,
141-
items,
141+
_ingredients,
142142
),
143143
returnValueForMissingStub: null,
144144
);
145145

146+
@override
147+
List<_i4.NutritionalPlan> get items => (super.noSuchMethod(
148+
Invocation.getter(#items),
149+
returnValue: <_i4.NutritionalPlan>[],
150+
) as List<_i4.NutritionalPlan>);
151+
146152
@override
147153
bool get hasListeners => (super.noSuchMethod(
148154
Invocation.getter(#hasListeners),
@@ -367,17 +373,22 @@ class MockNutritionPlansProvider extends _i1.Mock
367373
) as _i9.Future<void>);
368374

369375
@override
370-
_i9.Future<_i7.Ingredient> fetchIngredient(int? ingredientId) =>
376+
_i9.Future<_i7.Ingredient> fetchIngredient(
377+
int? ingredientId, {
378+
_i3.IngredientDatabase? database,
379+
}) =>
371380
(super.noSuchMethod(
372381
Invocation.method(
373382
#fetchIngredient,
374383
[ingredientId],
384+
{#database: database},
375385
),
376386
returnValue: _i9.Future<_i7.Ingredient>.value(_FakeIngredient_5(
377387
this,
378388
Invocation.method(
379389
#fetchIngredient,
380390
[ingredientId],
391+
{#database: database},
381392
),
382393
)),
383394
) as _i9.Future<_i7.Ingredient>);

test/workout/gym_mode_screen_test.mocks.dart

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -629,16 +629,6 @@ class MockExercisesProvider extends _i1.Mock implements _i12.ExercisesProvider {
629629
)),
630630
) as _i11.Future<_i6.Exercise>);
631631

632-
@override
633-
_i11.Future<void> checkExerciseCacheVersion() => (super.noSuchMethod(
634-
Invocation.method(
635-
#checkExerciseCacheVersion,
636-
[],
637-
),
638-
returnValue: _i11.Future<void>.value(),
639-
returnValueForMissingStub: _i11.Future<void>.value(),
640-
) as _i11.Future<void>);
641-
642632
@override
643633
_i11.Future<void> initCacheTimesLocalPrefs({dynamic forceInit = false}) =>
644634
(super.noSuchMethod(

test/workout/workout_set_form_test.mocks.dart

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -557,16 +557,6 @@ class MockExercisesProvider extends _i1.Mock implements _i19.ExercisesProvider {
557557
)),
558558
) as _i20.Future<_i4.Exercise>);
559559

560-
@override
561-
_i20.Future<void> checkExerciseCacheVersion() => (super.noSuchMethod(
562-
Invocation.method(
563-
#checkExerciseCacheVersion,
564-
[],
565-
),
566-
returnValue: _i20.Future<void>.value(),
567-
returnValueForMissingStub: _i20.Future<void>.value(),
568-
) as _i20.Future<void>);
569-
570560
@override
571561
_i20.Future<void> initCacheTimesLocalPrefs({dynamic forceInit = false}) =>
572562
(super.noSuchMethod(

0 commit comments

Comments
 (0)