@@ -1365,6 +1365,9 @@ void main() {
1365
1365
of: find.byType (MessageItem ),
1366
1366
matching: find.text (content, findRichText: true )).hitTestable ();
1367
1367
1368
+ Finder messageIsntSentErrorFinder = find.text (
1369
+ 'MESSAGE ISN\' T SENT. CHECK YOUR CONNECTION.' ).hitTestable ();
1370
+
1368
1371
testWidgets ('sent message appear in message list after debounce timeout' , (tester) async {
1369
1372
await setupMessageListPage (tester,
1370
1373
narrow: eg.topicNarrow (stream.streamId, 'topic' ), streams: [stream],
@@ -1374,10 +1377,131 @@ void main() {
1374
1377
await tester.enterText (contentInputFinder, content);
1375
1378
await tester.tap (find.byIcon (ZulipIcons .send));
1376
1379
await tester.pump (Duration .zero);
1377
- check (findTextInMessages (content) ).findsNothing ();
1380
+ check (outboxMessageFinder ).findsNothing ();
1378
1381
1379
1382
await tester.pump (kLocalEchoDebounceDuration);
1380
- check (findTextInMessages (content)).findsOne ();
1383
+ check (outboxMessageFinder).findsOne ();
1384
+ check (find.descendant (
1385
+ of: find.byType (MessageItem ),
1386
+ matching: find.byType (LinearProgressIndicator ))).findsOne ();
1387
+ });
1388
+
1389
+ testWidgets ('failed to send message, retrieve the content to compose box' , (tester) async {
1390
+ await setupMessageListPage (tester,
1391
+ narrow: eg.topicNarrow (stream.streamId, 'topic' ), streams: [stream],
1392
+ messages: []);
1393
+
1394
+ // Send a message and fail. Dismiss the error dialog as it pops up.
1395
+ connection.prepare (apiException: eg.apiBadRequest ());
1396
+ await tester.enterText (contentInputFinder, content);
1397
+ await tester.tap (find.byIcon (ZulipIcons .send));
1398
+ await tester.pump (Duration .zero);
1399
+ await tester.tap (find.byWidget (
1400
+ checkErrorDialog (tester, expectedTitle: 'Message not sent' )));
1401
+ await tester.pump ();
1402
+ check (outboxMessageFinder).findsOne ();
1403
+ check (messageIsntSentErrorFinder).findsOne ();
1404
+
1405
+ final controller = tester.state <ComposeBoxState >(find.byType (ComposeBox )).controller;
1406
+ check (controller.content).text.isNotNull ().isEmpty ();
1407
+
1408
+ // Tap the message. This should put its content back into the compose box
1409
+ // and remove it.
1410
+ await tester.tap (outboxMessageFinder);
1411
+ await tester.pump ();
1412
+ check (outboxMessageFinder).findsNothing ();
1413
+ check (controller.content).text.equals ('$content \n\n ' );
1414
+
1415
+ await tester.pump (kLocalEchoDebounceDuration);
1416
+ });
1417
+
1418
+ testWidgets ('tapping does nothing if compose box is not offered' , (tester) async {
1419
+ final messages = [eg.streamMessage (stream: stream, topic: 'some topic' )];
1420
+ await setupMessageListPage (tester,
1421
+ narrow: const CombinedFeedNarrow (), streams: [stream], subscriptions: [eg.subscription (stream)],
1422
+ messages: messages);
1423
+
1424
+ // Navigate to a message list page in a topic narrow,
1425
+ // which has a compose box.
1426
+ connection.prepare (json:
1427
+ eg.newestGetMessagesResult (foundOldest: true , messages: messages).toJson ());
1428
+ await tester.tap (find.text ('some topic' ));
1429
+ await tester.pump (); // handle tap
1430
+ await tester.pump (); // wait for navigation
1431
+
1432
+ // Send a message and fail. Dismiss the error dialog as it pops up.
1433
+ connection.prepare (apiException: eg.apiBadRequest ());
1434
+ await tester.enterText (contentInputFinder, content);
1435
+ await tester.tap (find.byIcon (ZulipIcons .send));
1436
+ await tester.pump (Duration .zero);
1437
+ await tester.tap (find.byWidget (
1438
+ checkErrorDialog (tester, expectedTitle: 'Message not sent' )));
1439
+ await tester.pump (); // handle tap
1440
+ check (outboxMessageFinder).findsOne ();
1441
+ check (messageIsntSentErrorFinder).findsOne ();
1442
+
1443
+ // Navigate back to the message list page without a compose box,
1444
+ // where the failed to send message should still be visible.
1445
+ await tester.pageBack ();
1446
+ await tester.pump (); // handle tap
1447
+ await tester.pump (); // wait for navigation
1448
+ check (contentInputFinder).findsNothing ();
1449
+ check (outboxMessageFinder).findsOne ();
1450
+ check (messageIsntSentErrorFinder).findsOne ();
1451
+
1452
+ // Tap the failed to send message.
1453
+ // This should not remove it from the message list.
1454
+ await tester.tap (outboxMessageFinder);
1455
+ await tester.pump ();
1456
+ check (outboxMessageFinder).findsOne ();
1457
+ });
1458
+
1459
+ testWidgets ('tapping does nothing if message was successfully sent' , (tester) async {
1460
+ await setupMessageListPage (tester,
1461
+ narrow: eg.topicNarrow (stream.streamId, 'topic' ), streams: [stream],
1462
+ messages: []);
1463
+ final controller = tester.state <ComposeBoxState >(find.byType (ComposeBox )).controller;
1464
+
1465
+ // Send a message and wait until the debounce timer expires.
1466
+ connection.prepare (json: SendMessageResult (id: 1 ).toJson ());
1467
+ await tester.enterText (contentInputFinder, content);
1468
+ await tester.tap (find.byIcon (ZulipIcons .send));
1469
+ await tester.pump (Duration .zero);
1470
+ await tester.pump (kLocalEchoDebounceDuration);
1471
+ check (controller.content).text.isNotNull ().isEmpty ();
1472
+
1473
+ await tester.tap (outboxMessageFinder);
1474
+ await tester.pump ();
1475
+ check (outboxMessageFinder).findsOne ();
1476
+ check (controller.content).text.isNotNull ().isEmpty ();
1477
+ });
1478
+
1479
+ testWidgets ('tapping does nothing if message is still being sent' , (tester) async {
1480
+ await setupMessageListPage (tester,
1481
+ narrow: eg.topicNarrow (stream.streamId, 'topic' ), streams: [stream],
1482
+ messages: []);
1483
+ final controller = tester.state <ComposeBoxState >(find.byType (ComposeBox )).controller;
1484
+
1485
+ // Send a message and wait until the debounce timer expires but before
1486
+ // the message is successfully sent.
1487
+ connection.prepare (json: SendMessageResult (id: 1 ).toJson (),
1488
+ delay: kLocalEchoDebounceDuration + Duration (seconds: 1 ));
1489
+ await tester.enterText (contentInputFinder, content);
1490
+ await tester.tap (find.byIcon (ZulipIcons .send));
1491
+ await tester.pump (Duration .zero);
1492
+ await tester.pump (kLocalEchoDebounceDuration);
1493
+ check (controller.content).text.isNotNull ().isEmpty ();
1494
+
1495
+ await tester.tap (outboxMessageFinder);
1496
+ await tester.pump ();
1497
+ check (outboxMessageFinder).findsOne ();
1498
+ check (controller.content).text.isNotNull ().isEmpty ();
1499
+
1500
+ // Wait till the send request completes. The outbox message should
1501
+ // remain visible because the message event didn't arrive.
1502
+ await tester.pump (Duration (seconds: 1 ));
1503
+ check (outboxMessageFinder).findsOne ();
1504
+ check (controller.content).text.isNotNull ().isEmpty ();
1381
1505
});
1382
1506
});
1383
1507
0 commit comments