Skip to content

Commit 3708cb4

Browse files
committed
compose test: Test topic- and content-max-length validation errors
1 parent f4c5ff3 commit 3708cb4

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

test/widgets/compose_box_test.dart

+106
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,23 @@ void main() {
9595
..url.path.equals('/api/v1/users/me/${narrow.streamId}/topics');
9696
}
9797

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

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

0 commit comments

Comments
 (0)