Last active
July 12, 2024 11:50
-
-
Save ellemedit/33e02ee544cbcd076c94f2157e68a5cc to your computer and use it in GitHub Desktop.
NextJS App Router cookie module mock with Bun/TypeScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { mock } from "bun:test"; | |
import { ReadonlyRequestCookies } from "next/dist/server/web/spec-extension/adapters/request-cookies"; | |
export function mockNextjsReadonlyCookie() { | |
mock.module("next/headers", () => { | |
const cookieMap = new Map<string, { name: string; value: string }>(); | |
const cookies: ReadonlyRequestCookies = { | |
get: (nameOrCookie: string | { name: string }) => { | |
const name = | |
typeof nameOrCookie === "string" ? nameOrCookie : nameOrCookie.name; | |
const cookie = cookieMap.get(name); | |
return cookie ? { name: cookie.name, value: cookie.value } : undefined; | |
}, | |
has: (nameOrCookie: string | { name: string }) => { | |
const name = | |
typeof nameOrCookie === "string" ? nameOrCookie : nameOrCookie.name; | |
return cookieMap.has(name); | |
}, | |
set: () => { | |
throw new Error( | |
"You should not set cookies in readonly mode like Server Component or Data Access Layer", | |
); | |
}, | |
delete: () => { | |
throw new Error( | |
"You should not set cookies in readonly mode like Server Component or Data Access Layer", | |
); | |
}, | |
get size() { | |
return cookieMap.size; | |
}, | |
getAll: (...args: Array<string | { name: string }> | []) => { | |
if (args.length === 0) { | |
return Array.from(cookieMap.values()); | |
} | |
const names = new Set( | |
args.map((arg) => (typeof arg === "string" ? arg : arg.name)), | |
); | |
return Array.from(cookieMap.values()).filter((cookie) => | |
names.has(cookie.name), | |
); | |
}, | |
[Symbol.iterator]: () => cookieMap.entries(), | |
}; | |
return { | |
cookies: () => cookies, | |
headers: () => { | |
throw new Error("not implemented yet, mock this"); | |
}, | |
draftMode: () => { | |
throw new Error("not implemented yet, mock this"); | |
}, | |
}; | |
}); | |
} | |
export function mockNextjsMutableCookie() { | |
mock.module("next/headers", () => { | |
const cookieMap = new Map<string, { name: string; value: string }>(); | |
const cookies: ReadonlyRequestCookies = { | |
get: (nameOrCookie: string | { name: string }) => { | |
const name = | |
typeof nameOrCookie === "string" ? nameOrCookie : nameOrCookie.name; | |
const cookie = cookieMap.get(name); | |
return cookie ? { name: cookie.name, value: cookie.value } : undefined; | |
}, | |
has: (nameOrCookie: string | { name: string }) => { | |
const name = | |
typeof nameOrCookie === "string" ? nameOrCookie : nameOrCookie.name; | |
return cookieMap.has(name); | |
}, | |
set: (...args: [string, string] | [{ name: string; value: string }]) => { | |
if (typeof args[0] === "string") { | |
cookieMap.set(args[0], { name: args[0], value: args[1]! }); | |
} else if (typeof args[0] === "object") { | |
const cookie = args[0]; | |
cookieMap.set(cookie.name, cookie); | |
} else { | |
throw new Error("Invalid cookie set or mock bug"); | |
} | |
return cookies; | |
}, | |
delete: (nameOrCookie: string | { name: string }) => { | |
const name = | |
typeof nameOrCookie === "string" ? nameOrCookie : nameOrCookie.name; | |
if (cookieMap.has(name)) { | |
cookieMap.set(name, { name, value: "" }); | |
} | |
return cookies; | |
}, | |
get size() { | |
return cookieMap.size; | |
}, | |
getAll: (...args: Array<string | { name: string }> | []) => { | |
if (args.length === 0) { | |
return Array.from(cookieMap.values()); | |
} | |
const names = new Set( | |
args.map((arg) => (typeof arg === "string" ? arg : arg.name)), | |
); | |
return Array.from(cookieMap.values()).filter((cookie) => | |
names.has(cookie.name), | |
); | |
}, | |
[Symbol.iterator]: () => cookieMap.entries(), | |
}; | |
return { | |
cookies: () => cookies, | |
headers: () => { | |
throw new Error("not implemented yet, mock this"); | |
}, | |
draftMode: () => { | |
throw new Error("not implemented yet, mock this"); | |
}, | |
}; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment