aboutsummaryrefslogtreecommitdiff
path: root/castle-search/test/google-links.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'castle-search/test/google-links.test.ts')
-rw-r--r--castle-search/test/google-links.test.ts41
1 files changed, 41 insertions, 0 deletions
diff --git a/castle-search/test/google-links.test.ts b/castle-search/test/google-links.test.ts
new file mode 100644
index 0000000..f31f112
--- /dev/null
+++ b/castle-search/test/google-links.test.ts
@@ -0,0 +1,41 @@
+import assert from "node:assert/strict";
+import { test } from "node:test";
+
+import { formatResults } from "../src/format.ts";
+import { isGoogleGoto } from "../src/google-links.ts";
+import { getEngine } from "../src/engines.ts";
+import { resolveLink } from "../src/search.ts";
+
+test("only well-formed google /goto links count", () => {
+ assert.equal(isGoogleGoto("https://www.google.com/goto?url=CAESabc_-9"), true);
+ assert.equal(isGoogleGoto("https://www.google.co.uk/goto?url=CAESabc"), true);
+ assert.equal(isGoogleGoto("https://www.google.com/search?q=x"), false);
+ assert.equal(isGoogleGoto("https://example.com/goto?url=CAES"), false);
+ // Not a general navigator: nothing may ride along after the token.
+ assert.equal(isGoogleGoto("https://www.google.com/goto?url=CAES&x=https://evil.example"), false);
+ assert.equal(isGoogleGoto("https://www.google.com.evil.example/goto?url=CAES"), false);
+});
+
+test("the google self-host filter lets /goto through but still blocks google's own pages", () => {
+ const re = new RegExp(getEngine("google").extraction.selfHostPattern);
+ assert.equal(re.test("https://www.google.com/goto?url=CAES"), false);
+ assert.equal(re.test("https://www.google.com/search?q=x"), true);
+ assert.equal(re.test("https://accounts.google.com/ServiceLogin"), false);
+});
+
+test("resolveLink refuses anything that is not a google /goto link, before touching the browser", async () => {
+ await assert.rejects(() => resolveLink("https://example.com/", AbortSignal.timeout(1000)), /only follows Google result links/);
+ await assert.rejects(() => resolveLink("file:///etc/passwd", AbortSignal.timeout(1000)), /only follows Google result links/);
+});
+
+test("a wrapped result says so, shows Google's breadcrumb, and names the tool to resolve it", () => {
+ const text = formatResults({
+ query: "q", searchUrl: "u", finalUrl: "u", endpoint: "e", engine: "Google", engineSource: "s",
+ results: [
+ { title: "Wrapped", url: "https://www.google.com/goto?url=CAES", snippet: "snip", display: "GitHub — https://github.com › a › b" },
+ { title: "Direct", url: "https://example.com/", snippet: "" },
+ ],
+ });
+ assert.match(text, /\[Google-wrapped link, real URL not yet known\. Google shows it as: GitHub — https:\/\/github\.com › a › b\. Pass it to castle_cdp_resolve/);
+ assert.equal((text.match(/Google-wrapped/g) ?? []).length, 1);
+});