Skip to content

Commit 25cf030

Browse files
chrisbobbegithub-actions[bot]
authored andcommitted
compose test: Test topic- and content-max-length validation errors
1 parent 9dc69b2 commit 25cf030

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

test/widgets/compose_box_test.dart

+107
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ void main() {
104104
await tester.enterText(contentInputFinder, content);
105105
}
106106

107+
Future<void> tapSendButton(WidgetTester tester) async {
108+
connection.prepare(json: SendMessageResult(id: 123).toJson());
109+
await tester.tap(find.byIcon(ZulipIcons.send));
110+
await tester.pump(Duration.zero);
111+
}
112+
107113
group('ComposeContentController', () {
108114
group('insertPadded', () {
109115
// Like `parseMarkedText` in test/model/autocomplete_test.dart,
@@ -206,6 +212,107 @@ void main() {
206212
});
207213
});
208214

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

0 commit comments

Comments
 (0)