import 'package:flutter_test/flutter_test.dart'; import 'package:marianum_mobile/push/push_status.dart'; const _liveProxy = 'https://connect.marianum-fulda.de/push-proxy/'; const _betaProxy = 'https://connect-beta.marianum-fulda.de/push-proxy/'; PushTypeStatus _typeStatus({ bool nextcloudRegistered = true, String? registeredNcBaseUrl = 'https://cloud.marianum-fulda.de', String? registeredProxyServer = _liveProxy, DateTime? lastRegistrationAt, String? lastRegistrationError, }) => PushTypeStatus( nextcloudRegistered: nextcloudRegistered, registeredNcBaseUrl: registeredNcBaseUrl, registeredProxyServer: registeredProxyServer, lastRegistrationAt: lastRegistrationAt, lastRegistrationError: lastRegistrationError, ); PushStatusReport _report({ bool settingEnabled = true, PushCheck osPermission = PushCheck.ok, PushCheck serverCapability = PushCheck.ok, bool appPasswordPresent = true, bool talkAppPasswordPresent = true, bool keypairPresent = true, PushTypeStatus? general, PushTypeStatus? talk, String? currentProxyServer = _liveProxy, }) => PushStatusReport( settingEnabled: settingEnabled, osPermission: osPermission, serverCapability: serverCapability, appPasswordPresent: appPasswordPresent, talkAppPasswordPresent: talkAppPasswordPresent, keypairPresent: keypairPresent, general: general ?? _typeStatus(), talk: talk ?? _typeStatus(), currentProxyServer: currentProxyServer, ); PushStatusRow _row(List rows, String label) => rows.singleWhere((r) => r.label == label); void main() { group('buildPushStatusRows', () { test('healthy chain shows nine ok rows in chain order', () { final rows = buildPushStatusRows(_report()); expect(rows, hasLength(9)); expect(rows.map((r) => r.label), [ 'Push-Benachrichtigungen aktiviert', 'Benachrichtigungsberechtigung', 'Server-Unterstützung', 'App-Passwörter', 'Geräteschlüssel', 'Nextcloud-Registrierung (Allgemein)', 'Nextcloud-Registrierung (Talk)', 'Connect-Registrierung (Allgemein)', 'Connect-Registrierung (Talk)', ]); expect(rows.every((r) => r.state == PushCheck.ok), isTrue); }); test('disabled setting fails the first row with a hint', () { final rows = buildPushStatusRows(_report(settingEnabled: false)); final row = _row(rows, 'Push-Benachrichtigungen aktiviert'); expect(row.state, PushCheck.fail); expect(row.detail, contains('deaktiviert')); }); test('unloaded capabilities show as unknown, not as failure', () { final rows = buildPushStatusRows( _report(serverCapability: PushCheck.unknown), ); final row = _row(rows, 'Server-Unterstützung'); expect(row.state, PushCheck.unknown); expect(row.detail, contains('noch nicht geladen')); }); test('missing talk app password fails the password row and names it', () { final rows = buildPushStatusRows(_report(talkAppPasswordPresent: false)); final row = _row(rows, 'App-Passwörter'); expect(row.state, PushCheck.fail); expect(row.detail, contains('Talk-App-Passwort fehlt')); }); test('registered rows carry their URL as detail', () { final rows = buildPushStatusRows(_report()); expect( _row(rows, 'Nextcloud-Registrierung (Allgemein)').detail, 'https://cloud.marianum-fulda.de', ); expect(_row(rows, 'Connect-Registrierung (Talk)').detail, _liveProxy); }); test('a broken talk registration fails only the talk rows', () { final rows = buildPushStatusRows( _report( talk: _typeStatus( nextcloudRegistered: false, registeredProxyServer: null, ), ), ); expect( _row(rows, 'Nextcloud-Registrierung (Allgemein)').state, PushCheck.ok, ); expect( _row(rows, 'Connect-Registrierung (Allgemein)').state, PushCheck.ok, ); expect( _row(rows, 'Nextcloud-Registrierung (Talk)').state, PushCheck.fail, ); final talkConnect = _row(rows, 'Connect-Registrierung (Talk)'); expect(talkConnect.state, PushCheck.fail); expect(talkConnect.detail, contains('ausstehend')); }); test('proxy endpoint mismatch fails the affected row naming both URLs', () { final report = _report( talk: _typeStatus(registeredProxyServer: _liveProxy), currentProxyServer: _betaProxy, general: _typeStatus(registeredProxyServer: _betaProxy), ); expect(report.proxyEndpointMismatch(report.talk), isTrue); expect(report.proxyEndpointMismatch(report.general), isFalse); final row = _row( buildPushStatusRows(report), 'Connect-Registrierung (Talk)', ); expect(row.state, PushCheck.fail); expect(row.detail, contains('connect.marianum-fulda.de')); expect(row.detail, contains('connect-beta.marianum-fulda.de')); }); test('per-type registration errors fail only their own connect row', () { final rows = buildPushStatusRows( _report(talk: _typeStatus(lastRegistrationError: 'HTTP 404')), ); expect( _row(rows, 'Connect-Registrierung (Allgemein)').state, PushCheck.ok, ); final talkRow = _row(rows, 'Connect-Registrierung (Talk)'); expect(talkRow.state, PushCheck.fail); expect(talkRow.detail, contains('fehlgeschlagen')); }); }); group('PushStatusReport.readyForTestNotification', () { test('test push only depends on the general chain', () { // Test pushes are Connect direct pushes via the general registration — // a broken talk registration must not disable the test action. final report = _report( talk: _typeStatus( nextcloudRegistered: false, registeredProxyServer: null, lastRegistrationError: 'HTTP 404', ), ); expect(report.readyForTestNotification, isTrue); }); test('denied OS permission wins over a complete registration', () { expect( _report(osPermission: PushCheck.fail).readyForTestNotification, isFalse, ); }); test('undetermined OS permission stays permissive', () { expect( _report(osPermission: PushCheck.unknown).readyForTestNotification, isTrue, ); }); test('missing general registration is not ready', () { expect( _report( general: _typeStatus(nextcloudRegistered: false), ).readyForTestNotification, isFalse, ); expect( _report( general: _typeStatus(registeredProxyServer: null), ).readyForTestNotification, isFalse, ); }); test('general endpoint mismatch or failed attempt is not ready', () { expect( _report( general: _typeStatus(registeredProxyServer: _liveProxy), talk: _typeStatus(registeredProxyServer: _betaProxy), currentProxyServer: _betaProxy, ).readyForTestNotification, isFalse, ); expect( _report( general: _typeStatus(lastRegistrationError: 'HTTP 404'), ).readyForTestNotification, isFalse, ); }); }); }