@@ -44,61 +44,71 @@ describe('isNarrowLink', () => {
44
44
[ true , 'legacy: stream name, no ID' , urlOnRealm ( '#narrow/stream/jest' ) ] ,
45
45
[ true , 'legacy: stream name, no ID, topic' , urlOnRealm ( '#narrow/stream/jest/topic/topic1' ) ] ,
46
46
47
- [ true , 'with numeric stream ID' , urlOnRealm ( '#narrow/stream/123-jest' ) ] ,
48
- [ true , 'with numeric stream ID and topic' , urlOnRealm ( '#narrow/stream/123-jest/topic/topic1' ) ] ,
47
+ [ true , 'with numeric channel ID' , urlOnRealm ( '#narrow/channel/123-jest' ) ] ,
48
+ [ true , 'with numeric channel ID (old operator)' , urlOnRealm ( '#narrow/stream/123-jest' ) ] ,
49
+ [
50
+ true ,
51
+ 'with numeric channel ID and topic' ,
52
+ urlOnRealm ( '#narrow/channel/123-jest/topic/topic1' ) ,
53
+ ] ,
54
+ [
55
+ true ,
56
+ 'with numeric channel ID (old operator) and topic' ,
57
+ urlOnRealm ( '#narrow/stream/123-jest/topic/topic1' ) ,
58
+ ] ,
49
59
50
60
[ true , 'with numeric pm user IDs (new operator)' , urlOnRealm ( '#narrow/dm/123-mark' ) ] ,
51
61
[ true , 'with numeric pm user IDs (old operator)' , urlOnRealm ( '#narrow/pm-with/123-mark' ) ] ,
52
62
53
63
[ false , 'wrong fragment' , urlOnRealm ( '#nope' ) ] ,
54
- [ false , 'wrong path' , urlOnRealm ( '/user_uploads/#narrow/stream /jest' ) ] ,
55
- [ false , 'wrong domain' , new URL ( 'https://another.com/#narrow/stream /jest' ) ] ,
64
+ [ false , 'wrong path' , urlOnRealm ( '/user_uploads/#narrow/channel /jest' ) ] ,
65
+ [ false , 'wrong domain' , new URL ( 'https://another.com/#narrow/channel /jest' ) ] ,
56
66
57
- [ false , '#narrowly' , urlOnRealm ( '#narrowly/stream /jest' ) ] ,
67
+ [ false , '#narrowly' , urlOnRealm ( '#narrowly/channel /jest' ) ] ,
58
68
59
- [ false , 'double slash' , new URL ( `${ realm . origin } //#narrow/stream /jest` ) ] ,
60
- [ false , 'triple slash' , new URL ( `${ realm . origin } ///#narrow/stream /jest` ) ] ,
69
+ [ false , 'double slash' , new URL ( `${ realm . origin } //#narrow/channel /jest` ) ] ,
70
+ [ false , 'triple slash' , new URL ( `${ realm . origin } ///#narrow/channel /jest` ) ] ,
61
71
62
72
[
63
73
true ,
64
74
'with port' ,
65
- new URL ( '#narrow/stream /jest' , 'https://example.com:444/' ) ,
75
+ new URL ( '#narrow/channel /jest' , 'https://example.com:444/' ) ,
66
76
new URL ( 'https://example.com:444/' ) ,
67
77
] ,
68
78
69
79
// This one fails because our polyfilled URL implementation has IDNA stripped out.
70
80
// [
71
81
// true,
72
82
// 'same domain, punycoded host',
73
- // new URL('https://example.xn--h2brj9c/#narrow/stream /jest'),
83
+ // new URL('https://example.xn--h2brj9c/#narrow/channel /jest'),
74
84
// new URL('https://example.भारत/'),
75
85
// ], // FAILS
76
86
[
77
87
true ,
78
88
'punycodable host' ,
79
- new URL ( '#narrow/stream /jest' , 'https://example.भारत/' ) ,
89
+ new URL ( '#narrow/channel /jest' , 'https://example.भारत/' ) ,
80
90
new URL ( 'https://example.भारत/' ) ,
81
91
] ,
82
92
83
93
// This one fails because our polyfilled URL implementation has IDNA stripped out.
84
94
// [
85
95
// true,
86
96
// 'same domain, IDNA-mappable',
87
- // new URL('https://ℯⅩªm🄿ₗℰ.ℭᴼⓂ/#narrow/stream /jest'),
97
+ // new URL('https://ℯⅩªm🄿ₗℰ.ℭᴼⓂ/#narrow/channel /jest'),
88
98
// new URL('https://example.com'),
89
99
// ], // FAILS
90
100
91
101
[
92
102
true ,
93
103
'ipv4 address' ,
94
- new URL ( '#narrow/stream /jest' , 'http://192.168.0.1/' ) ,
104
+ new URL ( '#narrow/channel /jest' , 'http://192.168.0.1/' ) ,
95
105
new URL ( 'http://192.168.0.1/' ) ,
96
106
] ,
97
107
// This one fails because our polyfilled URL implementation has IDNA stripped out.
98
108
// [
99
109
// true,
100
110
// 'same IPv4 address, IDNA-mappable',
101
- // new URL('http://1𝟗𝟚。①⁶🯸.₀。𝟭/#narrow/stream /jest'),
111
+ // new URL('http://1𝟗𝟚。①⁶🯸.₀。𝟭/#narrow/channel /jest'),
102
112
// new URL('http://192.168.0.1/'),
103
113
// ], // FAILS
104
114
@@ -111,17 +121,17 @@ describe('isNarrowLink', () => {
111
121
// This one, except possibly the fragment, is a 100% realistic link
112
122
// for innocent normal use. The buggy old version narrowly avoided
113
123
// accepting it... but would accept all the variations below.
114
- new URL ( `https://web.archive.org/web/*/${ urlOnRealm ( '#narrow/stream /jest' ) . toString ( ) } ` ) ,
124
+ new URL ( `https://web.archive.org/web/*/${ urlOnRealm ( '#narrow/channel /jest' ) . toString ( ) } ` ) ,
115
125
] ,
116
126
[
117
127
false ,
118
128
'odd scheme, wrong domain, realm-like path, narrow-like fragment' ,
119
- new URL ( `ftp://web.archive.org/web/*/${ urlOnRealm ( '#narrow/stream /jest' ) . toString ( ) } ` ) ,
129
+ new URL ( `ftp://web.archive.org/web/*/${ urlOnRealm ( '#narrow/channel /jest' ) . toString ( ) } ` ) ,
120
130
] ,
121
131
[
122
132
false ,
123
133
'same domain, realm-like path, narrow-like fragment' ,
124
- urlOnRealm ( `web/*/${ urlOnRealm ( '#narrow/stream /jest' ) . toString ( ) } ` ) ,
134
+ urlOnRealm ( `web/*/${ urlOnRealm ( '#narrow/channel /jest' ) . toString ( ) } ` ) ,
125
135
] ,
126
136
] ;
127
137
@@ -138,10 +148,10 @@ describe('isNarrowLink', () => {
138
148
describe ( 'getNarrowFromNarrowLink (part 1)' , ( ) => {
139
149
const mkCheck = ( narrowExpectation : ( Narrow => boolean ) | null ) => hash => {
140
150
const streams = [
141
- eg . makeStream ( { name : 'jest' } ) ,
142
- eg . makeStream ( { name : 'stream' } ) ,
143
- eg . makeStream ( { name : 'topic' } ) ,
144
- eg . makeStream ( { name : 'mobile' } ) ,
151
+ eg . makeStream ( { stream_id : 1 , name : 'jest' } ) ,
152
+ eg . makeStream ( { stream_id : 2 , name : 'stream' } ) ,
153
+ eg . makeStream ( { stream_id : 3 , name : 'topic' } ) ,
154
+ eg . makeStream ( { stream_id : 4 , name : 'mobile' } ) ,
145
155
] ;
146
156
const baseState = eg . reduxStatePlus ( { streams } ) ;
147
157
const narrow = getNarrowFromNarrowLink (
@@ -163,6 +173,13 @@ describe('getNarrowFromNarrowLink (part 1)', () => {
163
173
}
164
174
} ;
165
175
176
+ describe ( '"/#narrow/channel/<…>" is a channel link' , ( ) => {
177
+ const check = mkCheck ( isStreamNarrow ) ;
178
+ [ '/#narrow/channel/1-jest' , '/#narrow/channel/2-stream/' , '/#narrow/channel/3-topic/' ] . forEach (
179
+ hash => check ( hash ) ,
180
+ ) ;
181
+ } ) ;
182
+
166
183
describe ( '"/#narrow/stream/<…>" is a stream link' , ( ) => {
167
184
const check = mkCheck ( isStreamNarrow ) ;
168
185
[ '/#narrow/stream/jest' , '/#narrow/stream/stream/' , '/#narrow/stream/topic/' ] . forEach ( hash =>
@@ -172,6 +189,16 @@ describe('getNarrowFromNarrowLink (part 1)', () => {
172
189
// TODO: Test with modern-style stream links that use stream IDs
173
190
} ) ;
174
191
192
+ describe ( '"/#narrow/channel/<…>/topic/<…>" is a topic link' , ( ) => {
193
+ const check = mkCheck ( isTopicNarrow ) ;
194
+ [
195
+ '/#narrow/channel/1-jest/topic/test' ,
196
+ '/#narrow/channel/4-mobile/subject/topic/near/378333' ,
197
+ '/#narrow/channel/4-mobile/topic/topic/' ,
198
+ '/#narrow/channel/3-stream/topic/topic/near/1' ,
199
+ ] . forEach ( hash => check ( hash ) ) ;
200
+ } ) ;
201
+
175
202
describe ( '"/#narrow/stream/<…>/topic/<…>" is a topic link' , ( ) => {
176
203
const check = mkCheck ( isTopicNarrow ) ;
177
204
[
@@ -216,14 +243,14 @@ describe('getNarrowFromNarrowLink (part 1)', () => {
216
243
const check = mkCheck ( null ) ;
217
244
[
218
245
// `near` with no operand
219
- '/#narrow/stream /stream/topic/topic/near/' ,
246
+ '/#narrow/channel /stream/topic/topic/near/' ,
220
247
221
248
// `is` with invalid operand
222
249
'/#narrow/is/men' ,
223
- '/#narrow/is/men/stream ' ,
250
+ '/#narrow/is/men/channel ' ,
224
251
225
- // invalid operand `are`; `stream ` operator with no operand
226
- '/#narrow/are/men/stream ' ,
252
+ // invalid operand `are`; `channel ` operator with no operand
253
+ '/#narrow/are/men/channel ' ,
227
254
] . forEach ( hash => check ( hash ) ) ;
228
255
} ) ;
229
256
} ) ;
@@ -263,8 +290,11 @@ describe('getNarrowFromNarrowLink (part 2)', () => {
263
290
eg . selfUser . user_id ,
264
291
) ;
265
292
266
- describe ( 'on stream links' , ( ) => {
293
+ describe ( 'on channel links' , ( ) => {
267
294
const expectStream = ( operand , streams , expectedStream : null | Stream ) => {
295
+ expect ( get ( `#narrow/channel/${ operand } ` , streams ) ) . toEqual (
296
+ expectedStream === null ? null : streamNarrow ( expectedStream . stream_id ) ,
297
+ ) ;
268
298
expect ( get ( `#narrow/stream/${ operand } ` , streams ) ) . toEqual (
269
299
expectedStream === null ? null : streamNarrow ( expectedStream . stream_id ) ,
270
300
) ;
@@ -278,12 +308,12 @@ describe('getNarrowFromNarrowLink (part 2)', () => {
278
308
expectStream ( `${ streamGeneral . stream_id } -general` , [ ] , streamGeneral ) ;
279
309
} ) ;
280
310
281
- test ( 'on stream link with wrong name: ID wins' , ( ) => {
311
+ test ( 'on channel link with wrong name: ID wins' , ( ) => {
282
312
expectStream ( `${ streamGeneral . stream_id } -nonsense` , [ streamGeneral ] , streamGeneral ) ;
283
313
expectStream ( `${ streamGeneral . stream_id } -` , [ streamGeneral ] , streamGeneral ) ;
284
314
} ) ;
285
315
286
- test ( 'on malformed stream link: reject' , ( ) => {
316
+ test ( 'on malformed channel link: reject' , ( ) => {
287
317
expectStream ( `-${ streamGeneral . stream_id } ` , [ streamGeneral ] , null ) ;
288
318
expectStream ( `${ streamGeneral . stream_id } nonsense-general` , [ streamGeneral ] , null ) ;
289
319
} ) ;
@@ -340,17 +370,21 @@ describe('getNarrowFromNarrowLink (part 2)', () => {
340
370
describe ( 'on topic links' , ( ) => {
341
371
test ( 'basic' , ( ) => {
342
372
const expectBasic = ( operand , expectedTopic ) => {
343
- const url = `#narrow/stream/${ streamGeneral . stream_id } -general/topic/${ operand } ` ;
373
+ const url = `#narrow/channel/${ streamGeneral . stream_id } -general/topic/${ operand } ` ;
374
+ const legacyUrl = `#narrow/stream/${ streamGeneral . stream_id } -general/topic/${ operand } ` ;
344
375
expect ( get ( url , [ streamGeneral ] ) ) . toEqual (
345
376
topicNarrow ( streamGeneral . stream_id , expectedTopic ) ,
346
377
) ;
378
+ expect ( get ( legacyUrl , [ streamGeneral ] ) ) . toEqual (
379
+ topicNarrow ( streamGeneral . stream_id , expectedTopic ) ,
380
+ ) ;
347
381
} ;
348
382
349
383
expectBasic ( '(no.20topic)' , '(no topic)' ) ;
350
384
expectBasic ( 'lunch' , 'lunch' ) ;
351
385
} ) ;
352
386
353
- test ( 'on old topic link, with dot-encoding' , ( ) => {
387
+ test ( 'on old topic link (no stream ID) , with dot-encoding' , ( ) => {
354
388
expect (
355
389
get ( `https://example.com/#narrow/stream/${ eg . stream . name } /topic/(no.20topic)` , [ eg . stream ] ) ,
356
390
) . toEqual ( topicNarrow ( eg . stream . stream_id , '(no topic)' ) ) ;
@@ -376,7 +410,7 @@ describe('getNarrowFromNarrowLink (part 2)', () => {
376
410
) . toEqual ( topicNarrow ( eg . stream . stream_id , 'topic' ) ) ;
377
411
} ) ;
378
412
379
- test ( 'on old topic link, without realm info' , ( ) => {
413
+ test ( 'on old topic link (no stream ID) , without realm info' , ( ) => {
380
414
expect ( get ( `/#narrow/stream/${ eg . stream . name } /topic/topic` , [ eg . stream ] ) ) . toEqual (
381
415
topicNarrow ( eg . stream . stream_id , 'topic' ) ,
382
416
) ;
@@ -423,6 +457,13 @@ describe('getNarrowFromNarrowLink (part 2)', () => {
423
457
pmNarrowFromUsersUnsafe ( [ userB , userC ] ) ,
424
458
) ;
425
459
460
+ expect (
461
+ get (
462
+ `https://example.com/#narrow/channel/${ eg . stream . stream_id } -${ eg . stream . name } /topic/test/near/1` ,
463
+ [ eg . stream ] ,
464
+ ) ,
465
+ ) . toEqual ( topicNarrow ( eg . stream . stream_id , 'test' ) ) ;
466
+
426
467
expect (
427
468
get ( `https://example.com/#narrow/stream/${ eg . stream . name } /topic/test/near/1` , [ eg . stream ] ) ,
428
469
) . toEqual ( topicNarrow ( eg . stream . stream_id , 'test' ) ) ;
@@ -436,6 +477,7 @@ describe('getNarrowFromNarrowLink (part 2)', () => {
436
477
describe ( 'getNearOperandFromLink' , ( ) => {
437
478
test ( 'not message link' , ( ) => {
438
479
expect ( getNearOperandFromLink ( new URL ( '/#narrow/is/private' , realm ) , realm ) ) . toBe ( null ) ;
480
+ expect ( getNearOperandFromLink ( new URL ( '/#narrow/channel/jest' , realm ) , realm ) ) . toBe ( null ) ;
439
481
expect ( getNearOperandFromLink ( new URL ( '/#narrow/stream/jest' , realm ) , realm ) ) . toBe ( null ) ;
440
482
} ) ;
441
483
@@ -451,6 +493,9 @@ describe('getNearOperandFromLink', () => {
451
493
} ) ;
452
494
453
495
test ( 'when link is a topic link, return anchor message id' , ( ) => {
496
+ expect (
497
+ getNearOperandFromLink ( new URL ( '/#narrow/channel/1-jest/topic/test/near/1' , realm ) , realm ) ,
498
+ ) . toBe ( 1 ) ;
454
499
expect (
455
500
getNearOperandFromLink ( new URL ( '/#narrow/stream/jest/topic/test/near/1' , realm ) , realm ) ,
456
501
) . toBe ( 1 ) ;
0 commit comments