chore: Halkyon Learn moves into apps/learn
Its server, client, app and curator, and the tools that write its assets (maps, Anki fixtures, icons), as they are; paths are fixed in the commits that follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
11abd9afce
commit
649499be23
1 changed files with 0 additions and 0 deletions
|
|
@ -0,0 +1,119 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:halkyon_learn_flutter/src/core/content/payload.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/settings/data/settings_payload.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/settings/data/settings_repository.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/settings/model/person_settings.dart';
|
||||
|
||||
import '../../../support/fake_settings_gateway.dart';
|
||||
|
||||
void main() {
|
||||
late FakeSettingsGateway gateway;
|
||||
late SettingsRepository repository;
|
||||
|
||||
setUp(() {
|
||||
gateway = FakeSettingsGateway();
|
||||
repository = SettingsRepository(gateway);
|
||||
});
|
||||
tearDown(() => repository.dispose());
|
||||
|
||||
const verb = (id: 'tag-1', name: 'verb');
|
||||
const noun = (id: 'tag-2', name: 'noun');
|
||||
|
||||
test('a person without settings has the defaults, and nothing is '
|
||||
'stored for reading them', () async {
|
||||
expect(await repository.read(), const PersonSettings());
|
||||
expect(gateway.writes, isEmpty);
|
||||
});
|
||||
|
||||
test('stores a change in one row, made by the first change', () async {
|
||||
await repository.update((s) => s.withStudyTags('japanese', [verb]));
|
||||
await repository.update((s) => s.withStudyTags('german', [noun]));
|
||||
|
||||
expect(
|
||||
await repository.read(),
|
||||
const PersonSettings(
|
||||
studyTags: {
|
||||
'japanese': [verb],
|
||||
'german': [noun],
|
||||
},
|
||||
),
|
||||
);
|
||||
expect({for (final (id, _) in gateway.writes) id}, hasLength(1));
|
||||
});
|
||||
|
||||
test('two rows from two devices fold into the one with the smaller id, '
|
||||
"with the other's settings added where it has none", () async {
|
||||
await repository.update((s) => s.withStudyTags('japanese', [verb]));
|
||||
gateway.receiveRemoteRow(
|
||||
'settings-000',
|
||||
encodeSettingsPayload(
|
||||
const PersonSettings(
|
||||
studyTags: {
|
||||
'japanese': [noun],
|
||||
'german': [noun],
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final settings = await repository.read();
|
||||
|
||||
expect(
|
||||
settings,
|
||||
const PersonSettings(
|
||||
studyTags: {
|
||||
'japanese': [noun],
|
||||
'german': [noun],
|
||||
},
|
||||
),
|
||||
);
|
||||
expect(gateway.deleted, ['settings-001']);
|
||||
// Blanked before deleted.
|
||||
expect(gateway.writes.last, ('settings-001', redactedPayload));
|
||||
});
|
||||
|
||||
test('leaves settings of a newer app version alone, and keeps its own '
|
||||
'beside them', () async {
|
||||
gateway.receiveRemoteRow(
|
||||
'settings-000',
|
||||
encodePayload(settingsSchemaVersion + 1, {'studyTags': {}}),
|
||||
);
|
||||
|
||||
await repository.update((s) => s.withStudyTags('japanese', [verb]));
|
||||
|
||||
expect(
|
||||
(await repository.read()).studyTagsOf('japanese'),
|
||||
[verb],
|
||||
);
|
||||
expect(gateway.deleted, isEmpty);
|
||||
expect(gateway.writes.single.$1, isNot('settings-000'));
|
||||
});
|
||||
|
||||
test('follows changes on this device and from others', () async {
|
||||
final watched = repository.watch();
|
||||
final expectation = expectLater(
|
||||
watched.map((s) => s.studyTags.keys.toList()),
|
||||
emitsInOrder([
|
||||
<String>[],
|
||||
['japanese'],
|
||||
['japanese', 'german'],
|
||||
]),
|
||||
);
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
|
||||
await repository.update((s) => s.withStudyTags('japanese', [verb]));
|
||||
final id = gateway.writes.single.$1;
|
||||
gateway.receiveRemoteRow(
|
||||
id,
|
||||
encodeSettingsPayload(
|
||||
const PersonSettings(
|
||||
studyTags: {
|
||||
'japanese': [verb],
|
||||
'german': [noun],
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
await expectation;
|
||||
});
|
||||
}
|
||||
Loading…
Reference in a new issue