Files
rely/test/features/app/app_mobile_crud_sync_flow_test.dart
T
2026-05-18 20:33:54 +02:00

96 lines
3.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:relationship_saver/core/auth/in_memory_token_store.dart';
import 'package:relationship_saver/features/local/storage/local_data_store_in_memory.dart';
import 'package:relationship_saver/features/local/storage/local_data_store_provider.dart';
import 'package:relationship_saver/features/sync/storage/sync_state_store_in_memory.dart';
import 'package:relationship_saver/features/sync/storage/sync_state_store_provider.dart';
import 'package:relationship_saver/features/sync/sync_queue_repository.dart';
import 'package:relationship_saver/integrations/backend/backend_gateway_fake.dart';
import 'package:relationship_saver/integrations/backend/backend_gateway_provider.dart';
import 'package:relationship_saver/integrations/backend/models/backend_models.dart';
import 'package:relationship_saver/main.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
setUp(() {
SharedPreferences.setMockInitialValues(<String, Object>{});
});
testWidgets('mobile flow adds person and queues a sync change', (
WidgetTester tester,
) async {
await tester.binding.setSurfaceSize(const Size(390, 844));
addTearDown(() => tester.binding.setSurfaceSize(null));
final ProviderContainer container = ProviderContainer(
overrides: [
tokenStoreProvider.overrideWithValue(InMemoryTokenStore()),
backendGatewayProvider.overrideWithValue(BackendGatewayFake()),
localDataStoreProvider.overrideWithValue(InMemoryLocalDataStore()),
syncStateStoreProvider.overrideWithValue(InMemorySyncStateStore()),
],
);
addTearDown(container.dispose);
await tester.pumpWidget(
UncontrolledProviderScope(
container: container,
child: const RelationshipSaverApp(),
),
);
await tester.pumpAndSettle();
expect(find.text('Sign in to continue'), findsOneWidget);
await tester.tap(find.widgetWithText(FilledButton, 'Sign In'));
await tester.pumpAndSettle(const Duration(milliseconds: 500));
expect(find.text('Capture'), findsWidgets);
await tester.tap(find.text('People').last);
await tester.pumpAndSettle(const Duration(milliseconds: 500));
expect(find.text('People'), findsWidgets);
await tester.tap(find.widgetWithText(FilledButton, 'Add person'));
await tester.pumpAndSettle(const Duration(milliseconds: 300));
expect(find.text('Add Person'), findsOneWidget);
await tester.enterText(
find.widgetWithText(TextField, 'Name'),
'Taylor Quinn',
);
await tester.enterText(
find.widgetWithText(TextField, 'Relationship'),
'Partner',
);
await tester.enterText(
find.widgetWithText(TextField, 'Tags (comma separated)'),
'tea, books',
);
await tester.enterText(
find.widgetWithText(TextField, 'Notes'),
'Prefers calm evenings and handmade gifts.',
);
await tester.tap(find.widgetWithText(FilledButton, 'Save'));
await tester.pumpAndSettle(const Duration(milliseconds: 500));
expect(find.text('Taylor Quinn'), findsWidgets);
final syncState = await container.read(syncQueueRepositoryProvider.future);
expect(syncState.pendingChanges.isNotEmpty, isTrue);
expect(
syncState.pendingChanges.any((ChangeEnvelope change) {
return change.entityType == 'person' &&
change.op == ChangeOperation.upsert &&
change.payload?['name'] == 'Taylor Quinn';
}),
isTrue,
);
});
}