240 lines
8.5 KiB
Dart
240 lines
8.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
|
|
import 'package:ertl_filament_verwaltung/controller/home_controller.dart';
|
|
import 'package:ertl_filament_verwaltung/helper/storage_keys.dart';
|
|
import 'package:ertl_filament_verwaltung/models/kauf_filament_model.dart';
|
|
import 'package:ertl_filament_verwaltung/pages/home_view.dart';
|
|
import 'package:ertl_filament_verwaltung/services/get_storage_services.dart';
|
|
import 'package:ertl_filament_verwaltung/theme/app_theme.dart';
|
|
import 'package:ertl_filament_verwaltung/widgets/filament_card.dart';
|
|
import 'package:ertl_filament_verwaltung/widgets/filament_form.dart';
|
|
|
|
import 'helpers/memory_storage_service.dart';
|
|
|
|
void main() {
|
|
late HomeController controller;
|
|
|
|
setUp(() {
|
|
PackageInfo.setMockInitialValues(
|
|
appName: 'Filamentverwaltung',
|
|
packageName: 'com.example.ertl_filament_verwaltung',
|
|
version: '1.2.3',
|
|
buildNumber: '42',
|
|
buildSignature: '',
|
|
);
|
|
Get.testMode = true;
|
|
Get.put<GetStorageService>(MemoryStorageService());
|
|
controller = Get.put(HomeController());
|
|
});
|
|
|
|
tearDown(() => Get.reset());
|
|
|
|
Future<void> showHome(WidgetTester tester, Size size) async {
|
|
tester.view.physicalSize = size;
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.resetPhysicalSize);
|
|
addTearDown(tester.view.resetDevicePixelRatio);
|
|
await tester.pumpWidget(
|
|
GetMaterialApp(theme: AppTheme.light, home: const HomeView()),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
}
|
|
|
|
KaufFilamentModel sample() => KaufFilamentModel(
|
|
filamentId: 'sample',
|
|
kaufdatum: DateTime(2026, 10, 27),
|
|
haendler: 'Filament Shop',
|
|
marke: 'Testmarke',
|
|
material: 'PLA+',
|
|
preis: 24.90,
|
|
farbe: 'Ozeanblau',
|
|
gewicht: '1000',
|
|
);
|
|
|
|
testWidgets('Hamburger menu displays the installed version and build', (
|
|
tester,
|
|
) async {
|
|
await showHome(tester, const Size(320, 640));
|
|
await tester.tap(find.byIcon(Icons.menu));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('Version 1.2.3'), findsOneWidget);
|
|
expect(find.text('Build 42'), findsOneWidget);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('Desktop shows both panes and edits PLA+', (tester) async {
|
|
controller.filamente.add(sample());
|
|
await showHome(tester, const Size(1280, 900));
|
|
|
|
expect(
|
|
tester.getTopLeft(find.byType(FilamentCard)).dx,
|
|
greaterThan(tester.getTopRight(find.byType(FilamentForm)).dx),
|
|
);
|
|
expect(find.text('1000 g'), findsOneWidget);
|
|
expect(find.text('Testmarke'), findsOneWidget);
|
|
|
|
await tester.tap(find.byTooltip('Filament verwalten'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('Bearbeiten'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Filament bearbeiten'), findsOneWidget);
|
|
expect(controller.markeController.text, 'Testmarke');
|
|
expect(controller.material.value, 'PLA+');
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('Small phone scrolls to save and shows the purchase', (
|
|
tester,
|
|
) async {
|
|
await showHome(tester, const Size(320, 640));
|
|
controller.haendlerController.text = 'Filament Shop';
|
|
controller.markeController.text = 'Testmarke';
|
|
controller.farbeController.text = 'Ozeanblau';
|
|
controller.preisController.text = '24,90';
|
|
controller.gewichtController.text = '1000';
|
|
|
|
await tester.scrollUntilVisible(
|
|
find.text('Filament speichern'),
|
|
200,
|
|
scrollable: find.byType(Scrollable).first,
|
|
);
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('Filament speichern'));
|
|
await tester.pumpAndSettle();
|
|
expect(controller.filamente, hasLength(1));
|
|
|
|
await tester.scrollUntilVisible(
|
|
find.byType(FilamentCard),
|
|
200,
|
|
scrollable: find.byType(Scrollable).first,
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('Testmarke'), findsOneWidget);
|
|
expect(find.text('1000 g'), findsOneWidget);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('Empty inventory is accessible on a narrow screen', (
|
|
tester,
|
|
) async {
|
|
await showHome(tester, const Size(320, 640));
|
|
await tester.scrollUntilVisible(
|
|
find.text('Hier beginnt dein Bestand'),
|
|
200,
|
|
scrollable: find.byType(Scrollable).first,
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
find.text('Hier beginnt dein Bestand').hitTestable(),
|
|
findsOneWidget,
|
|
);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('Custom material can be typed, selected and removed on a phone', (
|
|
tester,
|
|
) async {
|
|
await showHome(tester, const Size(320, 640));
|
|
final field = find.byWidgetPredicate(
|
|
(widget) =>
|
|
widget is TextFormField &&
|
|
widget.controller == controller.materialController,
|
|
);
|
|
await tester.ensureVisible(field);
|
|
await tester.enterText(field, 'PA12');
|
|
await tester.testTextInput.receiveAction(TextInputAction.done);
|
|
await tester.ensureVisible(find.text('Art hinzufügen'));
|
|
await tester.tap(find.text('Art hinzufügen'));
|
|
await tester.pumpAndSettle();
|
|
expect(controller.materialien, contains('PA12'));
|
|
|
|
await Scrollable.ensureVisible(
|
|
tester.element(find.byTooltip('Material auswählen')),
|
|
alignment: 0.5,
|
|
);
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.byTooltip('Material auswählen'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('PETG').last);
|
|
await tester.pumpAndSettle();
|
|
expect(controller.materialController.text, 'PETG');
|
|
|
|
await tester.ensureVisible(find.text('Arten verwalten'));
|
|
await tester.tap(find.text('Arten verwalten'));
|
|
await tester.pumpAndSettle();
|
|
await tester.scrollUntilVisible(
|
|
find.byTooltip('PA12 aus Liste entfernen'),
|
|
180,
|
|
scrollable: find.descendant(
|
|
of: find.byType(AlertDialog),
|
|
matching: find.byType(Scrollable),
|
|
),
|
|
);
|
|
await tester.tap(find.byTooltip('PA12 aus Liste entfernen'));
|
|
await tester.pumpAndSettle();
|
|
expect(controller.materialien, isNot(contains('PA12')));
|
|
expect(tester.takeException(), isNull);
|
|
await tester.tap(find.text('Schließen'));
|
|
await tester.pumpAndSettle();
|
|
final reloaded = Get.put(HomeController(), tag: 'materials-reload');
|
|
expect(reloaded.materialien, isNot(contains('PA12')));
|
|
});
|
|
|
|
testWidgets('Saving adds custom material and removal preserves purchases', (
|
|
tester,
|
|
) async {
|
|
await showHome(tester, const Size(1280, 900));
|
|
controller.haendlerController.text = 'Shop';
|
|
controller.markeController.text = 'Marke';
|
|
controller.farbeController.text = 'Rot';
|
|
controller.preisController.text = '20';
|
|
controller.gewichtController.text = '1000';
|
|
controller.materialController.text = ' PA12 ';
|
|
await controller.saveFilament();
|
|
expect(controller.filamente.single.material, 'PA12');
|
|
final reloaded = Get.put(HomeController(), tag: 'custom-reload');
|
|
expect(reloaded.materialien, contains('PA12'));
|
|
await controller.removeMaterial('PA12');
|
|
await controller.editFilament(controller.filamente.single);
|
|
await tester.pumpAndSettle();
|
|
expect(controller.materialController.text, 'PA12');
|
|
expect(controller.materialien, isNot(contains('PA12')));
|
|
expect(controller.filamente.single.material, 'PA12');
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
test(
|
|
'An empty material list survives reload and failed writes keep the list',
|
|
() async {
|
|
final storage = Get.find<GetStorageService>() as MemoryStorageService;
|
|
controller.materialController.text = 'pa12';
|
|
expect(await controller.addMaterial(), isTrue);
|
|
controller.materialController.text = ' PA12 ';
|
|
expect(await controller.addMaterial(), isTrue);
|
|
expect(
|
|
controller.materialien.where((item) => item.toLowerCase() == 'pa12'),
|
|
hasLength(1),
|
|
);
|
|
storage.failWrites = true;
|
|
expect(await controller.removeMaterial('pa12'), isFalse);
|
|
expect(controller.materialien, contains('pa12'));
|
|
expect(controller.materialMessage.value, isNotNull);
|
|
storage.failWrites = false;
|
|
for (final value in controller.materialien.toList()) {
|
|
await controller.removeMaterial(value);
|
|
}
|
|
final reloaded = Get.put(HomeController(), tag: 'empty-reload');
|
|
expect(reloaded.materialien, isEmpty);
|
|
expect(reloaded.materialController.text, isEmpty);
|
|
expect(
|
|
storage.getModelList(StorageKeys.materialien).single['werte'],
|
|
isEmpty,
|
|
);
|
|
},
|
|
);
|
|
}
|