@@ -469,6 +469,192 @@ void main() {
469
469
}
470
470
}
471
471
});
472
+
473
+ group ('moves' , () {
474
+ final origChannel = eg.stream ();
475
+ const origTopic = 'origTopic' ;
476
+ const newTopic = 'newTopic' ;
477
+
478
+ late List <StreamMessage > readMessages;
479
+ late List <StreamMessage > unreadMessages;
480
+
481
+ Future <void > prepareStore () async {
482
+ prepare ();
483
+ await channelStore.addStream (origChannel);
484
+ await channelStore.addSubscription (eg.subscription (origChannel));
485
+ readMessages = List <StreamMessage >.generate (10 ,
486
+ (_) => eg.streamMessage (stream: origChannel, topic: origTopic,
487
+ flags: [MessageFlag .read]));
488
+ unreadMessages = List <StreamMessage >.generate (10 ,
489
+ (_) => eg.streamMessage (stream: origChannel, topic: origTopic));
490
+ }
491
+
492
+ List <StreamMessage > copyMessagesWith (Iterable <StreamMessage > messages, {
493
+ ZulipStream ? newChannel,
494
+ String ? newTopic,
495
+ }) {
496
+ assert (newChannel != null || newTopic != null );
497
+ return messages.map ((message) => StreamMessage .fromJson (
498
+ message.toJson ()
499
+ ..['stream_id' ] = newChannel? .streamId ?? message.streamId
500
+ ..['subject' ] = newTopic ?? message.topic
501
+ )).toList ();
502
+ }
503
+
504
+ test ('moving a conversation exactly' , () async {
505
+ await prepareStore ();
506
+ final newChannel = eg.stream ();
507
+ await channelStore.addStream (newChannel);
508
+ await channelStore.addSubscription (eg.subscription (newChannel));
509
+ fillWithMessages (unreadMessages);
510
+ final originalMessageIds =
511
+ model.streams[origChannel.streamId]! [TopicName (origTopic)]! ;
512
+
513
+ model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
514
+ origMessages: unreadMessages,
515
+ newStreamId: newChannel.streamId,
516
+ newTopicStr: newTopic));
517
+ checkNotifiedOnce ();
518
+ checkMatchesMessages (copyMessagesWith (unreadMessages,
519
+ newChannel: newChannel, newTopic: newTopic));
520
+ final newMessageIds =
521
+ model.streams[newChannel.streamId]! [TopicName (newTopic)]! ;
522
+ check (originalMessageIds).identicalTo (newMessageIds);
523
+ });
524
+
525
+ test ('moving some read messages from a conversation' , () async {
526
+ await prepareStore ();
527
+ final messagesToMove = readMessages.take (2 ).toList ();
528
+ fillWithMessages (unreadMessages + readMessages);
529
+
530
+ model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
531
+ origMessages: messagesToMove,
532
+ newTopicStr: newTopic));
533
+ checkNotNotified ();
534
+ checkMatchesMessages (unreadMessages);
535
+ });
536
+
537
+ test ('moving some unread messages from a conversation' , () async {
538
+ await prepareStore ();
539
+ final messagesToMove = unreadMessages.take (2 ).toList ();
540
+ fillWithMessages (unreadMessages + readMessages);
541
+
542
+ model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
543
+ origMessages: messagesToMove,
544
+ newTopicStr: newTopic));
545
+ checkNotifiedOnce ();
546
+ checkMatchesMessages ([
547
+ ...copyMessagesWith (messagesToMove, newTopic: newTopic),
548
+ ...unreadMessages.skip (2 ),
549
+ ]);
550
+ });
551
+
552
+ test ('moving some read and unread messages from a conversation' , () async {
553
+ await prepareStore ();
554
+ final messagesToMove = [unreadMessages.first, readMessages.first];
555
+ fillWithMessages (unreadMessages + readMessages);
556
+
557
+ model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
558
+ origMessages: messagesToMove,
559
+ newTopicStr: newTopic));
560
+ checkNotifiedOnce ();
561
+ checkMatchesMessages ([
562
+ ...copyMessagesWith (unreadMessages.take (1 ), newTopic: newTopic),
563
+ ...unreadMessages.skip (1 ),
564
+ ]);
565
+ });
566
+
567
+ test ('moving some read and all unread messages from a conversation' , () async {
568
+ await prepareStore ();
569
+ final messagesToMove = unreadMessages + readMessages.take (2 ).toList ();
570
+ fillWithMessages (unreadMessages + readMessages);
571
+ final originalMessageIds =
572
+ model.streams[origChannel.streamId]! [TopicName (origTopic)]! ;
573
+
574
+ model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
575
+ origMessages: messagesToMove,
576
+ newTopicStr: newTopic));
577
+ checkNotifiedOnce ();
578
+ checkMatchesMessages ([
579
+ ...copyMessagesWith (unreadMessages, newTopic: newTopic),
580
+ ]);
581
+ final newMessageIds =
582
+ model.streams[origChannel.streamId]! [TopicName (newTopic)]! ;
583
+ check (originalMessageIds).identicalTo (newMessageIds);
584
+ });
585
+
586
+ test ('moving all read and unread messages from a conversation' , () async {
587
+ await prepareStore ();
588
+ final allMessages = unreadMessages + readMessages;
589
+ fillWithMessages (allMessages);
590
+ final originalMessageIds =
591
+ model.streams[origChannel.streamId]! [TopicName (origTopic)]! ;
592
+
593
+ model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
594
+ origMessages: allMessages,
595
+ newTopicStr: newTopic));
596
+ checkNotifiedOnce ();
597
+ checkMatchesMessages (copyMessagesWith (unreadMessages, newTopic: newTopic));
598
+ final newMessageIds =
599
+ model.streams[origChannel.streamId]! [TopicName (newTopic)]! ;
600
+ check (originalMessageIds).identicalTo (newMessageIds);
601
+ });
602
+
603
+ test ('moving to unsubscribed channels drops the unreads' , () async {
604
+ await prepareStore ();
605
+ final unsubscribedChannel = eg.stream ();
606
+ await channelStore.addStream (unsubscribedChannel);
607
+ assert (! channelStore.subscriptions.containsKey (
608
+ unsubscribedChannel.streamId));
609
+ fillWithMessages (unreadMessages);
610
+
611
+ model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
612
+ origMessages: unreadMessages,
613
+ newStreamId: unsubscribedChannel.streamId));
614
+ checkNotifiedOnce ();
615
+ checkMatchesMessages ([]);
616
+ });
617
+
618
+ test ('tolerates unsorted messages' , () async {
619
+ await prepareStore ();
620
+ final unreadMessages = List .generate (10 , (i) =>
621
+ eg.streamMessage (
622
+ id: 1000 - i, stream: origChannel, topic: origTopic));
623
+ fillWithMessages (unreadMessages);
624
+
625
+ model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
626
+ origMessages: unreadMessages,
627
+ newTopicStr: newTopic));
628
+ checkNotifiedOnce ();
629
+ checkMatchesMessages (copyMessagesWith (unreadMessages, newTopic: newTopic));
630
+ });
631
+
632
+ test ('tolerates unreads unknown to the model' , () async {
633
+ await prepareStore ();
634
+ fillWithMessages (unreadMessages);
635
+
636
+ final unknownChannel = eg.stream ();
637
+ assert (! channelStore.streams.containsKey (unknownChannel.streamId));
638
+ final unknownUnreadMessage = eg.streamMessage (
639
+ stream: unknownChannel, topic: origTopic);
640
+
641
+ model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
642
+ origMessages: [unknownUnreadMessage],
643
+ newTopicStr: newTopic));
644
+ checkNotNotified ();
645
+ checkMatchesMessages (unreadMessages);
646
+ });
647
+
648
+ test ('message edit but no move' , () async {
649
+ await prepareStore ();
650
+ fillWithMessages (unreadMessages);
651
+
652
+ model.handleUpdateMessageEvent (eg.updateMessageEditEvent (
653
+ unreadMessages.first));
654
+ checkNotNotified ();
655
+ checkMatchesMessages (unreadMessages);
656
+ });
657
+ });
472
658
});
473
659
474
660
0 commit comments