diff --git a/integration_test/test_support.dart b/integration_test/test_support.dart index 6f74a18b..698e4860 100644 --- a/integration_test/test_support.dart +++ b/integration_test/test_support.dart @@ -3,9 +3,9 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:xworkmate/app/app.dart'; +import 'package:xworkmate/runtime/secure_config_store.dart'; void initializeIntegrationHarness() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -13,15 +13,16 @@ void initializeIntegrationHarness() { Future resetIntegrationPreferences() async { SharedPreferences.setMockInitialValues({}); - try { - final supportDirectory = await getApplicationSupportDirectory(); - final xworkmateDirectory = Directory('${supportDirectory.path}/xworkmate'); - if (await xworkmateDirectory.exists()) { - await xworkmateDirectory.delete(recursive: true); + final isolatedRoot = await Directory.systemTemp.createTemp( + 'xworkmate-integration-store-', + ); + debugOverridePersistentSupportRoot(isolatedRoot.path); + addTearDown(() async { + debugOverridePersistentSupportRoot(null); + if (await isolatedRoot.exists()) { + await isolatedRoot.delete(recursive: true); } - } catch (_) { - // Keep integration setup best-effort on runners without path support. - } + }); } Future pumpDesktopApp( diff --git a/lib/runtime/file_store_support.dart b/lib/runtime/file_store_support.dart index 174f0005..880af2c1 100644 --- a/lib/runtime/file_store_support.dart +++ b/lib/runtime/file_store_support.dart @@ -4,6 +4,15 @@ import 'dart:io'; import 'package:path_provider/path_provider.dart'; import 'package:yaml/yaml.dart'; +String? _persistentSupportRootOverride; + +void debugOverridePersistentSupportRoot(String? path) { + final trimmed = path?.trim() ?? ''; + _persistentSupportRootOverride = trimmed.isEmpty + ? null + : normalizeStoreDirectoryPath(trimmed); +} + enum PersistentStoreScope { settings, tasks, secrets, audit } class PersistentWriteFailure { @@ -120,6 +129,10 @@ class StoreLayoutResolver { } Future _defaultSupportRootPath() async { + final override = _persistentSupportRootOverride; + if (override != null && override.isNotEmpty) { + return override; + } try { final supportDirectory = await getApplicationSupportDirectory(); return '${supportDirectory.path}/xworkmate'; diff --git a/test/runtime/app_controller_desktop_platform_suite.dart b/test/runtime/app_controller_desktop_platform_suite.dart index f7e53077..c0155323 100644 --- a/test/runtime/app_controller_desktop_platform_suite.dart +++ b/test/runtime/app_controller_desktop_platform_suite.dart @@ -12,6 +12,8 @@ import 'package:xworkmate/runtime/desktop_platform_service.dart'; import 'package:xworkmate/runtime/runtime_models.dart'; import 'package:xworkmate/runtime/secure_config_store.dart'; +import '../test_support.dart'; + class _FakeDesktopPlatformService implements DesktopPlatformService { _FakeDesktopPlatformService() : _state = DesktopIntegrationState.fromJson(const { @@ -104,8 +106,13 @@ class _FakeDesktopPlatformService implements DesktopPlatformService { } class _ThrowingSecureConfigStore extends SecureConfigStore { - _ThrowingSecureConfigStore() - : super(enableSecureStorage: false); + _ThrowingSecureConfigStore(String rootPath) + : super( + enableSecureStorage: false, + databasePathResolver: () async => '$rootPath/settings.sqlite3', + fallbackDirectoryPathResolver: () async => rootPath, + defaultSupportDirectoryPathResolver: () async => rootPath, + ); @override Future loadGatewayToken({int? profileIndex}) async { @@ -233,7 +240,10 @@ void main() { () async { SharedPreferences.setMockInitialValues({}); final service = _FakeDesktopPlatformService(); - final controller = AppController(desktopPlatformService: service); + final controller = AppController( + store: createIsolatedTestStore(enableSecureStorage: false), + desktopPlatformService: service, + ); addTearDown(controller.dispose); await _waitFor(() => !controller.initializing); @@ -272,9 +282,19 @@ void main() { () async { SharedPreferences.setMockInitialValues({}); final server = await _FakeGatewayTestServer.start(); - final controller = AppController(store: _ThrowingSecureConfigStore()); + final tempDirectory = await Directory.systemTemp.createTemp( + 'xworkmate-desktop-platform-tests-', + ); + final controller = AppController( + store: _ThrowingSecureConfigStore(tempDirectory.path), + ); addTearDown(server.close); addTearDown(controller.dispose); + addTearDown(() async { + if (await tempDirectory.exists()) { + await tempDirectory.delete(recursive: true); + } + }); await _waitFor(() => !controller.initializing); @@ -299,7 +319,7 @@ void main() { Future _waitFor( bool Function() condition, { - Duration timeout = const Duration(seconds: 2), + Duration timeout = const Duration(seconds: 5), }) async { final stopwatch = Stopwatch()..start(); while (!condition()) { diff --git a/test/runtime/app_controller_navigation_favorites_suite.dart b/test/runtime/app_controller_navigation_favorites_suite.dart index 6d815223..746eab19 100644 --- a/test/runtime/app_controller_navigation_favorites_suite.dart +++ b/test/runtime/app_controller_navigation_favorites_suite.dart @@ -8,12 +8,14 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:xworkmate/app/app_controller.dart'; import 'package:xworkmate/models/app_models.dart'; +import '../test_support.dart'; + void main() { test( 'AppController keeps tasks destination in focused destinations', () async { SharedPreferences.setMockInitialValues({}); - final controller = AppController(); + final controller = AppController(store: createIsolatedTestStore()); addTearDown(controller.dispose); await _waitFor(() => !controller.initializing); @@ -43,7 +45,7 @@ void main() { test('AppController toggles focused navigation destinations', () async { SharedPreferences.setMockInitialValues({}); - final controller = AppController(); + final controller = AppController(store: createIsolatedTestStore()); addTearDown(controller.dispose); await _waitFor(() => !controller.initializing);