@oneuptime/common 12.0.26 → 12.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/Tests/Types/API/HostnameAuthorityParsing.test.ts +1 -0
  2. package/Tests/Types/API/URLMailtoQueryString.test.ts +439 -0
  3. package/Tests/Types/API/URLQueryString.test.ts +33 -24
  4. package/Tests/Types/API/URLRouteQuerySeparation.test.ts +491 -0
  5. package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +393 -0
  6. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +248 -0
  7. package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +205 -0
  8. package/Tests/UI/Components/UseHistogramZoom.test.tsx +262 -0
  9. package/Types/API/URL.ts +55 -18
  10. package/UI/Components/Charts/Utils/useHistogramZoom.ts +101 -0
  11. package/UI/Components/LogsViewer/LogsViewer.tsx +19 -3
  12. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +52 -1
  13. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +18 -2
  14. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +52 -1
  15. package/build/dist/Types/API/URL.js +48 -17
  16. package/build/dist/Types/API/URL.js.map +1 -1
  17. package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js +47 -0
  18. package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js.map +1 -0
  19. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +15 -3
  20. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  21. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +33 -5
  22. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  23. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +14 -2
  24. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  25. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +33 -5
  26. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  27. package/package.json +1 -1
@@ -142,6 +142,7 @@ describe("URL.fromString keeps the authority separate from the rest", () => {
142
142
 
143
143
  expect(url.email.toString()).toBe("support@oneuptime.com");
144
144
  expect(url.getQueryParam("subject")).toBe("Hello");
145
+ expect(url.toString()).toBe("mailto:support@oneuptime.com?subject=Hello");
145
146
  });
146
147
 
147
148
  test("a webhook URL with basic-auth credentials still round-trips", () => {
@@ -0,0 +1,439 @@
1
+ import Email from "../../../Types/Email";
2
+ import Hostname from "../../../Types/API/Hostname";
3
+ import Protocol from "../../../Types/API/Protocol";
4
+ import Route from "../../../Types/API/Route";
5
+ import URL from "../../../Types/API/URL";
6
+
7
+ /*
8
+ * toString() never emitted the query string for a mailto: URL, so every
9
+ * prefilled field of a mail link was silently dropped:
10
+ * "mailto:a@b.com?subject=Hello&body=Hi" went back out as "mailto:a@b.com"
11
+ * and the link opened on an empty draft.
12
+ *
13
+ * The parse was never the problem — `params` held { subject, body } all along.
14
+ * The suffix was appended INSIDE the route-handling branch, and mailto skips
15
+ * that branch on purpose (it has no authority to trim and no path to append),
16
+ * so the query went with the route. mailto now returns early with the suffix
17
+ * attached, the way the opaque tel:/sms: branch above it already did.
18
+ */
19
+ describe("mailto query string — the prefilled fields survive toString", () => {
20
+ test("a subject on its own reaches the output", () => {
21
+ const url: URL = URL.fromString("mailto:a@b.com?subject=Hello");
22
+
23
+ expect(url.getQueryParam("subject")).toBe("Hello");
24
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello");
25
+ });
26
+
27
+ test("a subject and a body both reach the output", () => {
28
+ const url: URL = URL.fromString("mailto:a@b.com?subject=Hello&body=Hi");
29
+
30
+ expect(url.params).toEqual({ subject: "Hello", body: "Hi" });
31
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello&body=Hi");
32
+ });
33
+
34
+ test("the parse was always right — only the output was lossy", () => {
35
+ /*
36
+ * Pins the exact shape of the bug rather than just its fix: params were
37
+ * correct before the change and are asserted separately from toString, so
38
+ * a regression that breaks only one of the two still shows which one.
39
+ */
40
+ const url: URL = URL.fromString("mailto:a@b.com?subject=Hello&body=Hi");
41
+
42
+ expect(url.params).toEqual({ subject: "Hello", body: "Hi" });
43
+ expect(url.toString()).not.toBe("mailto:a@b.com");
44
+ expect(url.toString()).toContain("subject=Hello");
45
+ expect(url.toString()).toContain("body=Hi");
46
+ });
47
+
48
+ test("cc and bcc survive alongside subject and body", () => {
49
+ const url: URL = URL.fromString(
50
+ "mailto:a@b.com?cc=c@d.com&bcc=e@f.com&subject=Hello&body=Hi",
51
+ );
52
+
53
+ expect(url.params).toEqual({
54
+ cc: "c@d.com",
55
+ bcc: "e@f.com",
56
+ subject: "Hello",
57
+ body: "Hi",
58
+ });
59
+ expect(url.toString()).toBe(
60
+ "mailto:a@b.com?cc=c@d.com&bcc=e@f.com&subject=Hello&body=Hi",
61
+ );
62
+ });
63
+
64
+ test("a mailto with no query gains no stray '?'", () => {
65
+ const url: URL = URL.fromString("mailto:support@oneuptime.com");
66
+
67
+ expect(url.toString()).toBe("mailto:support@oneuptime.com");
68
+ expect(url.toString()).not.toContain("?");
69
+ });
70
+ });
71
+
72
+ describe("mailto query string — a value that contains '='", () => {
73
+ test("an '=' inside a subject is not truncated", () => {
74
+ const url: URL = URL.fromString("mailto:a@b.com?subject=a=b");
75
+
76
+ expect(url.getQueryParam("subject")).toBe("a=b");
77
+ expect(url.toString()).toBe("mailto:a@b.com?subject=a=b");
78
+ });
79
+
80
+ test("an '=' laden body keeps its whole expression", () => {
81
+ const url: URL = URL.fromString(
82
+ "mailto:ops@example.com?subject=Alert&body=filter: status = open AND team = ops",
83
+ );
84
+
85
+ expect(url.getQueryParam("body")).toBe(
86
+ "filter: status = open AND team = ops",
87
+ );
88
+ expect(url.toString()).toBe(
89
+ "mailto:ops@example.com?subject=Alert&body=filter: status = open AND team = ops",
90
+ );
91
+ });
92
+
93
+ test("only the first '=' separates, however many follow", () => {
94
+ const url: URL = URL.fromString("mailto:a@b.com?body=x=y=z");
95
+
96
+ expect(url.params).toEqual({ body: "x=y=z" });
97
+ expect(url.toString()).toBe("mailto:a@b.com?body=x=y=z");
98
+ });
99
+
100
+ test("'==' padding does not swallow the params that follow it", () => {
101
+ const url: URL = URL.fromString(
102
+ "mailto:a@b.com?ref=YWJjZGVmZ2g==&subject=Hello",
103
+ );
104
+
105
+ expect(url.params).toEqual({ ref: "YWJjZGVmZ2g==", subject: "Hello" });
106
+ expect(url.toString()).toBe(
107
+ "mailto:a@b.com?ref=YWJjZGVmZ2g==&subject=Hello",
108
+ );
109
+ });
110
+ });
111
+
112
+ describe("mailto query string — round trip is lossless", () => {
113
+ const roundTripCases: Array<string> = [
114
+ "mailto:a@b.com",
115
+ "mailto:a@b.com?subject=Hello",
116
+ "mailto:a@b.com?subject=Hello&body=Hi",
117
+ "mailto:a@b.com?body=Hi&subject=Hello",
118
+ "mailto:a@b.com?cc=c@d.com&bcc=e@f.com&subject=Hello&body=Hi",
119
+ "mailto:a@b.com?subject=a=b",
120
+ "mailto:a@b.com?body=x=y=z",
121
+ "mailto:a@b.com?ref=YWJjZGVmZ2g==&subject=Hello",
122
+ "mailto:a@b.com?subject=Hello%20World&body=Line%0A2",
123
+ "mailto:a@b.com?subject=café ✓",
124
+ "mailto:a@b.com?body=see?tab=1",
125
+ "mailto:a@b.com?body=/a/b",
126
+ "mailto:a@b.com?flag",
127
+ "mailto:a+tag@b.com?subject=Hello",
128
+ "mailto:first.last@sub.example.co.uk?subject=Hello",
129
+ "mailto:support@oneuptime.com?subject=OneUptime%20Microsoft%20Teams%20Bot",
130
+ "mailto:security@oneuptime.com?subject=Security%20documentation%20request",
131
+ ];
132
+
133
+ test.each(roundTripCases)(
134
+ "URL.fromString(%s).toString() returns it unchanged",
135
+ (original: string) => {
136
+ expect(URL.fromString(original).toString()).toBe(original);
137
+ },
138
+ );
139
+
140
+ test.each(roundTripCases)(
141
+ "a second parse of %s is stable",
142
+ (original: string) => {
143
+ const once: string = URL.fromString(original).toString();
144
+
145
+ expect(URL.fromString(once).toString()).toBe(once);
146
+ },
147
+ );
148
+
149
+ test("fromURL round trips a mailto with a query", () => {
150
+ const url: URL = URL.fromString("mailto:a@b.com?subject=Hello&body=Hi");
151
+
152
+ expect(URL.fromURL(url).toString()).toBe(
153
+ "mailto:a@b.com?subject=Hello&body=Hi",
154
+ );
155
+ });
156
+ });
157
+
158
+ describe("mailto query string — degenerate segments", () => {
159
+ test("a trailing '?' produces no params and no '?'", () => {
160
+ const url: URL = URL.fromString("mailto:a@b.com?");
161
+
162
+ expect(url.params).toEqual({});
163
+ expect(url.toString()).toBe("mailto:a@b.com");
164
+ });
165
+
166
+ test("a value-less param is kept and re-emits bare", () => {
167
+ const url: URL = URL.fromString("mailto:a@b.com?flag");
168
+
169
+ expect(url.params).toEqual({ flag: "" });
170
+ expect(url.toString()).toBe("mailto:a@b.com?flag");
171
+ expect(url.toString()).not.toContain("flag=");
172
+ });
173
+
174
+ test("an explicitly empty subject re-emits bare", () => {
175
+ const url: URL = URL.fromString("mailto:a@b.com?subject=");
176
+
177
+ expect(url.params).toEqual({ subject: "" });
178
+ expect(url.toString()).toBe("mailto:a@b.com?subject");
179
+ });
180
+
181
+ test("a later duplicate key wins", () => {
182
+ const url: URL = URL.fromString("mailto:a@b.com?subject=one&subject=two");
183
+
184
+ expect(url.getQueryParam("subject")).toBe("two");
185
+ expect(url.toString()).toBe("mailto:a@b.com?subject=two");
186
+ });
187
+
188
+ test("a '?' inside a body is not truncated", () => {
189
+ /*
190
+ * The address is taken from everything before the FIRST "?", and the query
191
+ * is everything after it — so a body that carries its own "?" survives.
192
+ */
193
+ const url: URL = URL.fromString("mailto:a@b.com?body=see?tab=1");
194
+
195
+ expect(url.getQueryParam("body")).toBe("see?tab=1");
196
+ expect(url.toString()).toBe("mailto:a@b.com?body=see?tab=1");
197
+ });
198
+
199
+ test("a '/' inside a body does not fabricate a route", () => {
200
+ /*
201
+ * Unlike a path-less https URL, whose authority is split off at the first
202
+ * "/" before the query is separated, a mailto never reaches that code:
203
+ * fromString takes its address from url.split("?")[0].
204
+ */
205
+ const url: URL = URL.fromString("mailto:a@b.com?body=/a/b");
206
+
207
+ expect(url.getQueryParam("body")).toBe("/a/b");
208
+ expect(url.route.toString()).toBe("");
209
+ expect(url.toString()).toBe("mailto:a@b.com?body=/a/b");
210
+ });
211
+
212
+ test("a unicode subject is passed through untouched", () => {
213
+ const url: URL = URL.fromString("mailto:a@b.com?subject=café ✓");
214
+
215
+ expect(url.getQueryParam("subject")).toBe("café ✓");
216
+ expect(url.toString()).toBe("mailto:a@b.com?subject=café ✓");
217
+ });
218
+
219
+ test("a percent-encoded subject and body are passed through verbatim", () => {
220
+ const url: URL = URL.fromString(
221
+ "mailto:a@b.com?subject=Hello%20World&body=Line%0A2",
222
+ );
223
+
224
+ expect(url.params).toEqual({
225
+ subject: "Hello%20World",
226
+ body: "Line%0A2",
227
+ });
228
+ expect(url.toString()).toBe(
229
+ "mailto:a@b.com?subject=Hello%20World&body=Line%0A2",
230
+ );
231
+ });
232
+
233
+ test("a pair with no key is dropped", () => {
234
+ const url: URL = URL.fromString("mailto:a@b.com?=novalue&subject=Hello");
235
+
236
+ expect(url.params).toEqual({ subject: "Hello" });
237
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello");
238
+ });
239
+ });
240
+
241
+ describe("mailto query string — the address is still an Email", () => {
242
+ test("the email is readable with a query present", () => {
243
+ const url: URL = URL.fromString("mailto:support@oneuptime.com?subject=Hi");
244
+
245
+ expect(url.email.toString()).toBe("support@oneuptime.com");
246
+ expect(url.protocol).toBe(Protocol.MAIL);
247
+ expect(url.toString()).toBe("mailto:support@oneuptime.com?subject=Hi");
248
+ });
249
+
250
+ test("a plus-addressed recipient keeps its tag", () => {
251
+ const url: URL = URL.fromString("mailto:a+tag@b.com?subject=Hello");
252
+
253
+ expect(url.email.toString()).toBe("a+tag@b.com");
254
+ expect(url.toString()).toBe("mailto:a+tag@b.com?subject=Hello");
255
+ });
256
+
257
+ test("an upper-case scheme is normalised and keeps its query", () => {
258
+ const url: URL = URL.fromString("MAILTO:a@b.com?subject=Hello");
259
+
260
+ expect(url.email.toString()).toBe("a@b.com");
261
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello");
262
+ });
263
+
264
+ test("a mailto payload that is not an email still keeps its query", () => {
265
+ /*
266
+ * "notanemail" fails Email.isValid, so the constructor stores it as a
267
+ * hostname and `email` is never set. The guard has to catch this case on
268
+ * the "mailto:" prefix rather than on `email`, or the query would be lost
269
+ * again for exactly these values.
270
+ */
271
+ const url: URL = URL.fromString("mailto:notanemail?subject=Hello");
272
+
273
+ expect(url.email).toBeUndefined();
274
+ expect(url.hostname.toString()).toBe("notanemail");
275
+ expect(url.toString()).toBe("mailto:notanemail?subject=Hello");
276
+ });
277
+ });
278
+
279
+ describe("mailto query string — constructed rather than parsed", () => {
280
+ test("the constructor takes a query alongside an Email", () => {
281
+ const url: URL = new URL(
282
+ Protocol.MAIL,
283
+ new Email("a@b.com"),
284
+ undefined,
285
+ "subject=Hello&body=Hi",
286
+ );
287
+
288
+ expect(url.params).toEqual({ subject: "Hello", body: "Hi" });
289
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello&body=Hi");
290
+ });
291
+
292
+ test("the constructor takes a query alongside a string address", () => {
293
+ const url: URL = new URL(
294
+ Protocol.MAIL,
295
+ "a@b.com",
296
+ undefined,
297
+ "subject=Hello",
298
+ );
299
+
300
+ expect(url.email.toString()).toBe("a@b.com");
301
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello");
302
+ });
303
+
304
+ test("addQueryParam prefills a mailto that had no query", () => {
305
+ const url: URL = URL.fromString("mailto:a@b.com").addQueryParam(
306
+ "subject",
307
+ "Hello",
308
+ );
309
+
310
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello");
311
+ });
312
+
313
+ test("addQueryParam with encode still round trips", () => {
314
+ const url: URL = URL.fromString("mailto:a@b.com").addQueryParam(
315
+ "subject",
316
+ "Hello World",
317
+ true,
318
+ );
319
+
320
+ expect(url.getQueryParam("subject")).toBe("Hello%20World");
321
+ expect(URL.fromString(url.toString()).getQueryParam("subject")).toBe(
322
+ "Hello%20World",
323
+ );
324
+ });
325
+
326
+ test("addQueryParams merges a body into an existing subject", () => {
327
+ const url: URL = URL.fromString(
328
+ "mailto:a@b.com?subject=Hello",
329
+ ).addQueryParams({ body: "Hi" });
330
+
331
+ expect(url.params).toEqual({ subject: "Hello", body: "Hi" });
332
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello&body=Hi");
333
+ });
334
+
335
+ test("removeQueryString strips the prefilled fields back off", () => {
336
+ const url: URL = URL.fromString(
337
+ "mailto:a@b.com?subject=Hello&body=Hi",
338
+ ).removeQueryString();
339
+
340
+ expect(url.params).toEqual({});
341
+ expect(url.toString()).toBe("mailto:a@b.com");
342
+ });
343
+ });
344
+
345
+ describe("mailto query string — crossing the wire", () => {
346
+ test("toJSON carries the query", () => {
347
+ const url: URL = URL.fromString("mailto:a@b.com?subject=Hello&body=Hi");
348
+
349
+ expect(url.toJSON()).toEqual({
350
+ _type: "URL",
351
+ value: "mailto:a@b.com?subject=Hello&body=Hi",
352
+ });
353
+ });
354
+
355
+ test("fromJSON restores a mailto with its query intact", () => {
356
+ const url: URL = URL.fromJSON(
357
+ URL.fromString("mailto:a@b.com?subject=Hello&body=Hi").toJSON(),
358
+ );
359
+
360
+ expect(url.getQueryParam("subject")).toBe("Hello");
361
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello&body=Hi");
362
+ });
363
+
364
+ test("a mailto with a query is not treated as malformed", () => {
365
+ const url: URL = URL.fromStringLenient("mailto:a@b.com?subject=Hello");
366
+
367
+ expect(url.isMalformed()).toBe(false);
368
+ expect(url.toString()).toBe("mailto:a@b.com?subject=Hello");
369
+ });
370
+ });
371
+
372
+ /*
373
+ * The fix returns early for mailto instead of widening the branch that builds
374
+ * the route, so the branch itself moved. These pin the shapes that go through
375
+ * it — every one of them held before the change and must still hold.
376
+ */
377
+ describe("mailto query string — every other scheme is unaffected", () => {
378
+ const untouchedCases: Array<string> = [
379
+ "https://example.com/a/b?x=1",
380
+ "https://example.com/path",
381
+ "http://localhost:5000/api/test?a=1",
382
+ "wss://example.com/socket?a=1",
383
+ "mongodb://example.com/db?a=1",
384
+ "https://user:token@hooks.example.com/x",
385
+ "https://example.com/p?flag",
386
+ "https://example.com/p?a=b=c=d",
387
+ "tel:+15555550123?ref=a=b",
388
+ "sms:+15555550123?body=x=1&y=2",
389
+ ];
390
+
391
+ test.each(untouchedCases)("%s still round trips", (original: string) => {
392
+ expect(URL.fromString(original).toString()).toBe(original);
393
+ });
394
+
395
+ test("a path-less https URL still gains its trailing slash", () => {
396
+ expect(URL.fromString("https://example.com").toString()).toBe(
397
+ "https://example.com/",
398
+ );
399
+ });
400
+
401
+ test("a route given with a leading slash is not doubled", () => {
402
+ const url: URL = new URL(
403
+ Protocol.HTTPS,
404
+ new Hostname("example.com"),
405
+ new Route("/a/b"),
406
+ "x=1",
407
+ );
408
+
409
+ expect(url.toString()).toBe("https://example.com/a/b?x=1");
410
+ });
411
+
412
+ test("a route given without a leading slash still gets one", () => {
413
+ const url: URL = new URL(
414
+ Protocol.HTTPS,
415
+ new Hostname("example.com"),
416
+ new Route("a/b"),
417
+ "x=1",
418
+ );
419
+
420
+ expect(url.toString()).toBe("https://example.com/a/b?x=1");
421
+ });
422
+
423
+ test("an empty route still renders as a bare slash", () => {
424
+ const url: URL = new URL(
425
+ Protocol.HTTPS,
426
+ new Hostname("example.com"),
427
+ new Route(""),
428
+ "x=1",
429
+ );
430
+
431
+ expect(url.toString()).toBe("https://example.com/?x=1");
432
+ });
433
+
434
+ test("a malformed URL is still echoed back raw", () => {
435
+ expect(URL.fromStringLenient("https://tel:1234567890/").toString()).toBe(
436
+ "https://tel:1234567890/",
437
+ );
438
+ });
439
+ });
@@ -235,6 +235,9 @@ describe("URL query string — round trip is lossless", () => {
235
235
  'https://example.com/p?json={"where":"a=b"}&page=2',
236
236
  "https://example.com/p?q=a%3Db",
237
237
  "http://localhost:5000/api/test?a=1&b=x=y",
238
+ "https://example.com/p?next=/a/b",
239
+ "https://example.com/?next=/a/b",
240
+ "https://example.com/?redirect=https://app.example.com/home?tab=1",
238
241
  "tel:+15555550123?ref=a=b",
239
242
  "sms:+15555550123?body=x=1&y=2",
240
243
  ];
@@ -400,12 +403,36 @@ describe("URL query string — constructed rather than parsed", () => {
400
403
  });
401
404
 
402
405
  /*
403
- * Round-tripping is lossless for the cases above, but not universally, and the
404
- * two gaps below are older than this change both predate it and neither is
405
- * reachable from the Jira/OData/signed-URL shapes it set out to fix, which all
406
- * carry a path and string keys. They are pinned so the round-trip guarantee is
407
- * not read as broader than it is; if either is fixed later, these tests are the
408
- * ones that should change.
406
+ * A "/" inside a query value used to be read as a path segment whenever the
407
+ * URL had no path of its own, because fromString split the authority off on
408
+ * the first "/" before the query was ever separated. The query is now cut off
409
+ * first, so no path is invented. URLRouteQuerySeparation.test.ts covers this
410
+ * in full; these two stay here because this is where the behaviour was pinned
411
+ * as a known limitation of the "=" fix.
412
+ */
413
+ describe("URL query string — a '/' inside a value", () => {
414
+ test("no path is fabricated when the URL has none of its own", () => {
415
+ const url: URL = URL.fromString("https://example.com?next=/a/b");
416
+
417
+ expect(url.getQueryParam("next")).toBe("/a/b");
418
+ expect(url.route.toString()).toBe("");
419
+ expect(url.toString()).toBe("https://example.com/?next=/a/b");
420
+ expect(url.toString()).not.toBe("https://example.com/a/b?next=/a/b");
421
+ });
422
+
423
+ test("and a '/' in a value is harmless once the URL has a path", () => {
424
+ const original: string = "https://example.com/p?next=/a/b";
425
+
426
+ expect(URL.fromString(original).toString()).toBe(original);
427
+ });
428
+ });
429
+
430
+ /*
431
+ * Round-tripping is lossless for the cases above, but not universally. The gap
432
+ * below is older than the "=" fix, predates it, and is not reachable from the
433
+ * Jira/OData/signed-URL shapes it set out to fix, which all carry string keys.
434
+ * It is pinned so the round-trip guarantee is not read as broader than it is;
435
+ * if it is fixed later, this test is the one that should change.
409
436
  */
410
437
  describe("URL query string — known round-trip limitations", () => {
411
438
  test("an integer-like key is hoisted to the front on re-serialization", () => {
@@ -420,24 +447,6 @@ describe("URL query string — known round-trip limitations", () => {
420
447
  expect(url.params).toEqual({ b: "1", "1": "x", a: "2" });
421
448
  expect(url.toString()).toBe("https://example.com/p?1=x&b=1&a=2");
422
449
  });
423
-
424
- test("a '/' in a value fabricates a path when the URL has no path", () => {
425
- /*
426
- * fromString splits the authority off on the first "/" before the query is
427
- * ever separated, so a "/" inside a query value is read as a path segment.
428
- * Only bites a URL with no path of its own; "…/p?next=/a/b" is fine.
429
- */
430
- const url: URL = URL.fromString("https://example.com?next=/a/b");
431
-
432
- expect(url.getQueryParam("next")).toBe("/a/b");
433
- expect(url.toString()).toBe("https://example.com/a/b?next=/a/b");
434
- });
435
-
436
- test("but a '/' in a value is harmless once the URL has a path", () => {
437
- const original: string = "https://example.com/p?next=/a/b";
438
-
439
- expect(URL.fromString(original).toString()).toBe(original);
440
- });
441
450
  });
442
451
 
443
452
  /*