fix(explore): a study button in a copy studies the copy's studyset
All checks were successful
CI / check (push) Successful in 15m38s
CI / deploy (push) Successful in 1m20s

A study button names the studyset it studies by its id. Copied from a
release or an archive, the studysets get new ids, and a button in the
content kept naming the author's (or the archive's), which the person
doesn't have: it studied nothing. The copier now writes the content after
the studysets, each study button naming the studyset made of the one it
named; only a study button's studyset, as a short id could also be a word
of the content.

A later release taken into a copy still brings the author's ids into its
buttons: the copy updater doesn't rename them yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-11 16:50:26 +02:00
commit 0d4f7a432d
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -4,6 +4,7 @@ import 'dart:typed_data';
import 'package:archive/archive.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_learn_flutter/src/core/asset/data/asset_repository.dart';
import 'package:halkyon_learn_flutter/src/core/content/content_blocks.dart';
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
import 'package:halkyon_learn_flutter/src/feature/archive/data/archive_importer.dart';
import 'package:halkyon_learn_flutter/src/feature/archive/data/archive_reader.dart';
@ -12,7 +13,12 @@ import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart
import 'package:halkyon_learn_flutter/src/feature/card/model/card_content.dart';
import 'package:halkyon_learn_flutter/src/feature/dictionary/data/dictionary_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/explore/data/release_copier.dart';
import 'package:halkyon_learn_flutter/src/feature/learning_path/data/learning_path_payload.dart';
import 'package:halkyon_learn_flutter/src/feature/learning_path/data/learning_path_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/learning_path/data/learning_path_step_payload.dart';
import 'package:halkyon_learn_flutter/src/feature/learning_path/model/exercise.dart';
import 'package:halkyon_learn_flutter/src/feature/learning_path/model/learning_path.dart';
import 'package:halkyon_learn_flutter/src/feature/learning_path/model/step_content.dart';
import 'package:halkyon_learn_flutter/src/feature/note/data/note_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/pdf_source/data/pdf_source_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/study/data/review_repository.dart';
@ -163,13 +169,14 @@ void main() {
late StudysetRepository studysets;
late TagRepository tags;
late ReviewRepository reviews;
late LearningPathRepository paths;
late ArchiveImporter importer;
setUp(() {
studysets = StudysetRepository(FakeStudysetGateway());
cards = CardRepository(FakeCardGateway());
final notes = NoteRepository(FakeNoteGateway());
final paths = LearningPathRepository(FakeLearningPathGateway());
paths = LearningPathRepository(FakeLearningPathGateway());
tags = TagRepository(
FakeTagGateway(),
cardChanges: cards.changes,
@ -203,6 +210,57 @@ void main() {
);
});
test('content naming a studyset of the archive, as a study button '
'does, names it as it is in the library', () async {
final archive = {
...japanese(),
'paths/drill/path.json': {
'id': 'drill',
'position': 'a0',
'payload': json(
encodeLearningPathPayload(LearningPathContent.titled('Drill')),
),
},
'paths/drill/steps/go.json': {
'id': 'go',
'position': 'a0',
'kind': StepKind.info.value,
'payload': json(
encodeStepPayload(
StepContent.empty(StepKind.info).withField(
StepField.body,
RichContent({
'document': {
'type': 'page',
'children': [
{
'type': studyButtonBlockType,
'data': {studyButtonStudysetKey: 'vocabulary'},
},
],
},
}),
),
),
),
},
};
await importer.import(readArchive(zip(archive)));
final vocabulary = (await studysets.all()).singleWhere(
(s) => s.content.title == 'Vocabulary',
);
final path = (await paths.pathsOf(
(await studysets.all()).singleWhere((s) => s.parentId == null).id,
)).single;
final step = (await paths.stepsOf(path.id)).single;
expect(
jsonEncode(step.content.body.toJson()),
contains('"$studyButtonStudysetKey":"${vocabulary.id}"'),
);
});
test("brings the studysets and cards in as the person's own, a word "
'from the dictionary as adding it makes it, the reviews onto the '
'cards they were of; an entry the instance lacks is left out and '