diff --git a/lib/features/settings/settings_page_core.dart b/lib/features/settings/settings_page_core.dart index c8ef609c..aa4f9291 100644 --- a/lib/features/settings/settings_page_core.dart +++ b/lib/features/settings/settings_page_core.dart @@ -100,6 +100,7 @@ class _SettingsPageState extends State { identifier: identifier, password: _accountPasswordController.text, ); + await _refreshBridgeCapabilities(); } finally { _accountPasswordController.clear(); } @@ -110,6 +111,7 @@ class _SettingsPageState extends State { await widget.controller.settingsController.syncAccountSettings( baseUrl: _accountBaseUrlController.text.trim(), ); + await _refreshBridgeCapabilities(); } Future _verifyAccountMfa(SettingsSnapshot settings) async { @@ -119,11 +121,29 @@ class _SettingsPageState extends State { baseUrl: _accountBaseUrlController.text.trim(), code: _accountMfaCodeController.text.trim(), ); + await _refreshBridgeCapabilities(); } finally { _accountMfaCodeController.clear(); } } + Future _refreshBridgeCapabilities() async { + final dynamic controller = widget.controller; + try { + await controller.refreshSingleAgentCapabilitiesInternal( + forceRefresh: true, + ); + } catch (_) { + // Best effort only. Account sync should still succeed if runtime refresh + // is temporarily unavailable. + } + try { + await controller.refreshAcpCapabilitiesInternal(forceRefresh: true); + } catch (_) { + // Best effort only. Runtime capabilities can be retried later. + } + } + Future _cancelAccountMfa() async { await widget.controller.settingsController.cancelAccountMfaChallenge(); _accountPasswordController.clear(); diff --git a/test/features/settings/settings_page_core_test.dart b/test/features/settings/settings_page_core_test.dart index 2771abf9..6945efdb 100644 --- a/test/features/settings/settings_page_core_test.dart +++ b/test/features/settings/settings_page_core_test.dart @@ -138,6 +138,10 @@ void main() { await controller.settingsController.syncAccountSettings( baseUrl: controller.settings.accountBaseUrl, ); + await controller.refreshSingleAgentCapabilitiesInternal( + forceRefresh: true, + ); + await controller.refreshAcpCapabilitiesInternal(forceRefresh: true); await tester.pump(); expect( @@ -148,6 +152,8 @@ void main() { controller.settingsController.syncedBaseUrls, isNot(contains('https://draft-accounts.svc.plus')), ); + expect(controller.singleAgentRefreshCount, 1); + expect(controller.acpRefreshCount, 1); await controller.settingsController.logoutAccount(); await tester.pump(); @@ -268,6 +274,8 @@ class _FakeSettingsPageController extends ChangeNotifier final _FakeSettingsController settingsController; SettingsSnapshot _settingsDraft; + int singleAgentRefreshCount = 0; + int acpRefreshCount = 0; @override SettingsSnapshot get settings => settingsController.snapshot; @@ -280,6 +288,18 @@ class _FakeSettingsPageController extends ChangeNotifier notifyListeners(); } + Future refreshSingleAgentCapabilitiesInternal({ + bool forceRefresh = false, + }) async { + singleAgentRefreshCount += 1; + } + + Future refreshAcpCapabilitiesInternal({ + bool forceRefresh = false, + }) async { + acpRefreshCount += 1; + } + @override dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); } @@ -290,6 +310,13 @@ class _FakeSettingsController extends SettingsController { final List syncedBaseUrls = []; + @override + Future saveSnapshot(SettingsSnapshot snapshot) async { + snapshotInternal = snapshot; + lastSnapshotJsonInternal = snapshot.toJsonString(); + notifyListeners(); + } + void seedSignedOutState(SettingsSnapshot settings) { snapshotInternal = settings.copyWith(accountLocalMode: true); lastSnapshotJsonInternal = snapshotInternal.toJsonString();