Source publiée
Télécharger la source ZIP
CH-J SM Mobile
Parcourez les répertoires et les fichiers pour une version spécifique de l'application.
CH-J / SM Mobile
134 fichiers
sm-mobile-20261016T050549Z-3678f2a05fa9
Ajouté: · Construit:
1
import 'dart:convert';2
import 'package:flutter/material.dart';3
import 'package:flutter_secure_storage/flutter_secure_storage.dart';4
import 'package:flutter_test/flutter_test.dart';5
import 'package:integration_test/integration_test.dart';6
import 'package:sm_mobile/core/app_controller.dart';7
import 'package:sm_mobile/main.dart';8
import 'package:sm_mobile/models/server_profile.dart';9
import 'package:sm_mobile/services/secure_store.dart';10
import 'package:xterm/xterm.dart';12
void main() {13
IntegrationTestWidgetsFlutterBinding.ensureInitialized();14
testWidgets(15
'native secure storage, explicit license, profile UI, OpenSSH and lock',16
(tester) async {17
final namespace = 'sm_integration_${newId()}';18
final store = DeviceStore(19
FlutterSecureStorage(20
aOptions: AndroidOptions(21
resetOnError: false,22
storageNamespace: namespace,23
),24
iOptions: IOSOptions(25
accountName: namespace,26
accessibility: KeychainAccessibility.unlocked_this_device,27
),28
),29
);30
final c = AppController(store);31
Future<void> until(bool Function() predicate) async {32
for (var i = 0; i < 600 && !predicate(); i++) {33
await tester.pump(const Duration(milliseconds: 100));34
}35
expect(predicate(), true);36
}38
await c.initialize();39
c.locale = const Locale('en');40
await tester.pumpWidget(SmMobileApp(c));41
await tester.pumpAndSettle();42
expect(c.accepted, false);43
await tester.tap(find.text('Continue'));44
await tester.pumpAndSettle();45
expect(46
tester47
.widget<FilledButton>(48
find.widgetWithText(FilledButton, 'Accept and continue'),49
)50
.onPressed,51
null,52
);53
await tester.tap(find.byType(Checkbox));54
await tester.pumpAndSettle();55
await tester.tap(find.text('Accept and continue'));56
await until(() => c.accepted);57
await tester.pumpAndSettle();58
await tester.enterText(59
find.byType(TextField).at(0),60
'native integration master password',61
);62
await tester.enterText(63
find.byType(TextField).at(1),64
'native integration master password',65
);66
await tester.tap(67
find.widgetWithText(FilledButton, 'Create secure Vault'),68
);69
await until(() => c.vault.unlocked);70
await tester.pumpAndSettle();71
await tester.tap(find.byTooltip('Add server'));72
await tester.pumpAndSettle();73
final fields = find.byType(TextField);74
await tester.enterText(fields.at(0), 'Isolated device test');75
const host = String.fromEnvironment(76
'SM_TEST_HOST',77
defaultValue: '127.0.0.1',78
);79
await tester.enterText(fields.at(1), host);80
await tester.enterText(81
fields.at(2),82
const String.fromEnvironment('SM_TEST_USER', defaultValue: 'test'),83
);84
await tester.enterText(fields.at(3), '22229');85
FocusManager.instance.primaryFocus?.unfocus();86
await tester.pumpAndSettle();87
await tester.ensureVisible(find.widgetWithText(FilledButton, 'Save'));88
await tester.pumpAndSettle();89
await tester.tap(find.widgetWithText(FilledButton, 'Save'));90
await until(() => c.vault.profiles.isNotEmpty);91
await tester.pumpAndSettle();92
final p = c.vault.profiles.single;93
const keyB64 = String.fromEnvironment('SM_TEST_KEY_B64');94
if (keyB64.isNotEmpty) {95
await c.vault.save(96
ServerProfile(97
id: p.id,98
name: p.name,99
host: p.host,100
username: p.username,101
port: p.port,102
auth: AuthMethod.privateKey,103
),104
privateKey: utf8.decode(base64Decode(keyB64)),105
);106
c.changed();107
await tester.pumpAndSettle();108
await tester.tap(find.text('Isolated device test'));109
await tester.pumpAndSettle();110
await tester.enterText(111
find.byType(TextField).last,112
'isolated-test-passphrase',113
);114
await tester.tap(find.widgetWithText(FilledButton, 'Connect'));115
await until(116
() => find.text('Verify server identity').evaluate().isNotEmpty,117
);118
const fingerprint = String.fromEnvironment('SM_TEST_FINGERPRINT');119
expect(120
find.byWidgetPredicate(121
(w) => w is SelectableText && (w.data ?? '').contains(fingerprint),122
),123
findsOneWidget,124
);125
await tester.tap(find.text('Trust this key'));126
await until(() => c.ssh.connected);127
await tester.pumpAndSettle();128
expect(find.byType(TerminalView), findsOneWidget);129
await tester.tap(find.text('Files').last);130
await tester.pumpAndSettle();131
await until(132
() => find.byTooltip('Parent directory').evaluate().isNotEmpty,133
);134
}135
expect(136
await store.read('vault'),137
isNot(contains('Isolated device test')),138
);139
c.lock();140
await tester.pumpAndSettle();141
expect(c.ssh.connected, false);142
expect(c.vault.unlocked, false);143
expect(find.byType(TerminalView), findsNothing);144
await tester.enterText(145
find.byType(TextField).first,146
'native integration master password',147
);148
await tester.tap(find.widgetWithText(FilledButton, 'Unlock'));149
await until(() => c.vault.unlocked);150
await tester.pumpAndSettle();151
expect(c.vault.profiles.single.name, 'Isolated device test');152
await tester.pumpWidget(const SizedBox());153
c.dispose();154
for (final key in ['vault', 'consent', 'preferences']) {155
await store.delete(key);156
}157
},158
timeout: const Timeout(Duration(minutes: 3)),159
);160
}SHA-256
5f7aaf3659d7794c1d5f8d62c378159f9a235a133d60ee627a51aa557e332a45CH-J Proprietary Software License 1.14 · La source est fournie sous CH-J Proprietary Software License 1.14. Sa disponibilité ne modifie pas les termes de la licence ni n'accorde de droits supplémentaires.
Archive SHA-256
c486a807e4828998b9c57ab0f2e760f7980b31965fe118e89d3e1a5a2b65be65