diff --git a/lib/api/route/channels.dart b/lib/api/route/channels.dart index bfa46f5ab8..3d4909b0d8 100644 --- a/lib/api/route/channels.dart +++ b/lib/api/route/channels.dart @@ -8,7 +8,10 @@ part 'channels.g.dart'; Future getStreamTopics(ApiConnection connection, { required int streamId, }) { - return connection.get('getStreamTopics', GetStreamTopicsResult.fromJson, 'users/me/$streamId/topics', {}); + final supportsEmptyTopics = connection.zulipFeatureLevel! >= 334; // TODO(server-10) + return connection.get('getStreamTopics', GetStreamTopicsResult.fromJson, 'users/me/$streamId/topics', { + if (supportsEmptyTopics) 'allow_empty_topic_name': true, + }); } @JsonSerializable(fieldRename: FieldRename.snake) diff --git a/lib/api/route/events.dart b/lib/api/route/events.dart index bbd7be5a0a..bd14521c74 100644 --- a/lib/api/route/events.dart +++ b/lib/api/route/events.dart @@ -18,6 +18,7 @@ Future registerQueue(ApiConnection connection) { 'user_avatar_url_field_optional': false, // TODO(#254): turn on 'stream_typing_notifications': true, 'user_settings_object': true, + 'empty_topic_name': true, }, }); } diff --git a/lib/api/route/messages.dart b/lib/api/route/messages.dart index be6728c790..06ebb97844 100644 --- a/lib/api/route/messages.dart +++ b/lib/api/route/messages.dart @@ -59,8 +59,10 @@ Future getMessage(ApiConnection connection, { bool? applyMarkdown, }) { assert(connection.zulipFeatureLevel! >= 120); + final supportsEmptyTopics = connection.zulipFeatureLevel! >= 334; // TODO(server-10) return connection.get('getMessage', GetMessageResult.fromJson, 'messages/$messageId', { if (applyMarkdown != null) 'apply_markdown': applyMarkdown, + if (supportsEmptyTopics) 'allow_empty_topic_name': true, }); } @@ -90,6 +92,7 @@ Future getMessages(ApiConnection connection, { bool? applyMarkdown, // bool? useFirstUnreadAnchor // omitted because deprecated }) { + final supportsEmptyTopics = connection.zulipFeatureLevel! >= 334; // TODO(server-10) return connection.get('getMessages', GetMessagesResult.fromJson, 'messages', { 'narrow': resolveDmElements(narrow, connection.zulipFeatureLevel!), 'anchor': RawParameter(anchor.toJson()), @@ -98,6 +101,7 @@ Future getMessages(ApiConnection connection, { 'num_after': numAfter, if (clientGravatar != null) 'client_gravatar': clientGravatar, if (applyMarkdown != null) 'apply_markdown': applyMarkdown, + if (supportsEmptyTopics) 'allow_empty_topic_name': true, }); } diff --git a/test/api/route/channels_test.dart b/test/api/route/channels_test.dart index 011dc508c5..eb249ffdd5 100644 --- a/test/api/route/channels_test.dart +++ b/test/api/route/channels_test.dart @@ -8,6 +8,30 @@ import '../../stdlib_checks.dart'; import '../fake_api.dart'; void main() { + test('smoke getStreamTopics', () { + return FakeApiConnection.with_((connection) async { + connection.prepare(json: GetStreamTopicsResult(topics: []).toJson()); + await getStreamTopics(connection, streamId: 1); + check(connection.takeRequests()).single.isA() + ..method.equals('GET') + ..url.path.equals('/api/v1/users/me/1/topics') + ..url.queryParameters.deepEquals({ + 'allow_empty_topic_name': 'true', + }); + }); + }); + + test('legacy: getStreamTopics when FL < 334', () { + return FakeApiConnection.with_(zulipFeatureLevel: 333, (connection) async { + connection.prepare(json: GetStreamTopicsResult(topics: []).toJson()); + await getStreamTopics(connection, streamId: 1); + check(connection.takeRequests()).single.isA() + ..method.equals('GET') + ..url.path.equals('/api/v1/users/me/1/topics') + ..url.queryParameters.deepEquals({}); + }); + }); + test('smoke updateUserTopic', () { return FakeApiConnection.with_((connection) async { connection.prepare(json: {}); diff --git a/test/api/route/messages_test.dart b/test/api/route/messages_test.dart index 4da4334bae..f914422528 100644 --- a/test/api/route/messages_test.dart +++ b/test/api/route/messages_test.dart @@ -43,6 +43,7 @@ void main() { ..url.path.equals('/api/v1/messages/$messageId') ..url.queryParameters.deepEquals({ if (applyMarkdown != null) 'apply_markdown': applyMarkdown.toString(), + 'allow_empty_topic_name': 'true', }); } return result; @@ -149,7 +150,10 @@ void main() { await checkGetMessage(connection, messageId: 1, applyMarkdown: true, - expected: {'apply_markdown': 'true'}); + expected: { + 'apply_markdown': 'true', + 'allow_empty_topic_name': 'true', + }); }); }); @@ -159,7 +163,19 @@ void main() { await checkGetMessage(connection, messageId: 1, applyMarkdown: false, - expected: {'apply_markdown': 'false'}); + expected: { + 'apply_markdown': 'false', + 'allow_empty_topic_name': 'true', + }); + }); + }); + + test('legacy: empty topic name not supported', () { + return FakeApiConnection.with_(zulipFeatureLevel: 333, (connection) async { + connection.prepare(json: fakeResult.toJson()); + await checkGetMessage(connection, + messageId: 1, + expected: {}); }); }); @@ -259,6 +275,7 @@ void main() { 'anchor': 'newest', 'num_before': '10', 'num_after': '20', + 'allow_empty_topic_name': 'true', }); }); }); @@ -292,6 +309,22 @@ void main() { 'anchor': '42', 'num_before': '10', 'num_after': '20', + 'allow_empty_topic_name': 'true', + }); + }); + }); + + test('legacy: empty topic name not supported', () { + return FakeApiConnection.with_(zulipFeatureLevel: 333, (connection) async { + connection.prepare(json: fakeResult.toJson()); + await checkGetMessages(connection, + narrow: const CombinedFeedNarrow().apiEncode(), + anchor: AnchorCode.newest, numBefore: 10, numAfter: 20, + expected: { + 'narrow': jsonEncode([]), + 'anchor': 'newest', + 'num_before': '10', + 'num_after': '20', }); }); });