@@ -469,6 +469,145 @@ void main() {
469469        }
470470      }
471471    });
472+ 
473+     group ('moves' , () {
474+       final  origChannel =  eg.stream ();
475+       const  origTopic =  'origTopic' ;
476+       const  newTopic =  'newTopic' ;
477+ 
478+       final  readMessages =  List <StreamMessage >.generate (10 ,
479+         (_) =>  eg.streamMessage (
480+           stream:  origChannel, topic:  origTopic, flags:  [MessageFlag .read]));
481+       final  unreadMessages =  List <StreamMessage >.generate (10 ,
482+         (_) =>  eg.streamMessage (stream:  origChannel, topic:  origTopic));
483+ 
484+       Future <void > prepareStore () async  {
485+         prepare ();
486+         await  channelStore.addStream (origChannel);
487+         await  channelStore.addSubscription (eg.subscription (origChannel));
488+       }
489+ 
490+       List <StreamMessage > copyMessagesWith (Iterable <StreamMessage > messages, {
491+         ZulipStream ?  newChannel,
492+         String ?  newTopic,
493+       }) {
494+         assert (newChannel !=  null  ||  newTopic !=  null );
495+         return  messages.map ((message) =>  StreamMessage .fromJson (
496+           message.toJson ()
497+             ..['stream_id' ] =  newChannel? .streamId ??  message.streamId
498+             ..['subject' ] =  newTopic ??  message.topic
499+         )).toList ();
500+       }
501+ 
502+       test ('smoke' , () async  {
503+         await  prepareStore ();
504+         final  newChannel =  eg.stream ();
505+         await  channelStore.addStream (newChannel);
506+         await  channelStore.addSubscription (eg.subscription (newChannel));
507+         fillWithMessages (unreadMessages);
508+ 
509+         model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
510+           origMessages:  unreadMessages,
511+           newStreamId:  newChannel.streamId,
512+           newTopicStr:  newTopic));
513+         checkNotifiedOnce ();
514+         checkMatchesMessages (copyMessagesWith (unreadMessages,
515+           newChannel:  newChannel, newTopic:  newTopic));
516+       });
517+ 
518+       test ('moving some read and unread messages from a conversation' , () async  {
519+         await  prepareStore ();
520+         final  messagesToMove =  [unreadMessages.first, readMessages.first];
521+         fillWithMessages (unreadMessages +  readMessages);
522+ 
523+         model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
524+           origMessages:  messagesToMove,
525+           newTopicStr:  newTopic));
526+         checkNotifiedOnce ();
527+         checkMatchesMessages ([
528+           ...copyMessagesWith (unreadMessages.take (1 ), newTopic:  newTopic),
529+           ...unreadMessages.skip (1 ),
530+         ]);
531+       });
532+ 
533+       test ('moving all read and unread messages from a conversation' , () async  {
534+         await  prepareStore ();
535+         final  allMessages =  unreadMessages +  readMessages;
536+         fillWithMessages (allMessages);
537+ 
538+         model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
539+           origMessages:  allMessages,
540+           newTopicStr:  newTopic));
541+         checkNotifiedOnce ();
542+         checkMatchesMessages (copyMessagesWith (unreadMessages, newTopic:  newTopic));
543+       });
544+ 
545+       test ('moving to unsubscribed channels drops the unreads' , () async  {
546+         await  prepareStore ();
547+         final  unsubscribedChannel =  eg.stream ();
548+         await  channelStore.addStream (unsubscribedChannel);
549+         assert (! channelStore.subscriptions.containsKey (
550+           unsubscribedChannel.streamId));
551+         fillWithMessages (unreadMessages);
552+ 
553+         model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
554+           origMessages:  unreadMessages,
555+           newStreamId:  unsubscribedChannel.streamId));
556+         checkNotifiedOnce ();
557+         checkMatchesMessages ([]);
558+       });
559+ 
560+       test ('tolerates unsorted messages' , () async  {
561+         await  prepareStore ();
562+         final  unreadMessages =  List .generate (10 , (i) => 
563+           eg.streamMessage (
564+             id:  1000  -  i, stream:  origChannel, topic:  origTopic));
565+         fillWithMessages (unreadMessages);
566+ 
567+         model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
568+           origMessages:  unreadMessages,
569+           newTopicStr:  newTopic));
570+         checkNotifiedOnce ();
571+         checkMatchesMessages (copyMessagesWith (unreadMessages, newTopic:  newTopic));
572+       });
573+ 
574+       test ('tolerates unreads unknown to the model' , () async  {
575+         await  prepareStore ();
576+         fillWithMessages (unreadMessages);
577+ 
578+         final  unknownChannel =  eg.stream ();
579+         assert (! channelStore.streams.containsKey (unknownChannel.streamId));
580+         final  unknownUnreadMessage =  eg.streamMessage (
581+           stream:  unknownChannel, topic:  origTopic);
582+ 
583+         model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
584+           origMessages:  [unknownUnreadMessage],
585+           newTopicStr:  newTopic));
586+         checkNotNotified ();
587+         checkMatchesMessages (unreadMessages);
588+       });
589+ 
590+       test ('moving read messages has no effect' , () async  {
591+         await  prepareStore ();
592+         fillWithMessages (unreadMessages +  readMessages);
593+ 
594+         model.handleUpdateMessageEvent (eg.updateMessageEventMoveFrom (
595+           origMessages:  readMessages,
596+           newTopicStr:  newTopic));
597+         checkNotNotified ();
598+         checkMatchesMessages (unreadMessages);
599+       });
600+ 
601+       test ('message edit but no move' , () async  {
602+         await  prepareStore ();
603+         fillWithMessages (unreadMessages);
604+ 
605+         model.handleUpdateMessageEvent (eg.updateMessageEditEvent (
606+           unreadMessages.first));
607+         checkNotNotified ();
608+         checkMatchesMessages (unreadMessages);
609+       });
610+     });
472611  });
473612
474613
0 commit comments