Files
CookIT/test/planning/plan_share_service_test.dart
2026-10-28 22:55:09 +01:00

101 lines
4.3 KiB
Dart

import 'package:cookit/src/bundle/bundle_service.dart';
import 'package:cookit/src/database/database.dart';
import 'package:cookit/src/planning/day.dart';
import 'package:cookit/src/planning/plan_repository.dart';
import 'package:cookit/src/planning/plan_share_service.dart';
import 'package:cookit/src/recipes/course_repository.dart';
import 'package:cookit/src/recipes/photo_store.dart';
import 'package:cookit/src/recipes/recipe_repository.dart';
import 'package:cookit/src/recipes/unit_repository.dart';
import 'package:flutter_test/flutter_test.dart';
import '../support/fixtures.dart';
import '../support/test_database.dart';
/// One cook's collection and Week Plan.
class Phone {
Phone._(this.db, this.photos)
: recipes = RecipeRepository(db, photos),
courses = CourseRepository(db),
units = UnitRepository(db),
plan = PlanRepository(db) {
bundles = BundleService(recipes, courses, units, photos);
shares = PlanShareService(recipes, courses, units, photos, plan, bundles);
}
static Future<Phone> create() async {
final phone = Phone._(testDatabase(), await tempPhotoStore());
addTearDown(() async {
await phone.db.close();
await phone.photos.directory.delete(recursive: true);
});
return phone;
}
final AppDatabase db;
final PhotoStore photos;
final RecipeRepository recipes;
final CourseRepository courses;
final UnitRepository units;
final PlanRepository plan;
late final BundleService bundles;
late final PlanShareService shares;
Future<String> meal(String name) async => (await plan.allMeals()).firstWhere((m) => m.name == name).id;
}
void main() {
final monday = DateTime.utc(2026, 10, 19);
test('a shared week reuses known Recipes, adds new ones and its Meals, and keeps what is planned', () async {
final mine = await Phone.create();
final theirs = await Phone.create();
// Mine: three Recipes planned across the week, plus a note and a Meal they don't have.
await mine.recipes.saveRecipe(recipe(id: 'shared', name: 'Focaccia'));
await mine.recipes.saveRecipe(recipe(id: 'mine-pizza', name: 'Pizza'));
await mine.recipes.saveRecipe(recipe(id: 'new', name: 'Gulasch'));
await mine.plan.addMeal('Frühstück');
await mine.plan.addEntry(monday, await mine.meal('Abend'), recipeId: 'shared');
await mine.plan.addEntry(addDays(monday, 1), await mine.meal('Abend'), recipeId: 'mine-pizza');
await mine.plan.addEntry(addDays(monday, 2), await mine.meal('Mittag'), recipeId: 'new');
await mine.plan.addEntry(addDays(monday, 3), await mine.meal('Frühstück'), note: 'Bäcker');
await mine.plan.addEntry(addDays(monday, 8), await mine.meal('Abend'), recipeId: 'new'); // next week: not sent
// Theirs: the same Focaccia (same id), their own Pizza (same name), and a plan of their own.
await theirs.recipes.saveRecipe(recipe(id: 'shared', name: 'Focaccia'));
await theirs.recipes.saveRecipe(recipe(id: 'their-pizza', name: 'pizza '));
await theirs.plan.addEntry(monday, await theirs.meal('Mittag'), note: 'Reste');
final week = SharedWeek(await theirs.bundles.read(await mine.shares.weekFile(monday)));
final preview = await theirs.shares.preview(week);
expect((preview.entries, preview.newRecipes, preview.existingEntries), (4, 1, 1));
await theirs.shares.adopt(week);
final recipes = await theirs.recipes.allRecipes();
expect(recipes.map((r) => r.id), unorderedEquals(['shared', 'their-pizza', 'new']));
final meals = {for (final m in await theirs.plan.allMeals()) m.id: m.name};
final entries = await theirs.plan.allEntries();
expect(
[for (final e in entries) (e.day, meals[e.mealId], e.recipeId ?? e.note)],
unorderedEquals([
(monday, 'Mittag', 'Reste'),
(monday, 'Abend', 'shared'),
(addDays(monday, 1), 'Abend', 'their-pizza'),
(addDays(monday, 2), 'Mittag', 'new'),
(addDays(monday, 3), 'Frühstück', 'Bäcker'),
]),
);
});
test('only a bundle shared from the Week Plan carries a week', () async {
final mine = await Phone.create();
await mine.recipes.saveRecipe(recipe());
final contents = await mine.bundles.read(await mine.bundles.exportBundle());
expect(contents.plan, isNull);
final week = await mine.bundles.read(await mine.shares.weekFile(monday));
expect(week.plan, isNotNull);
});
}