Skip to content

Commit

Permalink
compose test: Test topic- and content-max-length validation errors
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbobbe authored and gnprice committed Jan 23, 2025
1 parent c0b9a5d commit e67b014
Showing 1 changed file with 107 additions and 0 deletions.
107 changes: 107 additions & 0 deletions test/widgets/compose_box_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ void main() {
await tester.enterText(contentInputFinder, content);
}

Future<void> tapSendButton(WidgetTester tester) async {
connection.prepare(json: SendMessageResult(id: 123).toJson());
await tester.tap(find.byIcon(ZulipIcons.send));
await tester.pump(Duration.zero);
}

group('ComposeContentController', () {
group('insertPadded', () {
// Like `parseMarkedText` in test/model/autocomplete_test.dart,
Expand Down Expand Up @@ -206,6 +212,107 @@ void main() {
});
});

group('length validation', () {
final channel = eg.stream();

/// String where there are [n] Unicode code points,
/// >[n] UTF-16 code units, and <[n] "characters" a.k.a. grapheme clusters.
String makeStringWithCodePoints(int n) {
assert(n >= 5);
const graphemeCluster = '👨‍👩‍👦';
assert(graphemeCluster.runes.length == 5);
assert(graphemeCluster.length == 8);
assert(graphemeCluster.characters.length == 1);

final result =
graphemeCluster * (n ~/ 5)
+ 'a' * (n % 5);
assert(result.runes.length == n);

return result;
}

group('content', () {
Future<void> prepareWithContent(WidgetTester tester, String content) async {
TypingNotifier.debugEnable = false;
addTearDown(TypingNotifier.debugReset);

final narrow = ChannelNarrow(channel.streamId);
await prepareComposeBox(tester, narrow: narrow, streams: [channel]);
await enterTopic(tester, narrow: narrow, topic: 'some topic');
await enterContent(tester, content);
}

Future<void> checkErrorResponse(WidgetTester tester) async {
await tester.tap(find.byWidget(checkErrorDialog(tester,
expectedTitle: 'Message not sent',
expectedMessage: 'Message length shouldn\'t be greater than 10000 characters.')));
}

testWidgets('too-long content is rejected', (tester) async {
await prepareWithContent(tester,
makeStringWithCodePoints(kMaxMessageLengthCodePoints + 1));
await tapSendButton(tester);
await checkErrorResponse(tester);
});

// TODO(#1238) unskip
// testWidgets('max-length content not rejected', (tester) async {
// await prepareWithContent(tester,
// makeStringWithCodePoints(kMaxMessageLengthCodePoints));
// await tapSendButton(tester);
// checkNoErrorDialog(tester);
// });

// TODO(#1238) replace with above commented-out test
testWidgets('some content not rejected', (tester) async {
await prepareWithContent(tester, 'a' * kMaxMessageLengthCodePoints);
await tapSendButton(tester);
checkNoErrorDialog(tester);
});
});

group('topic', () {
Future<void> prepareWithTopic(WidgetTester tester, String topic) async {
TypingNotifier.debugEnable = false;
addTearDown(TypingNotifier.debugReset);

final narrow = ChannelNarrow(channel.streamId);
await prepareComposeBox(tester, narrow: narrow, streams: [channel]);
await enterTopic(tester, narrow: narrow, topic: topic);
await enterContent(tester, 'some content');
}

Future<void> checkErrorResponse(WidgetTester tester) async {
await tester.tap(find.byWidget(checkErrorDialog(tester,
expectedTitle: 'Message not sent',
expectedMessage: 'Topic length shouldn\'t be greater than 60 characters.')));
}

testWidgets('too-long topic is rejected', (tester) async {
await prepareWithTopic(tester,
makeStringWithCodePoints(kMaxTopicLengthCodePoints + 1));
await tapSendButton(tester);
await checkErrorResponse(tester);
});

// TODO(#1238) unskip
// testWidgets('max-length topic not rejected', (tester) async {
// await prepareWithTopic(tester,
// makeStringWithCodePoints(kMaxTopicLengthCodePoints));
// await tapSendButton(tester);
// checkNoErrorDialog(tester);
// });

// TODO(#1238) replace with above commented-out test
testWidgets('some topic not rejected', (tester) async {
await prepareWithTopic(tester, 'a' * kMaxTopicLengthCodePoints);
await tapSendButton(tester);
checkNoErrorDialog(tester);
});
});
});

group('ComposeBox textCapitalization', () {
void checkComposeBoxTextFields(WidgetTester tester, {
required bool expectTopicTextField,
Expand Down

0 comments on commit e67b014

Please sign in to comment.