Skip to content

Commit 6d9f22d

Browse files
committed
api: Add markAllAsRead, markStreamAsRead, and markTopicAsRead routes
1 parent 681a744 commit 6d9f22d

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

lib/api/route/messages.dart

+60
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,63 @@ class UpdateMessageFlagsForNarrowResult {
373373

374374
Map<String, dynamic> toJson() => _$UpdateMessageFlagsForNarrowResultToJson(this);
375375
}
376+
377+
/// https://zulip.com/api/mark-all-as-read
378+
///
379+
/// This binding is deprecated, in FL 155+ use
380+
/// [updateMessageFlagsForNarrow] instead.
381+
// TODO(server-6): Remove as deprecated by updateMessageFlagsForNarrow
382+
//
383+
// For FL < 153 this call was atomic on the server and would
384+
// not mark any messages as read if it timed out.
385+
// From FL 153 and onward the server started processing
386+
// in batches so progress could still be made in the event
387+
// of a timeout interruption. Thus, in FL 153 this call
388+
// started returning `result: partially_completed` and
389+
// `code: REQUEST_TIMEOUT` for timeouts.
390+
//
391+
// In FL 211 the `partially_completed` variant of
392+
// `result` was removed, the string `code` field also
393+
// removed, and a boolean `complete` field introduced.
394+
//
395+
// For full support of this endpoint we would need three
396+
// variants of the return structure based on feature
397+
// level (`{}`, `{code: string}`, and `{complete: bool}`)
398+
// as well as handling of `partially_completed` variant
399+
// of `result` in `lib/api/core.dart`. For simplicity we
400+
// ignore these return values.
401+
//
402+
// We don't use this method for FL 155+ (it is replaced
403+
// by `updateMessageFlagsForNarrow`) so there are only
404+
// two versions (FL 153 and FL 154) affected.
405+
Future<void> markAllAsRead(ApiConnection connection) {
406+
return connection.post('markAllAsRead', (_) {}, 'mark_all_as_read', {});
407+
}
408+
409+
/// https://zulip.com/api/mark-stream-as-read
410+
///
411+
/// This binding is deprecated, in FL 155+ use
412+
/// [updateMessageFlagsForNarrow] instead.
413+
// TODO(server-6): Remove as deprecated by updateMessageFlagsForNarrow
414+
Future<void> markStreamAsRead(ApiConnection connection, {
415+
required int streamId,
416+
}) {
417+
return connection.post('markStreamAsRead', (_) {}, 'mark_stream_as_read', {
418+
'stream_id': streamId,
419+
});
420+
}
421+
422+
/// https://zulip.com/api/mark-topic-as-read
423+
///
424+
/// This binding is deprecated, in FL 155+ use
425+
/// [updateMessageFlagsForNarrow] instead.
426+
// TODO(server-6): Remove as deprecated by updateMessageFlagsForNarrow
427+
Future<void> markTopicAsRead(ApiConnection connection, {
428+
required int streamId,
429+
required String topicName,
430+
}) {
431+
return connection.post('markTopicAsRead', (_) {}, 'mark_topic_as_read', {
432+
'stream_id': streamId,
433+
'topic_name': RawParameter(topicName),
434+
});
435+
}

test/api/route/messages_test.dart

+72
Original file line numberDiff line numberDiff line change
@@ -571,4 +571,76 @@ void main() {
571571
});
572572
});
573573
});
574+
575+
group('markAllAsRead', () {
576+
Future<void> checkMarkAllAsRead(
577+
FakeApiConnection connection, {
578+
required Map<String, String> expected,
579+
}) async {
580+
connection.prepare(json: {});
581+
await markAllAsRead(connection);
582+
check(connection.lastRequest).isA<http.Request>()
583+
..method.equals('POST')
584+
..url.path.equals('/api/v1/mark_all_as_read')
585+
..bodyFields.deepEquals(expected);
586+
}
587+
588+
test('smoke', () {
589+
return FakeApiConnection.with_((connection) async {
590+
await checkMarkAllAsRead(connection, expected: {});
591+
});
592+
});
593+
});
594+
595+
group('markStreamAsRead', () {
596+
Future<void> checkMarkStreamAsRead(
597+
FakeApiConnection connection, {
598+
required int streamId,
599+
required Map<String, String> expected,
600+
}) async {
601+
connection.prepare(json: {});
602+
await markStreamAsRead(connection, streamId: streamId);
603+
check(connection.lastRequest).isA<http.Request>()
604+
..method.equals('POST')
605+
..url.path.equals('/api/v1/mark_stream_as_read')
606+
..bodyFields.deepEquals(expected);
607+
}
608+
609+
test('smoke', () {
610+
return FakeApiConnection.with_((connection) async {
611+
await checkMarkStreamAsRead(connection,
612+
streamId: 10,
613+
expected: {'stream_id': '10'});
614+
});
615+
});
616+
});
617+
618+
group('markTopicAsRead', () {
619+
Future<void> checkMarkTopicAsRead(
620+
FakeApiConnection connection, {
621+
required int streamId,
622+
required String topicName,
623+
required Map<String, String> expected,
624+
}) async {
625+
connection.prepare(json: {});
626+
await markTopicAsRead(connection,
627+
streamId: streamId, topicName: topicName);
628+
check(connection.lastRequest).isA<http.Request>()
629+
..method.equals('POST')
630+
..url.path.equals('/api/v1/mark_topic_as_read')
631+
..bodyFields.deepEquals(expected);
632+
}
633+
634+
test('smoke', () {
635+
return FakeApiConnection.with_((connection) async {
636+
await checkMarkTopicAsRead(connection,
637+
streamId: 10,
638+
topicName: 'topic',
639+
expected: {
640+
'stream_id': '10',
641+
'topic_name': 'topic',
642+
});
643+
});
644+
});
645+
});
574646
}

0 commit comments

Comments
 (0)