Skip to content

Commit 6cc9631

Browse files
committed
Simplify currentPlan
1 parent 0fd2af0 commit 6cc9631

File tree

5 files changed

+117
-23
lines changed

5 files changed

+117
-23
lines changed

lib/models/nutrition/nutritional_plan.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class NutritionalPlan {
7474
NutritionalPlan({
7575
this.id,
7676
required this.description,
77-
required this.creationDate,
77+
DateTime? creationDate,
7878
required this.startDate,
7979
this.endDate,
8080
this.onlyLogging = false,
@@ -85,7 +85,7 @@ class NutritionalPlan {
8585
this.goalFiber,
8686
List<Meal>? meals,
8787
List<Log>? diaryEntries,
88-
}) {
88+
}) : creationDate = creationDate ?? DateTime.now() {
8989
this.meals = meals ?? [];
9090
this.diaryEntries = diaryEntries ?? [];
9191
}

lib/models/nutrition/nutritional_plan.g.dart

Lines changed: 2 additions & 1 deletion
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 & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import 'dart:convert';
2020

21+
import 'package:collection/collection.dart';
2122
import 'package:flutter/material.dart';
2223
import 'package:logging/logging.dart';
2324
import 'package:wger/core/locator.dart';
@@ -72,25 +73,13 @@ class NutritionPlansProvider with ChangeNotifier {
7273
/// - Its end date is after now or not set
7374
/// If multiple plans match these criteria, the one with the most recent creation date is returned.
7475
NutritionalPlan? get currentPlan {
75-
if (_plans.isEmpty) {
76-
return null;
77-
}
78-
7976
final now = DateTime.now();
80-
final activePlans = _plans.where((plan) {
81-
final isAfterStart = plan.startDate.isBefore(now);
82-
final isBeforeEnd = plan.endDate == null || plan.endDate!.isAfter(now);
83-
return isAfterStart && isBeforeEnd;
84-
}).toList();
85-
86-
if (activePlans.isEmpty) {
87-
return null;
88-
}
89-
90-
// Sort by creation date (newest first) and return the first one
91-
// TODO: this should already be done on _plans. this whole function can be a firstWhere() ?
92-
activePlans.sort((a, b) => b.creationDate.compareTo(a.creationDate));
93-
return activePlans.first;
77+
return _plans
78+
.where((plan) =>
79+
plan.startDate.isBefore(now) && (plan.endDate == null || plan.endDate!.isAfter(now)))
80+
.toList()
81+
.sorted((a, b) => b.creationDate.compareTo(a.creationDate))
82+
.firstOrNull;
9483
}
9584

9685
NutritionalPlan findById(int id) {

pubspec.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,10 +744,10 @@ packages:
744744
dependency: transitive
745745
description:
746746
name: leak_tracker
747-
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
747+
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
748748
url: "https://pub.dev"
749749
source: hosted
750-
version: "11.0.1"
750+
version: "11.0.2"
751751
leak_tracker_flutter_testing:
752752
dependency: transitive
753753
description:

test/nutrition/nutrition_provider_test.dart

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import 'package:flutter_test/flutter_test.dart';
55
import 'package:mockito/mockito.dart';
66
import 'package:wger/database/ingredients/ingredients_database.dart';
77
import 'package:wger/models/nutrition/ingredient.dart';
8+
import 'package:wger/models/nutrition/nutritional_plan.dart';
89
import 'package:wger/providers/nutrition.dart';
910

1011
import '../fixtures/fixture_reader.dart';
1112
import '../measurements/measurement_provider_test.mocks.dart';
1213

1314
void main() {
15+
final now = DateTime.now();
1416
late NutritionPlansProvider nutritionProvider;
1517
late MockWgerBaseProvider mockWgerBaseProvider;
1618
late IngredientDatabase database;
@@ -110,6 +112,108 @@ void main() {
110112
});
111113
});
112114

115+
group('currentPlan', () {
116+
test('gibt den aktiven Plan zurück, wenn nur einer aktiv ist', () {
117+
final plan = NutritionalPlan(
118+
id: 1,
119+
description: 'Aktiver Plan',
120+
startDate: now.subtract(const Duration(days: 1)),
121+
endDate: now.add(const Duration(days: 1)),
122+
creationDate: now.subtract(const Duration(days: 2)),
123+
);
124+
nutritionProvider = NutritionPlansProvider(mockWgerBaseProvider, [plan], database: database);
125+
expect(nutritionProvider.currentPlan, equals(plan));
126+
});
127+
128+
test('gibt den neuesten aktiven Plan zurück, wenn mehrere aktiv sind', () {
129+
final olderPlan = NutritionalPlan(
130+
id: 1,
131+
description: 'Älterer aktiver Plan',
132+
startDate: now.subtract(const Duration(days: 10)),
133+
endDate: now.add(const Duration(days: 10)),
134+
creationDate: now.subtract(const Duration(days: 10)),
135+
);
136+
final newerPlan = NutritionalPlan(
137+
id: 2,
138+
description: 'Neuerer aktiver Plan',
139+
startDate: now.subtract(const Duration(days: 5)),
140+
endDate: now.add(const Duration(days: 5)),
141+
creationDate: now.subtract(const Duration(days: 2)),
142+
);
143+
nutritionProvider =
144+
NutritionPlansProvider(mockWgerBaseProvider, [olderPlan, newerPlan], database: database);
145+
expect(nutritionProvider.currentPlan, equals(newerPlan));
146+
});
147+
});
148+
149+
group('currentPlan correctly returns the active plan', () {
150+
test('no plans available -> null', () {
151+
nutritionProvider = NutritionPlansProvider(mockWgerBaseProvider, [], database: database);
152+
expect(nutritionProvider.currentPlan, isNull);
153+
});
154+
155+
test('no active plan -> null', () {
156+
final plans = [
157+
NutritionalPlan(
158+
id: 1,
159+
description: 'plan 1',
160+
startDate: now.subtract(const Duration(days: 30)),
161+
endDate: now.subtract(const Duration(days: 5)),
162+
),
163+
NutritionalPlan(
164+
id: 2,
165+
description: 'plan 2',
166+
startDate: now.add(const Duration(days: 100)),
167+
endDate: now.add(const Duration(days: 50)),
168+
),
169+
];
170+
nutritionProvider = NutritionPlansProvider(mockWgerBaseProvider, plans, database: database);
171+
expect(nutritionProvider.currentPlan, isNull);
172+
});
173+
174+
test('active plan exists -> return it', () {
175+
final plan = NutritionalPlan(
176+
description: 'Active plan',
177+
startDate: now.subtract(const Duration(days: 10)),
178+
endDate: now.add(const Duration(days: 10)),
179+
);
180+
nutritionProvider = NutritionPlansProvider(mockWgerBaseProvider, [plan], database: database);
181+
expect(nutritionProvider.currentPlan, equals(plan));
182+
});
183+
184+
test('inactive plans are ignored', () {
185+
final inactivePlan = NutritionalPlan(
186+
description: 'Inactive plan',
187+
startDate: now.subtract(const Duration(days: 10)),
188+
endDate: now.add(const Duration(days: 5)),
189+
);
190+
final plan = NutritionalPlan(
191+
description: 'Active plan',
192+
startDate: now.subtract(const Duration(days: 10)),
193+
endDate: now.add(const Duration(days: 10)),
194+
);
195+
nutritionProvider =
196+
NutritionPlansProvider(mockWgerBaseProvider, [plan, inactivePlan], database: database);
197+
expect(nutritionProvider.currentPlan, equals(plan));
198+
});
199+
200+
test('several active plans exists -> return newest', () {
201+
final olderPlan = NutritionalPlan(
202+
description: 'Old active plan',
203+
startDate: now.subtract(const Duration(days: 10)),
204+
endDate: now.add(const Duration(days: 10)),
205+
);
206+
final newerPlan = NutritionalPlan(
207+
description: 'Newer active plan',
208+
startDate: now.subtract(const Duration(days: 5)),
209+
endDate: now.add(const Duration(days: 5)),
210+
);
211+
nutritionProvider =
212+
NutritionPlansProvider(mockWgerBaseProvider, [olderPlan, newerPlan], database: database);
213+
expect(nutritionProvider.currentPlan, equals(newerPlan));
214+
});
215+
});
216+
113217
group('Ingredient cache DB', () {
114218
test('that if there is already valid data in the DB, the API is not hit', () async {
115219
// Arrange

0 commit comments

Comments
 (0)