@@ -6812,6 +6812,178 @@ void main() {
68126812 },
68136813 );
68146814
6815+ test (
6816+ 'should reset unread count on notification mark read event' ,
6817+ () async {
6818+ final currentUser = client.state.currentUser! ;
6819+ final currentRead = Read (
6820+ user: currentUser,
6821+ lastRead: DateTime (2020 ),
6822+ unreadMessages: 10 ,
6823+ );
6824+
6825+ // Setup initial read state
6826+ channel.state? .updateChannelState (
6827+ channel.state! .channelState.copyWith (
6828+ read: [currentRead],
6829+ ),
6830+ );
6831+
6832+ when (
6833+ () => client.channelDeliveryReporter.reconcileDelivery ([channel]),
6834+ ).thenAnswer ((_) => Future .value ());
6835+
6836+ // Verify initial state
6837+ expect (channel.state? .unreadCount, 10 );
6838+
6839+ // notification.mark_read is delivered on the reading user's own
6840+ // connection, so it reaches non-watched channels as well.
6841+ client.addEvent (
6842+ Event (
6843+ cid: channel.cid,
6844+ type: EventType .notificationMarkRead,
6845+ user: currentUser,
6846+ createdAt: DateTime (2022 ),
6847+ lastReadMessageId: 'message-123' ,
6848+ ),
6849+ );
6850+
6851+ // Wait for event to be processed
6852+ await Future .delayed (Duration .zero);
6853+
6854+ // Verify read state is updated
6855+ final updatedRead = channel.state? .read.first;
6856+ expect (updatedRead? .user.id, currentUser.id);
6857+ expect (channel.state? .unreadCount, 0 );
6858+ expect (updatedRead? .lastReadMessageId, 'message-123' );
6859+ expect (
6860+ updatedRead? .lastRead.isAtSameMomentAs (DateTime (2022 )),
6861+ isTrue,
6862+ );
6863+ },
6864+ );
6865+
6866+ test (
6867+ 'should preserve delivery info on notification mark read event' ,
6868+ () async {
6869+ final currentUser = User (id: 'test-user' );
6870+ final currentRead = Read (
6871+ user: currentUser,
6872+ lastRead: DateTime (2020 ),
6873+ unreadMessages: 10 ,
6874+ lastDeliveredAt: DateTime (2021 ),
6875+ lastDeliveredMessageId: 'delivered-msg-456' ,
6876+ );
6877+
6878+ // Setup initial read state
6879+ channel.state? .updateChannelState (
6880+ channel.state! .channelState.copyWith (
6881+ read: [currentRead],
6882+ ),
6883+ );
6884+
6885+ client.addEvent (
6886+ Event (
6887+ cid: channel.cid,
6888+ type: EventType .notificationMarkRead,
6889+ user: currentUser,
6890+ createdAt: DateTime (2022 ),
6891+ lastReadMessageId: 'message-123' ,
6892+ ),
6893+ );
6894+
6895+ // Wait for event to be processed
6896+ await Future .delayed (Duration .zero);
6897+
6898+ // Verify read state is updated but delivery info is preserved
6899+ final updatedRead = channel.state? .read.first;
6900+ expect (updatedRead? .unreadMessages, 0 );
6901+ expect (
6902+ updatedRead? .lastDeliveredAt? .isAtSameMomentAs (DateTime (2021 )),
6903+ isTrue,
6904+ );
6905+ expect (updatedRead? .lastDeliveredMessageId, 'delivered-msg-456' );
6906+ },
6907+ );
6908+
6909+ test (
6910+ 'should not update channel read state on thread notification mark '
6911+ 'read event' ,
6912+ () async {
6913+ final currentUser = User (id: 'test-user' );
6914+ final currentRead = Read (
6915+ user: currentUser,
6916+ lastRead: DateTime (2020 ),
6917+ unreadMessages: 10 ,
6918+ lastReadMessageId: 'channel-msg-1' ,
6919+ );
6920+
6921+ // Setup initial read state
6922+ channel.state? .updateChannelState (
6923+ channel.state! .channelState.copyWith (
6924+ read: [currentRead],
6925+ ),
6926+ );
6927+
6928+ client.addEvent (
6929+ Event (
6930+ cid: channel.cid,
6931+ type: EventType .notificationMarkRead,
6932+ user: currentUser,
6933+ createdAt: DateTime (2022 ),
6934+ lastReadMessageId: 'thread-reply-99' ,
6935+ thread: Thread (
6936+ channelCid: channel.cid! ,
6937+ parentMessageId: 'parent-msg-1' ,
6938+ createdByUserId: currentUser.id,
6939+ replyCount: 3 ,
6940+ participantCount: 2 ,
6941+ ),
6942+ ),
6943+ );
6944+
6945+ // Wait for event to be processed
6946+ await Future .delayed (Duration .zero);
6947+
6948+ // Channel read state must be untouched — thread reads
6949+ // must not clobber the channel-level Read.
6950+ final after = channel.state? .read.first;
6951+ expect (after? .unreadMessages, 10 );
6952+ expect (after? .lastReadMessageId, 'channel-msg-1' );
6953+ expect (after? .lastRead.isAtSameMomentAs (DateTime (2020 )), isTrue);
6954+ },
6955+ );
6956+
6957+ test (
6958+ 'should reconcile delivery when notification mark read event is from '
6959+ 'current user' ,
6960+ () async {
6961+ final currentUser = client.state.currentUser;
6962+
6963+ when (
6964+ () => client.channelDeliveryReporter.reconcileDelivery ([channel]),
6965+ ).thenAnswer ((_) => Future .value ());
6966+
6967+ client.addEvent (
6968+ Event (
6969+ cid: channel.cid,
6970+ type: EventType .notificationMarkRead,
6971+ user: currentUser,
6972+ createdAt: DateTime (2022 ),
6973+ lastReadMessageId: 'message-123' ,
6974+ ),
6975+ );
6976+
6977+ // Wait for event to be processed
6978+ await Future .delayed (Duration .zero);
6979+
6980+ // Verify reconcileDelivery was called
6981+ verify (
6982+ () => client.channelDeliveryReporter.reconcileDelivery ([channel]),
6983+ ).called (1 );
6984+ },
6985+ );
6986+
68156987 test ('should update read state on message delivered event' , () async {
68166988 final currentUser = User (id: 'test-user' );
68176989 final distantPast = DateTime .fromMillisecondsSinceEpoch (0 , isUtc: true );
0 commit comments