From a36052f485df0916e515ec98ce08fbbf323d2593 Mon Sep 17 00:00:00 2001 From: Seoa Yoon Date: Sat, 1 Aug 2026 15:29:08 +0900 Subject: [PATCH 1/6] Fix fedify/next test-each failure - add next as dependency and deno.json - skip Deno tests for packages without deno.json - add test scripts in next/package.json Assisted-by: OpenCode:gpt-5.6-terra --- mise.toml | 10 +++++++--- packages/next/package.json | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/mise.toml b/mise.toml index fa64e5194..f8231f597 100644 --- a/mise.toml +++ b/mise.toml @@ -304,11 +304,15 @@ shell = "nu -c" run = ''' let pkgs = ($env.usage_packages | split row " " | where ($it | is-not-empty)) mise run prepare-each ...$pkgs -mise run check-each ...$pkgs for pkg in $pkgs { - print $"Running tests for package: ($pkg)" - deno task --filter $"@fedify/($pkg)" test + if ($"packages/($pkg)/deno.json" | path exists) { + mise run check-each $pkg + print $"Running Deno tests for package: ($pkg)" + deno task --filter $"@fedify/($pkg)" test + } + print $"Running Node.js tests for package: ($pkg)" pnpm --filter $"@fedify/($pkg)" test + print $"Running Bun tests for package: ($pkg)" pnpm --filter $"@fedify/($pkg)" test:bun } ''' diff --git a/packages/next/package.json b/packages/next/package.json index 2401b777c..e32df431f 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -58,6 +58,8 @@ "build:self": "tsdown", "build": "pnpm --filter @fedify/next... run build:self", "prepack": "pnpm build", - "prepublish": "pnpm build" + "prepublish": "pnpm build", + "test": "node --experimental-transform-types --test", + "test:bun": "bun test" } } From 6a91433c1f71bf80e27e90cc2e41ab01decde245 Mon Sep 17 00:00:00 2001 From: Seoa Yoon Date: Sat, 1 Aug 2026 13:39:26 +0900 Subject: [PATCH 2/6] Add Accept header detection test in fedify/next --- packages/next/src/index.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 packages/next/src/index.test.ts diff --git a/packages/next/src/index.test.ts b/packages/next/src/index.test.ts new file mode 100644 index 000000000..5fa6ebf6a --- /dev/null +++ b/packages/next/src/index.test.ts @@ -0,0 +1,13 @@ +import { test } from "@fedify/fixture"; +import { strict as assert } from "node:assert"; +import { isFederationRequest } from "./index.ts"; + +test("Accept header detection", () => { + const request = new Request("https://example.com/", { + headers: { + Accept: "application/activity+json", + }, + }); + + assert.strictEqual(isFederationRequest(request), true); +}); From e3212caaa51b2c6aefb5a44e235955f10a41e7a4 Mon Sep 17 00:00:00 2001 From: Seoa Yoon Date: Sat, 1 Aug 2026 13:40:09 +0900 Subject: [PATCH 3/6] Add Content-Type header detection test in fedify/next --- packages/next/src/index.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/next/src/index.test.ts b/packages/next/src/index.test.ts index 5fa6ebf6a..63be19eb3 100644 --- a/packages/next/src/index.test.ts +++ b/packages/next/src/index.test.ts @@ -11,3 +11,14 @@ test("Accept header detection", () => { assert.strictEqual(isFederationRequest(request), true); }); + +test("Content-Type header detection", () => { + const request = new Request("https://example.com/", { + method: "POST", + headers: { + "Content-Type": "application/activity+json", + }, + }); + + assert.strictEqual(isFederationRequest(request), true); +}); From 39c65d504e64fdd0a5b98f6d888efcf40be916e1 Mon Sep 17 00:00:00 2001 From: Seoa Yoon Date: Sat, 1 Aug 2026 15:06:03 +0900 Subject: [PATCH 4/6] Add NodeInfo route detection test in fedify/next --- packages/next/src/index.test.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/next/src/index.test.ts b/packages/next/src/index.test.ts index 63be19eb3..6ee1a438a 100644 --- a/packages/next/src/index.test.ts +++ b/packages/next/src/index.test.ts @@ -1,6 +1,6 @@ import { test } from "@fedify/fixture"; import { strict as assert } from "node:assert"; -import { isFederationRequest } from "./index.ts"; +import { isFederationRequest, isNodeInfoRequest } from "./index.ts"; test("Accept header detection", () => { const request = new Request("https://example.com/", { @@ -22,3 +22,15 @@ test("Content-Type header detection", () => { assert.strictEqual(isFederationRequest(request), true); }); + +test("NodeInfo route detection", () => { + const request1 = new Request("https://example.com/.well-known/nodeinfo", {}); + + const request2 = new Request( + "https://example.com/.well-known/x-nodeinfo2", + {}, + ); + + assert.strictEqual(isNodeInfoRequest(request1), true); + assert.strictEqual(isNodeInfoRequest(request2), true); +}); From c63b718f934dfb6b4b2184904a54cf2b22d45bfb Mon Sep 17 00:00:00 2001 From: Seoa Yoon Date: Sat, 1 Aug 2026 15:45:01 +0900 Subject: [PATCH 5/6] Add non-federation request delegation test in fedify/next --- packages/next/src/index.test.ts | 42 ++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/next/src/index.test.ts b/packages/next/src/index.test.ts index 6ee1a438a..49a5565ea 100644 --- a/packages/next/src/index.test.ts +++ b/packages/next/src/index.test.ts @@ -1,6 +1,11 @@ +import { + createFederation, + InProcessMessageQueue, + MemoryKvStore, +} from "@fedify/fedify"; import { test } from "@fedify/fixture"; import { strict as assert } from "node:assert"; -import { isFederationRequest, isNodeInfoRequest } from "./index.ts"; +import { fedifyWith, isFederationRequest, isNodeInfoRequest } from "./index.ts"; test("Accept header detection", () => { const request = new Request("https://example.com/", { @@ -34,3 +39,38 @@ test("NodeInfo route detection", () => { assert.strictEqual(isNodeInfoRequest(request1), true); assert.strictEqual(isNodeInfoRequest(request2), true); }); + +test("Non-federation request delegation", async () => { + const federation = createFederation({ + kv: new MemoryKvStore(), + queue: new InProcessMessageQueue(), + }); + const customMiddleware = (request: Request) => { + if (request.url === "https://example.com/test") { + return new Response("Custom middleware response"); + } + return new Response("Default response"); + }; + const middleware = fedifyWith(federation)(customMiddleware); + + const request = new Request("https://example.com/", { + headers: { + Accept: "text/html", + }, + }); + + const request2 = new Request("https://example.com/test", { + headers: { + Accept: "text/html", + }, + }); + + assert.strictEqual(isFederationRequest(request), false); + assert.strictEqual(isFederationRequest(request2), false); + + const response1 = await middleware(request); + const response2 = await middleware(request2); + + assert.strictEqual(await response1.text(), "Default response"); + assert.strictEqual(await response2.text(), "Custom middleware response"); +}); From fe605d11d2160e0d39714fc245df494dcf84dae6 Mon Sep 17 00:00:00 2001 From: Seoa Yoon Date: Sat, 1 Aug 2026 15:51:08 +0900 Subject: [PATCH 6/6] Add custom not found/not acceptable handler Assisted-by: OpenCode:gpt-5.6-terra --- packages/next/src/index.test.ts | 41 ++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/next/src/index.test.ts b/packages/next/src/index.test.ts index 49a5565ea..430d32da2 100644 --- a/packages/next/src/index.test.ts +++ b/packages/next/src/index.test.ts @@ -5,7 +5,12 @@ import { } from "@fedify/fedify"; import { test } from "@fedify/fixture"; import { strict as assert } from "node:assert"; -import { fedifyWith, isFederationRequest, isNodeInfoRequest } from "./index.ts"; +import { + fedifyWith, + integrateFederation, + isFederationRequest, + isNodeInfoRequest, +} from "./index.ts"; test("Accept header detection", () => { const request = new Request("https://example.com/", { @@ -74,3 +79,37 @@ test("Non-federation request delegation", async () => { assert.strictEqual(await response1.text(), "Default response"); assert.strictEqual(await response2.text(), "Custom middleware response"); }); + +test("Custom not-found/not acceptable handler", async () => { + const federation = createFederation({ + kv: new MemoryKvStore(), + queue: new InProcessMessageQueue(), + }); + + // Set up a dispatcher that always returns null to simulate a not acceptable scenario + federation.setActorDispatcher("/users/{identifier}", () => null); + + const handler = integrateFederation(federation, undefined, { + onNotFound: () => new Response("Custom not found", { status: 418 }), + onNotAcceptable: () => + new Response("Custom not acceptable", { status: 418 }), + }); + + const response1 = await handler( + new Request("https://example.com/missing", { + headers: { Accept: "application/activity+json" }, + }), + ); + + assert.strictEqual(response1.status, 418); + assert.strictEqual(await response1.text(), "Custom not found"); + + const response2 = await handler( + new Request("https://example.com/users/123", { + headers: { Accept: "text/html" }, + }), + ); + + assert.strictEqual(response2.status, 418); + assert.strictEqual(await response2.text(), "Custom not acceptable"); +});