Skip to content

Commit 2ce23fe

Browse files
committed
compose test: Test topic- and content-max-length validation errors
1 parent 15f5bc1 commit 2ce23fe

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

test/widgets/compose_box_test.dart

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,23 @@ void main() {
9696
..url.path.equals('/api/v1/users/me/${narrow.streamId}/topics');
9797
}
9898

99+
/// Set the content input's text to [content], using [WidgetTester.enterText].
100+
Future<void> enterContent(WidgetTester tester, {
101+
required ChannelNarrow narrow,
102+
required String content,
103+
}) async {
104+
final contentInputFinder = find.byWidgetPredicate(
105+
(widget) => widget is TextField && widget.controller is ComposeContentController);
106+
107+
await tester.enterText(contentInputFinder, content);
108+
}
109+
110+
Future<void> tapSendButton(WidgetTester tester) async {
111+
connection.prepare(json: SendMessageResult(id: 123).toJson());
112+
await tester.tap(find.byIcon(ZulipIcons.send));
113+
await tester.pump(Duration.zero);
114+
}
115+
99116
group('ComposeContentController', () {
100117
group('insertPadded', () {
101118
// Like `parseMarkedText` in test/model/autocomplete_test.dart,
@@ -198,6 +215,95 @@ void main() {
198215
});
199216
});
200217

218+
group('length validation', () {
219+
final channel = eg.stream();
220+
221+
/// String where the number of Unicode code points is [n]
222+
/// and the number of UTF-16 code units is higher.
223+
String makeStringWithCodePoints(int n) {
224+
assert(n >= 5);
225+
const graphemeCluster = '👨‍👩‍👦';
226+
assert(graphemeCluster.runes.length == 5);
227+
assert(graphemeCluster.length == 8);
228+
assert(graphemeCluster.characters.length == 1);
229+
230+
final result =
231+
graphemeCluster * (n ~/ 5)
232+
+ 'a' * (n % 5);
233+
assert(result.runes.length == n);
234+
235+
return result;
236+
}
237+
238+
group('content', () {
239+
void doTest(String description, {required String content, required bool expectError}) {
240+
testWidgets(description, (tester) async {
241+
TypingNotifier.debugEnable = false;
242+
addTearDown(TypingNotifier.debugReset);
243+
244+
final narrow = ChannelNarrow(channel.streamId);
245+
await prepareComposeBox(tester, narrow: narrow, streams: [channel]);
246+
await enterTopic(tester, narrow: narrow, topic: 'some topic');
247+
await enterContent(tester, narrow: narrow, content: content);
248+
249+
await tapSendButton(tester);
250+
if (expectError) {
251+
await tester.tap(find.byWidget(checkErrorDialog(tester,
252+
expectedTitle: 'Message not sent',
253+
expectedMessage: 'Message length shouldn\'t be greater than 10000 characters.')));
254+
} else {
255+
checkNoErrorDialog(tester);
256+
}
257+
});
258+
}
259+
260+
doTest('too-long content is rejected',
261+
content: makeStringWithCodePoints(kMaxMessageLengthCodePoints + 1), expectError: true);
262+
263+
// TODO(#1238) unskip
264+
// doTest('max-length content not rejected',
265+
// content: makeStringWithCodePoints(kMaxMessageLengthCodePoints), expectError: false);
266+
267+
// TODO(#1238) replace with above commented-out test
268+
doTest('some content not rejected',
269+
content: 'a' * kMaxMessageLengthCodePoints, expectError: false);
270+
});
271+
272+
group('topic', () {
273+
void doTest(String description, {required String topic, required bool expectError}) {
274+
testWidgets(description, (tester) async {
275+
TypingNotifier.debugEnable = false;
276+
addTearDown(TypingNotifier.debugReset);
277+
278+
final narrow = ChannelNarrow(channel.streamId);
279+
await prepareComposeBox(tester, narrow: narrow, streams: [channel]);
280+
await enterTopic(tester, narrow: narrow, topic: topic);
281+
await enterContent(tester, narrow: narrow, content: 'some content');
282+
283+
await tapSendButton(tester);
284+
if (expectError) {
285+
await tester.tap(find.byWidget(checkErrorDialog(tester,
286+
expectedTitle: 'Message not sent',
287+
expectedMessage: 'Topic length shouldn\'t be greater than 60 characters.')));
288+
} else {
289+
checkNoErrorDialog(tester);
290+
}
291+
});
292+
}
293+
294+
doTest('too-long topic is rejected',
295+
topic: makeStringWithCodePoints(kMaxTopicLengthCodePoints + 1), expectError: true);
296+
297+
// TODO(#1238) unskip
298+
// doTest('max-length topic not rejected',
299+
// topic: makeStringWithCodePoints(kMaxTopicLengthCodePoints), expectError: false);
300+
301+
// TODO(#1238) replace with above commented-out test
302+
doTest('some topic not rejected',
303+
topic: 'a' * kMaxTopicLengthCodePoints, expectError: false);
304+
});
305+
});
306+
201307
group('ComposeBox textCapitalization', () {
202308
void checkComposeBoxTextFields(WidgetTester tester, {
203309
required bool expectTopicTextField,

0 commit comments

Comments
 (0)