(
baseUrl: string,
linkKey: string,
options?: { via?: string },
)
| 14 | |
| 15 | // Redirect includes ?dub_id=… and sets a matching dub_id_*_<linkKey> cookie whose value equals the query dub_id |
| 16 | async function assertRedirectWithDubIdCookie( |
| 17 | baseUrl: string, |
| 18 | linkKey: string, |
| 19 | options?: { via?: string }, |
| 20 | ) { |
| 21 | const response = await fetch(`${baseUrl}/${linkKey}`, fetchOptions); |
| 22 | |
| 23 | const location = response.headers.get("location"); |
| 24 | expect(location).toBeTruthy(); |
| 25 | const redirectUrl = new URL(location!, baseUrl); |
| 26 | const dubIdFromQuery = redirectUrl.searchParams.get("dub_id"); |
| 27 | expect(dubIdFromQuery).toBeTruthy(); |
| 28 | expect(dubIdFromQuery).toMatch(/^[a-zA-Z0-9_-]+$/); |
| 29 | |
| 30 | if (options?.via != null) { |
| 31 | expect(redirectUrl.searchParams.get("via")).toBe(options.via); |
| 32 | } |
| 33 | |
| 34 | expect(response.headers.get("x-powered-by")).toBe(poweredBy); |
| 35 | expect(response.status).toBe(302); |
| 36 | |
| 37 | const setCookie = response.headers.getSetCookie?.() ?? []; |
| 38 | const dubIdCookie = setCookie.find((line) => { |
| 39 | const name = line.split(";")[0]!.split("=")[0]!.trim(); |
| 40 | return name.startsWith("dub_id_") && name.endsWith(`_${linkKey}`); |
| 41 | }); |
| 42 | expect( |
| 43 | dubIdCookie, |
| 44 | "expected Set-Cookie from createResponseWithCookies (dub_id_<domain>_<key>)", |
| 45 | ).toBeDefined(); |
| 46 | |
| 47 | const pair = dubIdCookie!.split(";")[0]!; |
| 48 | const eq = pair.indexOf("="); |
| 49 | const cookieValue = pair.slice(eq + 1); |
| 50 | expect(cookieValue).toBe(dubIdFromQuery); |
| 51 | |
| 52 | const pathAttr = `/${encodeURI(linkKey)}`; |
| 53 | expect(dubIdCookie).toMatch( |
| 54 | new RegExp( |
| 55 | `Path=${pathAttr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?:;|$)`, |
| 56 | "i", |
| 57 | ), |
| 58 | ); |
| 59 | expect(dubIdCookie).toMatch(/Max-Age=3600\b/i); |
| 60 | } |
| 61 | |
| 62 | describe.runIf(env.CI)("Link Redirects", async () => { |
| 63 | const h = new IntegrationHarness(); |
no test coverage detected
searching dependent graphs…