Skip to content

Commit 761c24b

Browse files
chrisbobbegnprice
authored andcommitted
internalLinks [nfc]: Bring an isNarrowLink check out to caller
Also rename the function and add a note in the jsdoc, to make it clear that it's meant to operate on "narrow links", i.e., those that isNarrowLink gives `true` for. While we're at it, write the rest of the jsdoc.
1 parent cdf4a9a commit 761c24b

File tree

3 files changed

+32
-22
lines changed

3 files changed

+32
-22
lines changed

src/message/messagesActions.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import * as logging from '../utils/logging';
33
import * as NavigationService from '../nav/NavigationService';
44
import type { GetText, Message, Narrow, ThunkAction } from '../types';
55
import { getAuth, getRealm, getMessages, getZulipFeatureLevel } from '../selectors';
6-
import { getNearOperandFromLink, getNarrowFromLink } from '../utils/internalLinks';
6+
import {
7+
getNearOperandFromLink,
8+
getNarrowFromNarrowLink,
9+
isNarrowLink,
10+
} from '../utils/internalLinks';
711
import { openLinkWithUserPreference } from '../utils/openLink';
812
import { navigateToChat } from '../nav/navActions';
913
import { FIRST_UNREAD_ANCHOR } from '../anchor';
@@ -232,7 +236,9 @@ export const messageLinkPress =
232236
return;
233237
}
234238

235-
const narrow = getNarrowFromLink(parsedUrl, auth.realm, streamsById, streamsByName, ownUserId);
239+
const narrow = isNarrowLink(parsedUrl, auth.realm)
240+
? getNarrowFromNarrowLink(parsedUrl, auth.realm, streamsById, streamsByName, ownUserId)
241+
: null;
236242

237243
if (narrow) {
238244
// This call is OK: `narrow` is truthy, so isNarrowLink(…) was true.

src/utils/__tests__/internalLinks-test.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
} from '../narrow';
1919
import {
2020
isNarrowLink,
21-
getNarrowFromLink,
21+
getNarrowFromNarrowLink,
2222
getNearOperandFromLink,
2323
decodeHashComponent,
2424
} from '../internalLinks';
@@ -131,8 +131,8 @@ describe('isNarrowLink', () => {
131131
}
132132
});
133133

134-
// TODO: Combine / dedupe with "getNarrowFromLink (part 2)" tests, below
135-
describe('getNarrowFromLink (part 1)', () => {
134+
// TODO: Combine / dedupe with "getNarrowFromNarrowLink (part 2)" tests, below
135+
describe('getNarrowFromNarrowLink (part 1)', () => {
136136
const mkCheck = (narrowExpectation: (Narrow => boolean) | null) => hash => {
137137
const streams = [
138138
eg.makeStream({ name: 'jest' }),
@@ -141,7 +141,7 @@ describe('getNarrowFromLink (part 1)', () => {
141141
eg.makeStream({ name: 'mobile' }),
142142
];
143143
const baseState = eg.reduxStatePlus({ streams });
144-
const narrow = getNarrowFromLink(
144+
const narrow = getNarrowFromNarrowLink(
145145
new URL(hash, realm),
146146
realm,
147147
getStreamsById(baseState),
@@ -232,26 +232,22 @@ describe('decodeHashComponent', () => {
232232
});
233233
});
234234

235-
// TODO: Combine / dedupe with "getNarrowFromLink (part 1)" tests above
236-
describe('getNarrowFromLink (part 2)', () => {
235+
// TODO: Combine / dedupe with "getNarrowFromNarrowLink (part 1)" tests above
236+
describe('getNarrowFromNarrowLink (part 2)', () => {
237237
const [userB, userC] = [eg.makeUser(), eg.makeUser()];
238238

239239
const streamGeneral = eg.makeStream({ name: 'general' });
240240

241241
// TODO: Take URL object instead of string
242242
const get = (url, streams: $ReadOnlyArray<Stream>) =>
243-
getNarrowFromLink(
243+
getNarrowFromNarrowLink(
244244
new URL(url, 'https://example.com'),
245245
new URL('https://example.com'),
246246
new Map(streams.map(s => [s.stream_id, s])),
247247
new Map(streams.map(s => [s.name, s])),
248248
eg.selfUser.user_id,
249249
);
250250

251-
test('on link to realm domain but not narrow: return null', () => {
252-
expect(get('https://example.com/user_uploads', [])).toEqual(null);
253-
});
254-
255251
describe('on stream links', () => {
256252
const expectStream = (operand, streams, expectedStream: null | Stream) => {
257253
expect(get(`#narrow/stream/${operand}`, streams)).toEqual(

src/utils/internalLinks.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ const getHashSegmentsFromNarrowLink = (url: URL, realm: URL) => {
3434
};
3535

3636
/**
37-
* PRIVATE -- exported only for tests.
38-
*
3937
* Test for a link to a Zulip narrow on the given realm.
4038
*
4139
* True just if the given URL appears to be a link to a Zulip narrow on the
@@ -119,20 +117,30 @@ const parsePmOperand = operand => {
119117
};
120118

121119
/**
122-
* TODO write jsdoc
120+
* Gives a Narrow object for the given narrow link, or `null`.
121+
*
122+
* Returns null if any of the operator/operand pairs are invalid.
123+
*
124+
* Since narrow links can combine operators in ways our Narrow type can't
125+
* represent, this can also return null for valid narrow links.
126+
*
127+
* This can also return null for some valid narrow links that our Narrow
128+
* type *could* accurately represent. We should try to understand these
129+
* better, but some kinds will be rare, even unheard-of:
130+
* #narrow/topic/mobile.20releases/stream/1-announce (stream/topic reversed)
131+
* #narrow/stream/1-announce/stream/1-announce (duplicated operator)
132+
*
133+
* The passed `url` must appear to be a link to a Zulip narrow on the given
134+
* `realm`. In particular, `isNarrowLink(url, realm)` must be true.
123135
*/
124-
export const getNarrowFromLink = (
136+
export const getNarrowFromNarrowLink = (
125137
url: URL,
126138
realm: URL,
127139
streamsById: Map<number, Stream>,
128140
streamsByName: Map<string, Stream>,
129141
ownUserId: UserId,
130142
): Narrow | null => {
131-
if (!isNarrowLink(url, realm)) {
132-
return null;
133-
}
134-
135-
// isNarrowLink(…) is true, by early return above, so this call is OK.
143+
// isNarrowLink(…) is true, by jsdoc, so this call is OK.
136144
const hashSegments = getHashSegmentsFromNarrowLink(url, realm);
137145

138146
if (

0 commit comments

Comments
 (0)