xworkmate-app/test/runtime/secure_config_store_test.dart

113 lines
3.8 KiB
Dart

import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:xworkmate/runtime/secure_config_store.dart';
import 'package:xworkmate/runtime/runtime_models.dart';
void main() {
test(
'SecureConfigStore persists settings and secure refs in test runners',
() async {
SharedPreferences.setMockInitialValues(<String, Object>{});
final store = SecureConfigStore();
final snapshot = SettingsSnapshot.defaults().copyWith(
accountUsername: 'tester',
accountWorkspace: 'QA',
gateway: GatewayConnectionProfile.defaults().copyWith(
host: 'gateway.example.com',
port: 9443,
),
);
await store.saveSettingsSnapshot(snapshot);
await store.saveGatewayToken('token-secret');
await store.saveGatewayPassword('password-secret');
await store.saveVaultToken('vault-secret');
await store.saveAiGatewayApiKey('ai-gateway-secret');
final loadedSnapshot = await store.loadSettingsSnapshot();
final secureRefs = await store.loadSecureRefs();
expect(loadedSnapshot.accountUsername, 'tester');
expect(loadedSnapshot.accountWorkspace, 'QA');
expect(loadedSnapshot.gateway.host, 'gateway.example.com');
expect(loadedSnapshot.gateway.port, 9443);
expect(secureRefs['gateway_token'], 'token-secret');
expect(secureRefs['gateway_password'], 'password-secret');
expect(secureRefs['vault_token'], 'vault-secret');
expect(secureRefs['ai_gateway_api_key'], 'ai-gateway-secret');
expect(SecureConfigStore.maskValue('token-secret'), 'tok••••ret');
expect(SecureConfigStore.maskValue(''), 'Not set');
},
);
test(
'SecureConfigStore clears gateway token without touching snapshot',
() async {
SharedPreferences.setMockInitialValues(<String, Object>{});
final store = SecureConfigStore();
await store.saveGatewayToken('token-secret');
expect(await store.loadGatewayToken(), 'token-secret');
await store.clearGatewayToken();
expect(await store.loadGatewayToken(), isNull);
expect(
(await store.loadSecureRefs()).containsKey('gateway_token'),
isFalse,
);
},
);
test(
'SecureConfigStore falls back to file-backed device identity and token across instances',
() async {
SharedPreferences.setMockInitialValues(<String, Object>{});
final tempDirectory = await Directory.systemTemp.createTemp(
'xworkmate-secure-store-',
);
addTearDown(() async {
if (await tempDirectory.exists()) {
await tempDirectory.delete(recursive: true);
}
});
final identity = const LocalDeviceIdentity(
deviceId: 'device-123',
publicKeyBase64Url: 'public-key',
privateKeyBase64Url: 'private-key',
createdAtMs: 1700000000000,
);
final firstStore = SecureConfigStore(
fallbackDirectoryPathResolver: () async => tempDirectory.path,
);
await firstStore.saveDeviceIdentity(identity);
await firstStore.saveDeviceToken(
deviceId: identity.deviceId,
role: 'operator',
token: 'device-token',
);
final secondStore = SecureConfigStore(
fallbackDirectoryPathResolver: () async => tempDirectory.path,
);
final reloadedIdentity = await secondStore.loadDeviceIdentity();
final reloadedToken = await secondStore.loadDeviceToken(
deviceId: identity.deviceId,
role: 'operator',
);
expect(reloadedIdentity?.deviceId, identity.deviceId);
expect(reloadedIdentity?.publicKeyBase64Url, identity.publicKeyBase64Url);
expect(
reloadedIdentity?.privateKeyBase64Url,
identity.privateKeyBase64Url,
);
expect(reloadedToken, 'device-token');
},
);
}