// Integration test: registration and login flows on device. // Runs EnrollmentDb and SessionManager directly; no card required. // // Run with: flutter test integration_test/ -d emulator-5554 import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:k_phone/enrollment_db.dart'; import 'package:k_phone/session_manager.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('Registration flow', () { late EnrollmentDb db; setUp(() { db = EnrollmentDb(); }); testWidgets('register new user produces log entries', (tester) async { debugPrint('[REGISTRATION] Starting: enrolling user "alice"'); final enrollment = await db.register( username: 'alice', displayName: 'Alice Testuser', ); debugPrint('[REGISTRATION] SUCCESS: user="${enrollment.username}" ' 'displayName="${enrollment.displayName}" ' 'createdAt=${enrollment.createdAt} ' 'hasCredential=${enrollment.hasCredential}'); expect(enrollment.username, equals('alice')); expect(enrollment.displayName, equals('Alice Testuser')); expect(enrollment.hasCredential, isFalse); debugPrint('[REGISTRATION] Verifying user appears in list...'); final list = await db.list(); expect(list.any((e) => e.username == 'alice'), isTrue); debugPrint('[REGISTRATION] OK: "alice" found in enrollment list (${list.length} total)'); debugPrint('[REGISTRATION] Verifying duplicate registration is rejected...'); try { await db.register(username: 'alice'); fail('Expected StateError for duplicate username'); } on StateError catch (e) { debugPrint('[REGISTRATION] OK: duplicate rejected — ${e.message}'); } debugPrint('[REGISTRATION] COMPLETE'); }); testWidgets('delete user removes from enrollment list', (tester) async { await db.register(username: 'bob', displayName: 'Bob Testuser'); debugPrint('[REGISTRATION] Enrolled "bob"'); final deleted = await db.delete('bob'); debugPrint('[REGISTRATION] DELETE: removed user="${deleted.username}"'); final found = await db.get('bob'); expect(found, isNull); debugPrint('[REGISTRATION] OK: "bob" no longer in database'); }); }); group('Login flow', () { final session = SessionManager(); testWidgets('issue and validate session token', (tester) async { debugPrint('[LOGIN] Starting: issuing session for "alice"'); final token = session.issue('alice'); debugPrint('[LOGIN] Token issued: ${token.substring(0, 8)}... (${token.length} chars)'); final valid = session.isValid(token); debugPrint('[LOGIN] Session valid: $valid'); expect(valid, isTrue); final entry = session.getSession(token); debugPrint('[LOGIN] Session entry: username="${entry?.username}" ' 'expires=${entry?.expires.toIso8601String()}'); debugPrint('[LOGIN] COMPLETE'); }); testWidgets('revoke session invalidates token', (tester) async { final token = session.issue('alice'); debugPrint('[LOGIN] Token issued: ${token.substring(0, 8)}...'); session.revoke(token); debugPrint('[LOGIN] Token revoked'); final valid = session.isValid(token); debugPrint('[LOGIN] Session valid after revoke: $valid'); expect(valid, isFalse); debugPrint('[LOGIN] OK: revoked token correctly rejected'); }); testWidgets('revokeAll removes all sessions for user', (tester) async { final t1 = session.issue('charlie'); final t2 = session.issue('charlie'); debugPrint('[LOGIN] Issued 2 sessions for "charlie"'); session.revokeAll('charlie'); debugPrint('[LOGIN] revokeAll("charlie") called'); expect(session.isValid(t1), isFalse); expect(session.isValid(t2), isFalse); debugPrint('[LOGIN] OK: both sessions for "charlie" invalidated'); }); testWidgets('unknown token is rejected', (tester) async { debugPrint('[LOGIN] Testing unknown token...'); final valid = session.isValid('0000000000000000000000000000000000000000000000000000000000000000'); debugPrint('[LOGIN] Unknown token valid: $valid'); expect(valid, isFalse); debugPrint('[LOGIN] OK: unknown token correctly rejected'); }); }); }