Skip to content

Commit 1e7eabc

Browse files
committed
internal_link: Add generic support for is operators.
This is also a functionality change. Previously, `is` elements with operands other than `mentioned` are ignored when parsing internal links. When the remaining elements combined are recognized, some non-null narrows can be returned. Now `is` elements are never ignored, to avoid such false positives. Signed-off-by: Zixuan James Li <[email protected]>
1 parent 28702f9 commit 1e7eabc

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

lib/model/internal_link.dart

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
152152
ApiNarrowStream? streamElement;
153153
ApiNarrowTopic? topicElement;
154154
ApiNarrowDm? dmElement;
155-
ApiNarrowIs? isMentionedElement;
155+
Set<IsOperand> isElementOperands = {};
156156

157157
for (var i = 0; i < segments.length; i += 2) {
158158
final (operator, negated) = _parseOperator(segments[i]);
@@ -181,8 +181,9 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
181181
dmElement = ApiNarrowDm(dmIds, negated: negated);
182182

183183
case _NarrowOperator.is_:
184-
if (isMentionedElement != null) return null;
185-
if (operand == 'mentioned') isMentionedElement = ApiNarrowIs(IsOperand.mentioned);
184+
final isElementOperand = IsOperand.fromRawString(operand);
185+
if (isElementOperands.contains(isElementOperand)) return null;
186+
isElementOperands.add(isElementOperand);
186187

187188
case _NarrowOperator.near: // TODO(#82): support for near
188189
case _NarrowOperator.with_: // TODO(#683): support for with
@@ -193,9 +194,22 @@ Narrow? _interpretNarrowSegments(List<String> segments, PerAccountStore store) {
193194
}
194195
}
195196

196-
if (isMentionedElement != null) {
197+
if (isElementOperands.isNotEmpty) {
197198
if (streamElement != null || topicElement != null || dmElement != null) return null;
198-
return const MentionsNarrow();
199+
switch (isElementOperands.singleOrNull) {
200+
case IsOperand.mentioned:
201+
return const MentionsNarrow();
202+
case null:
203+
case IsOperand.dm:
204+
case IsOperand.private:
205+
case IsOperand.alerted:
206+
case IsOperand.starred:
207+
case IsOperand.followed:
208+
case IsOperand.resolved:
209+
case IsOperand.unread:
210+
case IsOperand.unknown:
211+
return null;
212+
}
199213
} else if (dmElement != null) {
200214
if (streamElement != null || topicElement != null) return null;
201215
return DmNarrow.withUsers(dmElement.operand, selfUserId: store.selfUserId);

test/model/internal_link_test.dart

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -221,18 +221,38 @@ void main() {
221221
testExpectedNarrows(testCases, streams: streams);
222222
});
223223

224-
group('"/#narrow/is/mentioned returns expected MentionsNarrow', () {
225-
final testCases = [
226-
('/#narrow/is/mentioned', const MentionsNarrow()),
227-
('/#narrow/is/mentioned/near/1', const MentionsNarrow()),
228-
('/#narrow/is/mentioned/with/2', const MentionsNarrow()),
229-
('/#narrow/channel/7-test-here/is/mentioned', null),
230-
('/#narrow/channel/check/topic/test/is/mentioned', null),
231-
('/#narrow/topic/test/is/mentioned', null),
232-
('/#narrow/dm/17327-Chris-Bobbe-(Test-Account)/is/mentioned', null),
233-
('/#narrow/-is/mentioned', null),
234-
];
235-
testExpectedNarrows(testCases, streams: streams);
224+
group('/#narrow/is/<...> returns corresponding narrow', () {
225+
// For these tests, we are more interested in the internal links
226+
// containing a single effective `is` operator.
227+
// Internal links with multiple operators should be tested separately.
228+
for (final operand in IsOperand.values) {
229+
List<(String, Narrow?)> sharedCases(Narrow? narrow) => [
230+
('/#narrow/is/$operand', narrow),
231+
('/#narrow/is/$operand/near/1', narrow),
232+
('/#narrow/is/$operand/with/2', narrow),
233+
('/#narrow/channel/7-test-here/is/$operand', null),
234+
('/#narrow/channel/check/topic/test/is/$operand', null),
235+
('/#narrow/topic/test/is/$operand', null),
236+
('/#narrow/dm/17327-Chris-Bobbe-(Test-Account)/is/$operand', null),
237+
('/#narrow/-is/$operand', null),
238+
];
239+
final List<(String, Narrow?)> testCases;
240+
switch (operand) {
241+
case IsOperand.mentioned:
242+
testCases = sharedCases(const MentionsNarrow());
243+
case IsOperand.dm:
244+
case IsOperand.private:
245+
case IsOperand.alerted:
246+
case IsOperand.starred:
247+
case IsOperand.followed:
248+
case IsOperand.resolved:
249+
case IsOperand.unread:
250+
case IsOperand.unknown:
251+
// Unsupported operands should not return any narrow.
252+
testCases = sharedCases(null);
253+
}
254+
testExpectedNarrows(testCases, streams: streams);
255+
}
236256
});
237257

238258
group('unexpected link shapes are rejected', () {

0 commit comments

Comments
 (0)