todo-app/test/wrapper_server_e2e_passphrase_test.dart
Krzysztof kuhy Rudnicki f7e24bbb1a
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file-length / file length <= 250 lines (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Desktop adopts the E2E passphrase once
The wrapper serves ~/.config/crdt-sync/password once on
/sync-e2e-passphrase; the web app stores it in its keystore, so desktop
todo never asks. Android still unlocks via the lock tile.

Todo: fda71ed1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 09:56:07 +01:00

73 lines
2.4 KiB
Dart

import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart' as http_testing;
import 'package:todo/desktop/wrapper_server.dart';
import 'package:todo/sync/e2e_passphrase_source.dart';
import 'fake_secure_storage.dart';
import 'wrapper_server_harness.dart';
void main() {
final h = WrapperHarness()..install();
group('wrapper e2e passphrase route', () {
test('serves the shared password once, then 404s', () async {
final origin = await h.enabledOrigin({'password': 'shared-pw\n'});
final url = Uri.parse('$origin$kSyncE2ePassphrasePath');
final first = await http.get(url);
expect(first.statusCode, HttpStatus.ok);
expect(first.body, 'shared-pw');
expect((await http.get(url)).statusCode, HttpStatus.notFound);
});
test('is 404 without a password file', () async {
final origin = await h.enabledOrigin({});
final url = Uri.parse('$origin$kSyncE2ePassphrasePath');
expect((await http.get(url)).statusCode, HttpStatus.notFound);
});
});
group('readE2ePassphrase', () {
setUp(() {
TestWidgetsFlutterBinding.ensureInitialized();
installFakeSecureStorage(initial: {'crdt_sync_e2e_passphrase': ''});
});
test('adopts the wrapper passphrase into the keystore once', () async {
var calls = 0;
final client = http_testing.MockClient((request) async {
calls++;
return http.Response('from-wrapper', 200);
});
final base = Uri.parse('http://127.0.0.1:1/');
expect(
await readE2ePassphrase(base: base, client: client),
'from-wrapper',
);
expect(
await readE2ePassphrase(base: base, client: client),
'from-wrapper',
);
expect(calls, 1);
});
test('no wrapper (file:// on Android) is just no passphrase', () async {
expect(await readE2ePassphrase(base: Uri.parse('file:///')), isNull);
});
test('a failing wrapper is no passphrase, not a crash', () async {
final client = http_testing.MockClient(
(_) async => http.Response('', 404),
);
final base = Uri.parse('http://127.0.0.1:1/');
expect(await readE2ePassphrase(base: base, client: client), isNull);
final down = http_testing.MockClient(
(_) async => throw const SocketException('x'),
);
expect(await readE2ePassphrase(base: base, client: down), isNull);
});
});
}