import 'dart:typed_data'; import 'package:cookit/src/bundle/bundle_service.dart'; import 'package:cookit/src/database/database.dart'; import 'package:cookit/src/recipes/course_repository.dart'; import 'package:cookit/src/recipes/models/recipe.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:cookit/src/sharing/recipe_share_service.dart'; import 'package:flutter_test/flutter_test.dart'; import '../support/fixtures.dart'; import '../support/test_database.dart'; /// One cook's collection. class Phone { Phone._(this.db, this.photos) : recipes = RecipeRepository(db, photos), courses = CourseRepository(db), units = UnitRepository(db) { bundles = BundleService(recipes, courses, units, photos); shares = RecipeShareService(recipes, courses, units, photos, bundles); } static Future 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; late final BundleService bundles; late final RecipeShareService shares; } void main() { test('a Recipe Code arrives as a new Recipe with its Course and own unit', () async { final mine = await Phone.create(); final theirs = await Phone.create(); final course = await mine.courses.addCourse('Brotzeit'); final cube = await mine.units.addOwn('Würfel'); final sent = recipe(courseId: course.id, favourite: true).copyWith( ingredientGroups: [ IngredientGroup( lines: [IngredientLine(amount: 1, unitKey: cube.key, name: 'Hefe')], ), ], ); await mine.recipes.saveRecipe(sent); final saved = await theirs.shares.save(theirs.shares.readCode(await mine.shares.recipeCode(sent))); expect(saved.id, isNot(sent.id)); expect(saved.favourite, isFalse); expect((await theirs.courses.allCourses()).firstWhere((c) => c.id == saved.courseId).name, 'Brotzeit'); expect((await theirs.units.allUnits()).firstWhere((u) => u.key == cube.key).label, 'Würfel'); expect((await theirs.recipes.allRecipes()).single.ingredientLines.single.unitKey, cube.key); }); test('a shared file carries the Photos, and saving twice gives two Recipes', () async { final mine = await Phone.create(); final theirs = await Phone.create(); final photo = await mine.photos.saveBytes(Uint8List.fromList([1, 2, 3])); final sent = recipe(photos: [photo], reviewReasons: ['Prüfen']); await mine.recipes.saveRecipe(sent); final file = await mine.shares.recipeFile(sent, includeNotes: false); final shared = (await theirs.shares.readFile(file))!; expect(shared.photos.single, [1, 2, 3]); expect(shared.recipe.notes, isNull); expect(shared.recipe.reviewReasons, isEmpty); expect(await theirs.shares.hasRecipeNamed('focaccia'), isFalse); await theirs.shares.save(shared); expect(await theirs.shares.hasRecipeNamed('focaccia'), isTrue); await theirs.shares.save(shared); final all = await theirs.recipes.allRecipes(); expect(all, hasLength(2)); expect(all.map((r) => r.id).toSet(), hasLength(2)); expect(all.first.photos, hasLength(1)); }); test('a file with a whole collection is not a single shared Recipe', () async { final mine = await Phone.create(); await mine.recipes.saveRecipe(recipe()); await mine.recipes.saveRecipe(recipe(id: 'r2', name: 'Pizza')); expect(await mine.shares.readFile(await mine.bundles.exportBundle()), isNull); }); }