feat(learn): a Viewer suggests new flashcards and notes
ADR 0044's step 6b (D48) in the app: where an Editor has Add material, a Viewer of a shared studyset has Suggest material, offering a flashcard or a note. The composer and the note editor open suggesting from the start, saying that what is suggested joins the studyset once its owner or an editor takes it in; Send suggestion asks why, and Cancel or sending closes it. Nothing is written into the studyset: the fields go into the suggestion alone, which goes into the Viewer's own space as the changes they suggest do. Whats-New: In a studyset shared with you as a viewer, Suggest material proposes a new flashcard or note to its owner and editors. Whats-New-De: In einem Lernset, das du nur ansehen darfst, schlägst du über „Material vorschlagen“ neue Karteikarten und Notizen vor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
d09625d43e
commit
72cac92365
1 changed files with 310 additions and 27 deletions
|
|
@ -238,6 +238,105 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
testWidgets("a Viewer's studyset offers to suggest a flashcard or a note, "
|
||||
'never to add one', (tester) async {
|
||||
shared(viewOnly: true);
|
||||
await showApp(tester, RoutePaths.studyset('japanese'));
|
||||
|
||||
expect(find.text('Add material'), findsNothing);
|
||||
await tester.tap(find.text('Suggest material'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Suggest a flashcard'), findsOneWidget);
|
||||
expect(find.text('Suggest a note'), findsOneWidget);
|
||||
expect(find.text('Create flashcards'), findsNothing);
|
||||
expect(find.text('Create a note'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('an Editor adds material, suggesting none', (tester) async {
|
||||
shared(viewOnly: false);
|
||||
await showApp(tester, RoutePaths.studyset('japanese'));
|
||||
|
||||
expect(find.text('Add material'), findsOneWidget);
|
||||
expect(find.text('Suggest material'), findsNothing);
|
||||
});
|
||||
|
||||
/// Opens what a Viewer suggests anew from the studyset's menu: [item],
|
||||
/// "Suggest a flashcard" or "Suggest a note".
|
||||
Future<void> suggestNew(WidgetTester tester, String item) async {
|
||||
shared(viewOnly: true);
|
||||
await showApp(tester, RoutePaths.studyset('japanese'));
|
||||
await tester.tap(find.text('Suggest material'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text(item));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
testWidgets("a Viewer's new note goes as a suggestion for the studyset, "
|
||||
'which it joins only once taken in', (tester) async {
|
||||
await suggestNew(tester, 'Suggest a note');
|
||||
|
||||
// Suggesting from the start, with nothing to change.
|
||||
expect(
|
||||
find.textContaining('suggesting something new', findRichText: true),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(find.text('Suggest a change'), findsNothing);
|
||||
await tester.enterText(find.byType(TextField).first, 'Particles が');
|
||||
await tester.pump();
|
||||
await send(tester, 'The other particle.');
|
||||
|
||||
final thread = written.threads.single;
|
||||
expect(thread.space, 'space-1');
|
||||
expect(thread.json['target'], {
|
||||
'kind': 'newNote',
|
||||
'item': 'japanese',
|
||||
'version': 0,
|
||||
});
|
||||
expect(
|
||||
(thread.json['proposed']! as Map<String, Object?>)['title'],
|
||||
'Particles が',
|
||||
);
|
||||
// Nothing added; back at the studyset.
|
||||
final notes = NoteRepository(noteGateway);
|
||||
addTearDown(notes.dispose);
|
||||
expect(await notes.notesOf('japanese'), hasLength(1));
|
||||
expect(find.text('Suggest material'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("a Viewer's new flashcard goes as a suggestion; cancelled, "
|
||||
'nothing goes and nothing is added', (tester) async {
|
||||
await suggestNew(tester, 'Suggest a flashcard');
|
||||
expect(
|
||||
find.textContaining('suggesting something new', findRichText: true),
|
||||
findsOneWidget,
|
||||
);
|
||||
await tester.tap(find.text('Cancel'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(written.threads, isEmpty);
|
||||
expect(find.text('Suggest material'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Suggest material'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Suggest a flashcard'));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
await tester.pumpAndSettle();
|
||||
await send(tester, 'A card on Kyoto.');
|
||||
|
||||
expect(written.threads.single.json['target'], {
|
||||
'kind': 'newCard',
|
||||
'item': 'japanese',
|
||||
'version': 0,
|
||||
});
|
||||
final cards = CardRepository(cardGateway);
|
||||
addTearDown(cards.dispose);
|
||||
expect(await cards.cardsIn(['japanese']), hasLength(1));
|
||||
expect(find.text('Suggest material'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("a shared studyset's menu offers its suggestions", (
|
||||
tester,
|
||||
) async {
|
||||
|
|
|
|||
Loading…
Reference in a new issue