233 lines
9.3 KiB
Dart
233 lines
9.3 KiB
Dart
import 'package:cookit/src/recipes/models/recipe.dart';
|
||
import 'package:cookit/src/recipes/views/widgets/recipe_card.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
|
||
import '../support/fixtures.dart';
|
||
import '../support/test_app.dart';
|
||
|
||
/// A Recipe name as shown on a grid card (the suggestion card may show it too).
|
||
Finder inGrid(String text) => find.descendant(of: find.byType(RecipeCard), matching: find.text(text));
|
||
|
||
void main() {
|
||
testWidgets('home grid shows Recipes and filters them by search, Course and review', (tester) async {
|
||
final app = await TestApp.create(tester);
|
||
final dessert = (await tester.runAsync(() => app.courses.findOrCreate('Dessert')))!;
|
||
await tester.runAsync(() async {
|
||
await app.recipes.saveRecipe(recipe(id: 'a', name: 'Käsespätzle', tags: ['schwäbisch']));
|
||
await app.recipes.saveRecipe(
|
||
recipe(id: 'b', name: 'Tiramisu', courseId: dessert.id, reviewReasons: ['Portionen fehlen.']),
|
||
);
|
||
});
|
||
|
||
await tester.pumpWidget(app.build());
|
||
await app.settle(tester);
|
||
expect(inGrid('Käsespätzle'), findsOneWidget);
|
||
expect(inGrid('Tiramisu'), findsOneWidget);
|
||
expect(find.text('IDEE FÜR HEUTE'), findsOneWidget);
|
||
|
||
await tester.enterText(find.byType(TextField), 'kase');
|
||
await tester.pumpAndSettle();
|
||
expect(inGrid('Käsespätzle'), findsOneWidget);
|
||
expect(inGrid('Tiramisu'), findsNothing);
|
||
|
||
await tester.enterText(find.byType(TextField), '');
|
||
await tester.tap(find.text('1 Rezept wartet auf deinen Blick'));
|
||
await tester.pumpAndSettle();
|
||
expect(inGrid('Käsespätzle'), findsNothing);
|
||
expect(inGrid('Tiramisu'), findsOneWidget);
|
||
|
||
await tester.tap(find.text('Nur Rezepte zum Prüfen – alle zeigen'));
|
||
await tester.pumpAndSettle();
|
||
final chips = find.byWidgetPredicate((w) => w is ListView && w.scrollDirection == Axis.horizontal);
|
||
final dessertChip = find.descendant(of: chips, matching: find.text('Dessert'));
|
||
await tester.scrollUntilVisible(
|
||
dessertChip,
|
||
200,
|
||
scrollable: find.descendant(of: chips, matching: find.byType(Scrollable)),
|
||
);
|
||
await tester.tap(dessertChip);
|
||
await tester.pumpAndSettle();
|
||
expect(inGrid('Tiramisu'), findsOneWidget);
|
||
expect(inGrid('Käsespätzle'), findsNothing);
|
||
|
||
await app.dispose(tester);
|
||
});
|
||
|
||
testWidgets('Cooking Mode walks through the ingredients and every step', (tester) async {
|
||
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(inGrid('Focaccia'));
|
||
await app.settle(tester);
|
||
|
||
await tester.tap(find.text('Kochmodus starten'));
|
||
await app.settle(tester);
|
||
expect(find.text('Bereit zum Kochen?'), findsOneWidget);
|
||
expect(find.text('300 g'), findsOneWidget);
|
||
|
||
await tester.tap(find.byTooltip('Mehr Portionen'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('5'), findsOneWidget);
|
||
expect(find.text('375 g'), findsOneWidget);
|
||
|
||
await tester.tap(find.text('Los geht’s'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('Schritt 1 von 2'), findsOneWidget);
|
||
expect(find.text('Kneten.'), findsOneWidget);
|
||
expect(find.text('Teig'), findsOneWidget);
|
||
|
||
await tester.tap(find.text('Weiter'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('Gehen lassen.'), findsOneWidget);
|
||
|
||
await tester.tap(find.text('Fertig'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('Guten Appetit!'), findsOneWidget);
|
||
|
||
await tester.tap(find.text('Zurück zum Rezept'));
|
||
await app.settle(tester);
|
||
expect(find.text('Kochmodus starten'), findsOneWidget);
|
||
|
||
await app.dispose(tester);
|
||
});
|
||
|
||
testWidgets('the heart on a card toggles the favourite', (tester) async {
|
||
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.byTooltip('Favorit')));
|
||
await app.settle(tester);
|
||
expect((await tester.runAsync(app.recipes.allRecipes))!.single.favourite, isTrue);
|
||
|
||
await app.dispose(tester);
|
||
});
|
||
|
||
testWidgets('empty collection explains how to start', (tester) async {
|
||
final app = await TestApp.create(tester);
|
||
await tester.pumpWidget(app.build());
|
||
await app.settle(tester);
|
||
expect(find.text('Noch keine Rezepte'), findsOneWidget);
|
||
await app.dispose(tester);
|
||
});
|
||
|
||
testWidgets('detail shows the Recipe, and "Erledigt" clears its Review Flag', (tester) async {
|
||
final app = await TestApp.create(tester);
|
||
await tester.runAsync(() => app.recipes.saveRecipe(recipe(reviewReasons: ['Portionen fehlen.'])));
|
||
await tester.pumpWidget(app.build());
|
||
await app.settle(tester);
|
||
|
||
await tester.tap(inGrid('Focaccia'));
|
||
await app.settle(tester);
|
||
expect(find.text('Bitte prüfen'), findsOneWidget);
|
||
expect(find.text('• Portionen fehlen.'), findsOneWidget);
|
||
expect(find.text('300 g'), findsOneWidget);
|
||
expect(find.text('2–3 EL'), findsOneWidget);
|
||
expect(find.text('Topping'), findsOneWidget);
|
||
expect(find.text('775 kcal'), findsOneWidget);
|
||
expect(find.text('pro Portion'), findsOneWidget);
|
||
expect(find.text('50 Min.'), findsOneWidget);
|
||
|
||
expect(find.text('22x22 cm Form'), findsOneWidget, reason: 'Notes show under the Zutaten tab too');
|
||
await tester.tap(find.text('Zubereitung · 2'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('Teig'), findsOneWidget);
|
||
expect(find.text('Kneten.'), findsOneWidget);
|
||
expect(find.text('22x22 cm Form'), findsOneWidget);
|
||
|
||
await tester.tap(find.text('Erledigt'));
|
||
await app.settle(tester);
|
||
expect(find.text('Bitte prüfen'), findsNothing);
|
||
|
||
await app.dispose(tester);
|
||
});
|
||
|
||
testWidgets('a new Recipe can be created with ingredients and steps', (tester) async {
|
||
final app = await TestApp.create(tester);
|
||
await tester.pumpWidget(app.build());
|
||
await app.settle(tester);
|
||
|
||
await tester.tap(find.byTooltip('Neues Rezept'));
|
||
await app.settle(tester);
|
||
|
||
await tester.tap(find.text('Speichern'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('Bitte gib dem Rezept einen Namen.'), findsOneWidget);
|
||
|
||
await tester.enterText(find.widgetWithText(TextFormField, 'Name'), 'Pfannkuchen');
|
||
await tester.enterText(find.widgetWithText(TextFormField, 'Portionen'), '2');
|
||
final ingredientName = find.widgetWithText(TextFormField, 'Zutat');
|
||
await tester.enterText(find.widgetWithText(TextFormField, 'Menge'), '1,5');
|
||
await tester.enterText(ingredientName, 'Mehl');
|
||
await tester.tap(find.text('–'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('Bund'), findsNothing);
|
||
await tester.tap(find.text('Weitere Einheiten …'));
|
||
await tester.pumpAndSettle();
|
||
await tester.tap(find.widgetWithText(ChoiceChip, 'Bund'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('Bund'), findsOneWidget);
|
||
await tester.enterText(find.widgetWithText(TextFormField, 'Schritt 1'), 'Alles verrühren.');
|
||
|
||
await tester.tap(find.text('Speichern'));
|
||
await app.settle(tester);
|
||
|
||
expect(inGrid('Pfannkuchen'), findsOneWidget);
|
||
final saved = (await tester.runAsync(app.recipes.allRecipes))!.single;
|
||
expect(saved.servings, 2);
|
||
expect(saved.ingredientGroups.single.lines.single.amount, 1.5);
|
||
expect(saved.ingredientGroups.single.lines.single.name, 'Mehl');
|
||
expect(saved.ingredientGroups.single.lines.single.unitKey, 'bunch');
|
||
expect(saved.stepSections.single.steps, ['Alles verrühren.']);
|
||
expect(saved.calories, isNull);
|
||
expect(saved.needsReview, isFalse);
|
||
|
||
await app.dispose(tester);
|
||
});
|
||
|
||
testWidgets('an invalid amount blocks saving', (tester) async {
|
||
final app = await TestApp.create(tester);
|
||
await tester.pumpWidget(app.build());
|
||
await app.settle(tester);
|
||
await tester.tap(find.byTooltip('Neues Rezept'));
|
||
await app.settle(tester);
|
||
|
||
await tester.enterText(find.widgetWithText(TextFormField, 'Name'), 'Test');
|
||
await tester.enterText(find.widgetWithText(TextFormField, 'Menge'), 'viel');
|
||
await tester.tap(find.text('Speichern'));
|
||
await app.settle(tester);
|
||
expect(find.text('z. B. 2, 1,5, ½ oder 2-3'), findsOneWidget);
|
||
expect(await tester.runAsync(app.recipes.allRecipes), isEmpty);
|
||
|
||
await app.dispose(tester);
|
||
});
|
||
|
||
testWidgets('editing keeps favourite and Review Flag', (tester) async {
|
||
final app = await TestApp.create(tester);
|
||
await tester.runAsync(() => app.recipes.saveRecipe(recipe(favourite: true, reviewReasons: ['x'])));
|
||
await tester.pumpWidget(app.build());
|
||
await app.settle(tester);
|
||
await tester.tap(inGrid('Focaccia'));
|
||
await app.settle(tester);
|
||
await tester.tap(find.byTooltip('Bearbeiten'));
|
||
await app.settle(tester);
|
||
|
||
await tester.enterText(find.widgetWithText(TextFormField, 'Name'), 'Focaccia mit Rosmarin');
|
||
await tester.tap(find.text('Speichern'));
|
||
await app.settle(tester);
|
||
|
||
final saved = (await tester.runAsync(app.recipes.allRecipes))!.single;
|
||
expect(saved.name, 'Focaccia mit Rosmarin');
|
||
expect(saved.favourite, isTrue);
|
||
expect(saved.reviewReasons, ['x']);
|
||
expect(saved.calories!.basis, CaloriesBasis.perServing);
|
||
expect(saved.ingredientGroups.map((g) => g.name), [null, 'Topping']);
|
||
expect(saved.stepSections.single.title, 'Teig');
|
||
|
||
await app.dispose(tester);
|
||
});
|
||
}
|