feat(studyset): make a studyset private or not, and what a locked one shows (ADR 0019)

- A top-level studyset's options make it private, with everything inside
  it, or non-private again, after a dialog saying what changes and that
  the instance's backups keep readable copies until they expire; a device
  without the account's keys says how to get them there.
- A locked studyset (its key doesn't open here) is titled Locked, says
  why when opened, and offers only Delete.
- Publishing names the person's tags as the device reads them, and says
  what to do when the studyset is private or a tag has no name.
- The export sheet says an archive is readable by whoever has the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-21 21:40:27 +02:00
commit 0e10afcc68
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -0,0 +1,33 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_learn_flutter/src/feature/publish/data/publish_repository.dart';
import '../../../support/fake_publish_gateway.dart';
import '../../../support/memory_published_store.dart';
/// The instance can't read the person's tags (ADR 0019, D2): publishing
/// names them as this device reads them.
void main() {
test("publishing sends the tags' names this device reads", () async {
final gateway = FakePublishGateway();
final publishing = PublishRepository(
gateway,
MemoryPublishedStore(),
tagNames: () async => {'tag-1': 'JLPT-N5'},
);
addTearDown(publishing.dispose);
await publishing.publish('studyset-1', slug: 'japanese', notes: '');
expect(gateway.lastTagNames, {'tag-1': 'JLPT-N5'});
});
test('without names to give, none are sent', () async {
final gateway = FakePublishGateway();
final publishing = PublishRepository(gateway, MemoryPublishedStore());
addTearDown(publishing.dispose);
await publishing.publish('studyset-1', slug: 'japanese', notes: '');
expect(gateway.lastTagNames, isNull);
});
}