fix(app): the phrase typed back is pasted into its fields, never copied out
The fields the recovery phrase is typed back into offered the system's Copy, Cut and Share, and Ctrl+C and Ctrl+X copied what was selected (the short reading's L3), so the phrase could still reach clipboard histories, cloud clipboards or another app. Their menu now offers Paste and Select all alone, and the field's own copy and cut, overridden from above, do nothing. The comment on the recovery codes no longer speaks of Copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
290f584329
commit
87529cd5c6
1 changed files with 162 additions and 37 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:halkyon_app/halkyon_app.dart';
|
||||
|
|
@ -19,6 +20,7 @@ void main() {
|
|||
return null;
|
||||
}(),
|
||||
'Clipboard.getData' => {'text': clipboard},
|
||||
'Clipboard.hasStrings' => {'value': clipboard != null},
|
||||
_ => null,
|
||||
},
|
||||
);
|
||||
|
|
@ -101,4 +103,92 @@ void main() {
|
|||
expect(find.byType(SelectableText), findsNothing);
|
||||
expect(clipboard, isNull);
|
||||
});
|
||||
|
||||
group('the phrase typed back is never copied, cut or shared from its '
|
||||
'fields: pasted into them only (the short reading, L3)', () {
|
||||
Future<void> withControl(
|
||||
WidgetTester tester,
|
||||
LogicalKeyboardKey key,
|
||||
) async {
|
||||
await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
|
||||
await tester.sendKeyEvent(key);
|
||||
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
|
||||
await tester.pump();
|
||||
}
|
||||
|
||||
/// Selects all of [field]'s text, then copies and cuts it with the keys.
|
||||
Future<void> copyAndCut(WidgetTester tester, Finder field) async {
|
||||
await tester.tap(field);
|
||||
await tester.pump();
|
||||
for (final key in [LogicalKeyboardKey.keyC, LogicalKeyboardKey.keyX]) {
|
||||
await withControl(tester, LogicalKeyboardKey.keyA);
|
||||
expect(
|
||||
tester.widget<TextField>(field).controller!.selection.isCollapsed,
|
||||
isFalse,
|
||||
);
|
||||
await withControl(tester, key);
|
||||
}
|
||||
}
|
||||
|
||||
/// Opens [field]'s menu, with its text selected (a right click).
|
||||
Future<void> openMenuOn(WidgetTester tester, Finder field) async {
|
||||
await withControl(tester, LogicalKeyboardKey.keyA);
|
||||
final gesture = await tester.startGesture(
|
||||
tester.getCenter(field),
|
||||
kind: PointerDeviceKind.mouse,
|
||||
buttons: kSecondaryMouseButton,
|
||||
);
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
void expectOnlyPasteAndSelectAll() {
|
||||
for (final item in ['Copy', 'Cut', 'Share', 'Share...']) {
|
||||
expect(find.text(item), findsNothing, reason: item);
|
||||
}
|
||||
expect(find.text('Paste'), findsOneWidget);
|
||||
}
|
||||
|
||||
testWidgets('the whole phrase', (tester) async {
|
||||
mockClipboard(tester);
|
||||
clipboard = 'copied before';
|
||||
final typed = TextEditingController(text: 'abandon ability able');
|
||||
addTearDown(typed.dispose);
|
||||
await pumpView(tester, PhraseField(controller: typed));
|
||||
final field = find.byType(TextField);
|
||||
|
||||
await copyAndCut(tester, field);
|
||||
await openMenuOn(tester, field);
|
||||
expectOnlyPasteAndSelectAll();
|
||||
|
||||
expect(clipboard, 'copied before');
|
||||
expect(typed.text, 'abandon ability able');
|
||||
}, variant: TargetPlatformVariant.only(TargetPlatform.linux));
|
||||
|
||||
testWidgets('its words', (tester) async {
|
||||
mockClipboard(tester);
|
||||
clipboard = 'copied before';
|
||||
final words = [
|
||||
TextEditingController(text: 'abandon'),
|
||||
TextEditingController(text: 'ability'),
|
||||
];
|
||||
addTearDown(() {
|
||||
for (final word in words) {
|
||||
word.dispose();
|
||||
}
|
||||
});
|
||||
await pumpView(
|
||||
tester,
|
||||
PhraseCheckFields(positions: const [2, 7], controllers: words),
|
||||
);
|
||||
final field = find.byType(TextField).first;
|
||||
|
||||
await copyAndCut(tester, field);
|
||||
await openMenuOn(tester, field);
|
||||
expectOnlyPasteAndSelectAll();
|
||||
|
||||
expect(clipboard, 'copied before');
|
||||
expect(words.first.text, 'abandon');
|
||||
}, variant: TargetPlatformVariant.only(TargetPlatform.linux));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue