diff --git a/lib/model/internal_link.dart b/lib/model/internal_link.dart index 7276225603..18c8e3affb 100644 --- a/lib/model/internal_link.dart +++ b/lib/model/internal_link.dart @@ -159,6 +159,7 @@ Narrow? _interpretNarrowSegments(List segments, PerAccountStore store) { final operand = segments[i + 1]; switch (operator) { case _NarrowOperator.stream: + case _NarrowOperator.channel: if (streamElement != null) return null; final streamId = _parseStreamOperand(operand, store); if (streamId == null) return null; @@ -207,6 +208,7 @@ enum _NarrowOperator { near, pmWith, stream, + channel, subject, topic, unknown; diff --git a/lib/model/internal_link.g.dart b/lib/model/internal_link.g.dart index 7a6952c5d5..c86b712e1b 100644 --- a/lib/model/internal_link.g.dart +++ b/lib/model/internal_link.g.dart @@ -13,6 +13,7 @@ const _$_NarrowOperatorEnumMap = { _NarrowOperator.near: 'near', _NarrowOperator.pmWith: 'pm-with', _NarrowOperator.stream: 'stream', + _NarrowOperator.channel: 'channel', _NarrowOperator.subject: 'subject', _NarrowOperator.topic: 'topic', _NarrowOperator.unknown: 'unknown', diff --git a/test/model/internal_link_test.dart b/test/model/internal_link_test.dart index 4b4a4b625e..eac8a8d023 100644 --- a/test/model/internal_link_test.dart +++ b/test/model/internal_link_test.dart @@ -9,6 +9,13 @@ import 'package:zulip/model/store.dart'; import '../example_data.dart' as eg; import 'test_store.dart'; +// Using Set instead of List in to avoid any duplicated test urls. +Set getUrlSyntaxVariants(String urlString) { + final urlWithChannelSyntax = urlString.replaceFirst('#narrow/stream', '#narrow/channel'); + final urlWithStreamSyntax = urlString.replaceFirst('#narrow/channel', '#narrow/stream'); + return {urlWithStreamSyntax, urlWithChannelSyntax}; +} + Future setupStore({ required Uri realmUrl, List? streams, @@ -36,12 +43,14 @@ void main() { assert(streams != null || users != null); for (final testCase in testCases) { final String urlString = testCase.$1; - final Narrow? expected = testCase.$2; - test(urlString, () async { - final store = await setupStore(realmUrl: realmUrl, streams: streams, users: users); - final url = store.tryResolveUrl(urlString)!; - check(parseInternalLink(url, store)).equals(expected); - }); + for (final urlString in getUrlSyntaxVariants(urlString)) { + final Narrow? expected = testCase.$2; + test(urlString, () async { + final store = await setupStore(realmUrl: realmUrl, streams: streams, users: users); + final url = store.tryResolveUrl(urlString)!; + check(parseInternalLink(url, store)).equals(expected); + }); + } } } @@ -131,12 +140,14 @@ void main() { final String description = testCase.$2; final String urlString = testCase.$3; final Uri realmUrl = testCase.$4; - test('${expected ? 'accepts': 'rejects'} $description: $urlString', () async { - final store = await setupStore(realmUrl: realmUrl, streams: streams); - final url = store.tryResolveUrl(urlString)!; - final result = parseInternalLink(url, store); - check(result != null).equals(expected); - }); + for (final urlString in getUrlSyntaxVariants(urlString)) { + test('${expected ? 'accepts': 'rejects'} $description: $urlString', () async { + final store = await setupStore(realmUrl: realmUrl, streams: streams); + final url = store.tryResolveUrl(urlString)!; + final result = parseInternalLink(url, store); + check(result != null).equals(expected); + }); + } } }); @@ -169,6 +180,18 @@ void main() { testExpectedNarrows(testCases, streams: streams); }); + group('Both `stream` and `channel` can be used interchangeably', () { + const testCases = [ + ('/#narrow/stream/check', StreamNarrow(1)), + ('/#narrow/channel/check', StreamNarrow(1)), + ('/#narrow/stream/check/topic/test', TopicNarrow(1, 'test')), + ('/#narrow/channel/check/topic/test', TopicNarrow(1, 'test')), + ('/#narrow/stream/check/topic/test/near/378333', TopicNarrow(1, 'test')), + ('/#narrow/channel/check/topic/test/near/378333', TopicNarrow(1, 'test')), + ]; + testExpectedNarrows(testCases, streams: streams); + }); + group('"/#narrow/dm/<...>" returns expected DmNarrow', () { final expectedNarrow = DmNarrow.withUsers([1, 2], selfUserId: eg.selfUser.userId);