Initial commit: CookIT recipe collection and week planner
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
7d7a0bc60b
173 files changed
+22803
No files matched your search
@@ -0,0 +1,183 @@
|
||||
import 'package:cookit/src/recipes/views/widgets/recipe_card.dart';
|
||||
import 'package:cookit/src/recipes/views/widgets/recipe_photo.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../support/fixtures.dart';
|
||||
import '../support/test_app.dart';
|
||||
|
||||
Finder inSheet(Finder finder) => find.descendant(of: find.byType(BottomSheet), matching: finder);
|
||||
|
||||
void main() {
|
||||
testWidgets('"Hilf mir entscheiden" narrows down by Course and time', (tester) async {
|
||||
final app = await TestApp.create(tester);
|
||||
final courses = (await tester.runAsync(app.courses.allCourses))!;
|
||||
final dessert = courses.firstWhere((c) => c.name == 'Dessert');
|
||||
final main = courses.firstWhere((c) => c.name == 'Hauptgericht');
|
||||
await tester.runAsync(() async {
|
||||
await app.recipes.saveRecipe(
|
||||
recipe(
|
||||
id: 'a',
|
||||
name: 'Kaiserschmarrn',
|
||||
courseId: dessert.id,
|
||||
).copyWith(prepMinutes: () => 10, cookMinutes: () => 10),
|
||||
);
|
||||
await app.recipes.saveRecipe(recipe(id: 'b', name: 'Tiramisu', courseId: dessert.id)); // 50 min
|
||||
await app.recipes.saveRecipe(recipe(id: 'c', name: 'Rinderrouladen', courseId: main.id));
|
||||
});
|
||||
await tester.pumpWidget(app.build());
|
||||
await app.settle(tester);
|
||||
|
||||
await tester.tap(find.byTooltip('Hilf mir entscheiden'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Worauf hast du Lust?'), findsOneWidget);
|
||||
await tester.tap(inSheet(find.text('Dessert')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Weiter'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Wie viel Zeit hast du?'), findsOneWidget);
|
||||
await tester.tap(find.text('bis 30 Min.'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Vorschlag zeigen'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('1 Rezept passt'), findsOneWidget);
|
||||
expect(inSheet(find.text('Kaiserschmarrn')), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Rezept öffnen'));
|
||||
await app.settle(tester);
|
||||
expect(find.text('Kochmodus starten'), findsOneWidget);
|
||||
expect(find.text('Kaiserschmarrn'), findsOneWidget);
|
||||
|
||||
await app.dispose(tester);
|
||||
});
|
||||
|
||||
testWidgets('the decision helper offers a looser choice when nothing fits', (tester) async {
|
||||
final app = await TestApp.create(tester);
|
||||
await tester.runAsync(() => app.recipes.saveRecipe(recipe())); // 50 min, no Course
|
||||
await tester.pumpWidget(app.build());
|
||||
await app.settle(tester);
|
||||
|
||||
await tester.tap(find.byTooltip('Hilf mir entscheiden'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Weiter'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('bis 30 Min.'));
|
||||
await tester.tap(find.text('Vorschlag zeigen'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Dazu passt leider nichts.'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Ohne Zeitlimit: 1'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('1 Rezept passt'), findsOneWidget);
|
||||
|
||||
await app.dispose(tester);
|
||||
});
|
||||
|
||||
testWidgets('Darstellung switches between light and dark', (tester) async {
|
||||
final app = await TestApp.create(tester);
|
||||
await tester.pumpWidget(app.build());
|
||||
await app.settle(tester);
|
||||
ThemeMode mode() => tester.widget<MaterialApp>(find.byType(MaterialApp)).themeMode!;
|
||||
expect(mode(), ThemeMode.light);
|
||||
|
||||
await tester.tap(find.byTooltip('Einstellungen'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Dunkel'));
|
||||
await app.settle(tester);
|
||||
expect(mode(), ThemeMode.dark);
|
||||
|
||||
await app.dispose(tester);
|
||||
});
|
||||
|
||||
testWidgets('an own unit added in the settings is offered in the unit picker', (tester) async {
|
||||
final app = await TestApp.create(tester);
|
||||
await tester.pumpWidget(app.build());
|
||||
await app.settle(tester);
|
||||
|
||||
await tester.tap(find.byTooltip('Einstellungen'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Maßeinheiten bearbeiten'));
|
||||
await app.settle(tester);
|
||||
await tester.tap(find.text('Einheit hinzufügen'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.enterText(find.byType(TextFormField), 'Würfel');
|
||||
await tester.tap(find.text('Speichern'));
|
||||
await app.settle(tester);
|
||||
expect(find.text('Würfel'), findsOneWidget);
|
||||
expect(find.text('Eigene Einheit'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byTooltip('Zurück'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byTooltip('Zurück'));
|
||||
await app.settle(tester);
|
||||
await tester.tap(find.byTooltip('Neues Rezept'));
|
||||
await app.settle(tester);
|
||||
await tester.tap(find.text('–'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.widgetWithText(ChoiceChip, 'Würfel'), findsOneWidget);
|
||||
|
||||
await app.dispose(tester);
|
||||
});
|
||||
|
||||
testWidgets('tapping a photo can make it the main Photo', (tester) async {
|
||||
final app = await TestApp.create(tester);
|
||||
final (first, second) = (await tester.runAsync(() async {
|
||||
final a = await app.photos.saveBytes(Uint8List.fromList([1]));
|
||||
final b = await app.photos.saveBytes(Uint8List.fromList([2]));
|
||||
await app.recipes.saveRecipe(recipe(photos: [a, b]));
|
||||
return (a, b);
|
||||
}))!;
|
||||
await tester.pumpWidget(app.build());
|
||||
await app.settle(tester);
|
||||
await tester.tap(find.descendant(of: find.byType(RecipeCard), matching: find.text('Focaccia')));
|
||||
await app.settle(tester);
|
||||
await tester.tap(find.byTooltip('Bearbeiten'));
|
||||
await app.settle(tester);
|
||||
|
||||
expect(find.textContaining('das erste Foto ist das Hauptfoto'), findsOneWidget);
|
||||
// The photo is covered by its own tap layer, which is what receives the tap.
|
||||
await tester.tap(find.byType(RecipePhoto).at(1), warnIfMissed: false);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Als Hauptfoto festlegen'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Speichern'));
|
||||
await app.settle(tester);
|
||||
|
||||
expect((await tester.runAsync(() => app.recipes.getRecipe('r1')))!.photos, [second, first]);
|
||||
|
||||
await app.dispose(tester);
|
||||
});
|
||||
|
||||
testWidgets('"Zutaten teilen" shares the ingredients for the chosen servings', (tester) async {
|
||||
final shared = <Map<Object?, Object?>>[];
|
||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(
|
||||
const MethodChannel('dev.fluttercommunity.plus/share'),
|
||||
(call) async {
|
||||
shared.add(call.arguments as Map<Object?, Object?>);
|
||||
return 'dev.fluttercommunity.plus/share/unavailable';
|
||||
},
|
||||
);
|
||||
final app = await TestApp.create(tester);
|
||||
await tester.runAsync(() => app.recipes.saveRecipe(recipe()));
|
||||
await tester.pumpWidget(app.build());
|
||||
await app.settle(tester);
|
||||
await tester.tap(find.descendant(of: find.byType(RecipeCard), matching: find.text('Focaccia')));
|
||||
await app.settle(tester);
|
||||
|
||||
await tester.scrollUntilVisible(find.text('Zutaten teilen'), 200, scrollable: find.byType(Scrollable).first);
|
||||
await tester.tap(find.text('Zutaten teilen'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(inSheet(find.byTooltip('Mehr Portionen')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Teilen'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(shared, hasLength(1));
|
||||
expect(shared.single['text'], '375 g Mehl\n2½–3¾ EL Olivenöl (gutes)\n\nRosmarin');
|
||||
expect(shared.single['subject'], 'Focaccia – Zutaten für 5 Portionen');
|
||||
|
||||
await app.dispose(tester);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user