diff options
| author | Joe Mou <dev@mou.fo> | 2026-08-11 11:39:01 -0400 |
|---|---|---|
| committer | Joe Mou <dev@mou.fo> | 2026-08-11 11:57:29 -0400 |
| commit | 0a39a7a981f619ac64fdeb26294c7cfd4f110a1a (patch) | |
| tree | bc5539448262980f9d5ca9d3fdaa25fca03a2368 /src/app.test.ts | |
| parent | d76a46b37b12823b5b3976d129c2d4b672a99693 (diff) | |
Redirect to GitHub with a meta refresh
A browser extension redirects github.com to cgithub with declarative net
requests. Its rules match our HTTP redirects back to github.com too, so
those bounce straight back here and loop forever. A meta refresh makes
cgithub the initiator origin instead, which the extension's rules can
exclude, and its delay leaves a page the user can stop on.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/app.test.ts')
| -rw-r--r-- | src/app.test.ts | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/app.test.ts b/src/app.test.ts new file mode 100644 index 0000000..498d8a6 --- /dev/null +++ b/src/app.test.ts @@ -0,0 +1,50 @@ +import assert from "node:assert"; +import path from "node:path"; +import { describe, it } from "node:test"; +import { Eta } from "eta"; +import { createApp } from "./app.ts"; + +// The routes exercised here redirect without scraping, so no network is needed. +const eta = new Eta({ views: path.join(import.meta.dirname, "..", "views") }); +const app = createApp(eta); + +describe("redirects to GitHub", () => { + // An HTTP redirect would be caught by the extension's declarativeNetRequest + // rules and bounced straight back here. + it("should redirect unknown paths with a meta refresh", async () => { + const res = await app.request("http://cgithub.example/a/b/c?x=1"); + + assert.strictEqual(res.status, 200); + assert.strictEqual(res.headers.get("location"), null); + assert.strictEqual(res.headers.get("Referrer-Policy"), "no-referrer"); + + const body = await res.text(); + assert.match( + body, + /<meta http-equiv="refresh" content="2; url=https:\/\/github.com\/a\/b\/c\?x=1">/, + ); + assert.doesNotMatch(body, /<script/); + }); + + it("should redirect unhandled search types", async () => { + const res = await app.request( + "http://cgithub.example/actions/deploy-pages/search?q=x&type=code", + ); + + assert.strictEqual(res.status, 200); + assert.match( + await res.text(), + /https:\/\/github.com\/actions\/deploy-pages\/search\?q=x&type=code/, + ); + }); + + it("should redirect raw file requests to raw.githubusercontent.com", async () => { + const res = await app.request("http://cgithub.example/actions/deploy-pages/raw/main/README.md"); + + assert.strictEqual(res.status, 200); + assert.match( + await res.text(), + /url=https:\/\/raw.githubusercontent.com\/actions\/deploy-pages\/main\/README.md"/, + ); + }); +}); |
