Files
sharedinbox/test/unit/managesieve_probe_service_test.dart
T

172 lines
4.7 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:sharedinbox/core/models/account.dart';
import 'package:sharedinbox/core/repositories/account_repository.dart';
import 'package:sharedinbox/core/services/managesieve_probe_service.dart';
const _imapAccount = Account(
id: 'acc-1',
displayName: 'Alice',
email: 'alice@example.com',
imapHost: 'imap.example.com',
smtpHost: 'smtp.example.com',
);
class _RecordingRepo implements AccountRepository {
final updates = <Account>[];
@override
Future<void> updateAccount(Account account, {String? password}) async {
updates.add(account);
}
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
ManageSieveProbeService _service(_RecordingRepo repo, {required bool result}) {
return ManageSieveProbeService(
repo,
probeFn: ({
required String host,
required int port,
required bool useTls,
}) async =>
result,
);
}
void main() {
group('ManageSieveProbeService', () {
test('marks unavailable when probe fails', () async {
final repo = _RecordingRepo();
await _service(repo, result: false).probe(_imapAccount);
expect(repo.updates, hasLength(1));
expect(repo.updates.first.manageSieveAvailable, false);
});
test('marks available when probe succeeds', () async {
final repo = _RecordingRepo();
await _service(repo, result: true).probe(_imapAccount);
expect(repo.updates, hasLength(1));
expect(repo.updates.first.manageSieveAvailable, true);
});
test('skips DB write when result matches stored value', () async {
final repo = _RecordingRepo();
const account = Account(
id: 'acc-1',
displayName: 'Alice',
email: 'alice@example.com',
imapHost: 'imap.example.com',
smtpHost: 'smtp.example.com',
manageSieveAvailable: false,
);
await _service(repo, result: false).probe(account);
expect(repo.updates, isEmpty);
});
test('skips JMAP accounts entirely', () async {
final repo = _RecordingRepo();
var probeCalled = false;
final svc = ManageSieveProbeService(
repo,
probeFn: ({
required String host,
required int port,
required bool useTls,
}) async {
probeCalled = true;
return true;
},
);
const jmap = Account(
id: 'acc-2',
displayName: 'Bob',
email: 'bob@example.com',
type: AccountType.jmap,
jmapUrl: 'https://example.com/jmap/session',
);
await svc.probe(jmap);
expect(probeCalled, false);
expect(repo.updates, isEmpty);
});
test('skips when imapHost and manageSieveHost are both empty', () async {
final repo = _RecordingRepo();
var probeCalled = false;
final svc = ManageSieveProbeService(
repo,
probeFn: ({
required String host,
required int port,
required bool useTls,
}) async {
probeCalled = true;
return true;
},
);
const blank = Account(
id: 'acc-3',
displayName: 'Carol',
email: 'carol@example.com',
);
await svc.probe(blank);
expect(probeCalled, false);
expect(repo.updates, isEmpty);
});
test('uses manageSieveHost override when set', () async {
final repo = _RecordingRepo();
String? probedHost;
int? probedPort;
bool? probedTls;
final svc = ManageSieveProbeService(
repo,
probeFn: ({
required String host,
required int port,
required bool useTls,
}) async {
probedHost = host;
probedPort = port;
probedTls = useTls;
return true;
},
);
const account = Account(
id: 'acc-1',
displayName: 'Alice',
email: 'alice@example.com',
imapHost: 'imap.example.com',
smtpHost: 'smtp.example.com',
manageSieveHost: 'sieve.elsewhere.com',
manageSievePort: 2000,
manageSieveSsl: false,
);
await svc.probe(account);
expect(probedHost, 'sieve.elsewhere.com');
expect(probedPort, 2000);
expect(probedTls, false);
});
test('falls back to imapHost when manageSieveHost is blank', () async {
final repo = _RecordingRepo();
String? probedHost;
final svc = ManageSieveProbeService(
repo,
probeFn: ({
required String host,
required int port,
required bool useTls,
}) async {
probedHost = host;
return true;
},
);
await svc.probe(_imapAccount);
expect(probedHost, 'imap.example.com');
});
});
}