1
+ import 'dart:convert' ;
2
+
1
3
import 'package:checks/checks.dart' ;
2
4
import 'package:flutter/material.dart' ;
3
5
import 'package:flutter/services.dart' ;
@@ -7,8 +9,10 @@ import 'package:http/http.dart' as http;
7
9
import 'package:zulip/api/model/model.dart' ;
8
10
import 'package:zulip/api/route/messages.dart' ;
9
11
import 'package:zulip/model/compose.dart' ;
12
+ import 'package:zulip/model/localizations.dart' ;
10
13
import 'package:zulip/model/narrow.dart' ;
11
14
import 'package:zulip/model/store.dart' ;
15
+ import 'package:zulip/widgets/action_sheet.dart' ;
12
16
import 'package:zulip/widgets/compose_box.dart' ;
13
17
import 'package:zulip/widgets/content.dart' ;
14
18
import 'package:zulip/widgets/message_list.dart' ;
@@ -386,4 +390,97 @@ void main() {
386
390
check (await Clipboard .getData ('text/plain' )).isNull ();
387
391
});
388
392
});
393
+
394
+ group ('StarButton' , () {
395
+ Future <void > tapButton (WidgetTester tester) async {
396
+ // Locating button by the icon (as other tests here do) is complicated
397
+ // by the fact that starred messages are decorated with the same icon.
398
+ // Selecting by button class instead here:
399
+ await tester.ensureVisible (find.byType (StarButton , skipOffstage: false ));
400
+ await tester.tap (find.byType (StarButton ));
401
+ await tester.pump (); // [MenuItemButton.onPressed] called in a post-frame callback: flutter/flutter@e4a39fa2e
402
+ }
403
+
404
+ testWidgets ('star success' , (WidgetTester tester) async {
405
+ final message = eg.streamMessage (flags: []);
406
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
407
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
408
+
409
+ final connection = store.connection as FakeApiConnection ;
410
+ connection.prepare (json: {});
411
+ await tapButton (tester);
412
+ await tester.pump (Duration .zero);
413
+
414
+ check (connection.lastRequest).isA< http.Request > ()
415
+ ..method.equals ('POST' )
416
+ ..url.path.equals ('/api/v1/messages/flags' )
417
+ ..bodyFields.deepEquals ({
418
+ 'messages' : jsonEncode ([message.id]),
419
+ 'op' : 'add' ,
420
+ 'flag' : 'starred' ,
421
+ });
422
+ });
423
+
424
+ testWidgets ('unstar success' , (WidgetTester tester) async {
425
+ final message = eg.streamMessage (flags: [MessageFlag .starred]);
426
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
427
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
428
+
429
+ final connection = store.connection as FakeApiConnection ;
430
+ connection.prepare (json: {});
431
+ await tapButton (tester);
432
+ await tester.pump (Duration .zero);
433
+
434
+ check (connection.lastRequest).isA< http.Request > ()
435
+ ..method.equals ('POST' )
436
+ ..url.path.equals ('/api/v1/messages/flags' )
437
+ ..bodyFields.deepEquals ({
438
+ 'messages' : jsonEncode ([message.id]),
439
+ 'op' : 'remove' ,
440
+ 'flag' : 'starred' ,
441
+ });
442
+ });
443
+
444
+ testWidgets ('star request has an error' , (WidgetTester tester) async {
445
+ final message = eg.streamMessage (flags: []);
446
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
447
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
448
+ final zulipLocalizations = GlobalLocalizations .zulipLocalizations;
449
+
450
+ final connection = store.connection as FakeApiConnection ;
451
+
452
+ connection.prepare (httpStatus: 400 , json: {
453
+ 'code' : 'BAD_REQUEST' ,
454
+ 'msg' : 'Invalid message(s)' ,
455
+ 'result' : 'error' ,
456
+ });
457
+ await tapButton (tester);
458
+ await tester.pump (Duration .zero); // error arrives; error dialog shows
459
+
460
+ await tester.tap (find.byWidget (checkErrorDialog (tester,
461
+ expectedTitle: zulipLocalizations.errorStarMessageFailedTitle,
462
+ expectedMessage: 'Invalid message(s)' )));
463
+ });
464
+
465
+ testWidgets ('unstar request has an error' , (WidgetTester tester) async {
466
+ final message = eg.streamMessage (flags: [MessageFlag .starred]);
467
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
468
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
469
+ final zulipLocalizations = GlobalLocalizations .zulipLocalizations;
470
+
471
+ final connection = store.connection as FakeApiConnection ;
472
+
473
+ connection.prepare (httpStatus: 400 , json: {
474
+ 'code' : 'BAD_REQUEST' ,
475
+ 'msg' : 'Invalid message(s)' ,
476
+ 'result' : 'error' ,
477
+ });
478
+ await tapButton (tester);
479
+ await tester.pump (Duration .zero); // error arrives; error dialog shows
480
+
481
+ await tester.tap (find.byWidget (checkErrorDialog (tester,
482
+ expectedTitle: zulipLocalizations.errorUnstarMessageFailedTitle,
483
+ expectedMessage: 'Invalid message(s)' )));
484
+ });
485
+ });
389
486
}
0 commit comments