This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
||||
// The language and the theme a person chooses (spec §10.4): precedence, the cookies that carry a
|
||||
// visitor's choice, and the roles and invitation states the shell words from the catalogues.
|
||||
|
||||
import { describe, expect, it } from "vitest"
|
||||
import { cookieValue, localeOf, themeOf } from "../apps/web/src/server/preferences.js"
|
||||
import { inviteErrorKey } from "../apps/web/src/ui/invite-accept.js"
|
||||
import {
|
||||
LOCALE_COOKIE,
|
||||
PREFERENCE_SECONDS,
|
||||
preferenceCookie,
|
||||
THEME_COOKIE,
|
||||
} from "../apps/web/src/ui/preference-cookies.js"
|
||||
|
||||
describe("the language", () => {
|
||||
it("is the signed-in person's own setting before anything else", () => {
|
||||
expect(
|
||||
localeOf({ appLocale: "en", userLocale: "lt", cookieHeader: `${LOCALE_COOKIE}=en`, acceptLanguage: "en" }),
|
||||
).toBe("lt")
|
||||
})
|
||||
|
||||
it("is a visitor's cookie when nobody is signed in", () => {
|
||||
expect(localeOf({ appLocale: "en", cookieHeader: `a=1; ${LOCALE_COOKIE}=lt; b=2` })).toBe("lt")
|
||||
})
|
||||
|
||||
it("falls to the app's default, then to the browser's, and ignores a language it does not serve", () => {
|
||||
expect(localeOf({ appLocale: "lt" })).toBe("lt")
|
||||
expect(localeOf({ appLocale: "xx", acceptLanguage: "lt-LT,en;q=0.8" })).toBe("lt")
|
||||
expect(localeOf({ appLocale: "en", userLocale: "fr", cookieHeader: `${LOCALE_COOKIE}=de` })).toBe("en")
|
||||
})
|
||||
})
|
||||
|
||||
describe("the theme", () => {
|
||||
it("is dark unless the cookie says light: the brand is dark-first", () => {
|
||||
expect(themeOf(null)).toBe("dark")
|
||||
expect(themeOf(`${THEME_COOKIE}=light`)).toBe("light")
|
||||
expect(themeOf(`${THEME_COOKIE}=dark`)).toBe("dark")
|
||||
expect(themeOf(`${THEME_COOKIE}=neon`)).toBe("dark")
|
||||
})
|
||||
})
|
||||
|
||||
describe("the cookies", () => {
|
||||
it("are written for a year, to every path, and never to another site", () => {
|
||||
expect(preferenceCookie(LOCALE_COOKIE, "lt")).toBe(
|
||||
`app_locale=lt; Path=/; Max-Age=${PREFERENCE_SECONDS}; SameSite=Lax`,
|
||||
)
|
||||
expect(PREFERENCE_SECONDS).toBe(31_536_000)
|
||||
})
|
||||
|
||||
it("read back what was written, and survive a value that is not valid percent-encoding", () => {
|
||||
expect(cookieValue(`x=1; ${preferenceCookie(THEME_COOKIE, "light").split(";")[0]}`, THEME_COOKIE)).toBe("light")
|
||||
expect(cookieValue("app_locale=%E0%A4%A", LOCALE_COOKIE)).toBeUndefined()
|
||||
expect(cookieValue(undefined, LOCALE_COOKIE)).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe("an invitation's states", () => {
|
||||
it.each([
|
||||
["not_found", "invalid"],
|
||||
["invitation_used", "used"],
|
||||
["invitation_expired", "expired"],
|
||||
["already_member", "member"],
|
||||
["conflict", "failed"],
|
||||
["rate_limited", "failed"],
|
||||
["", "failed"],
|
||||
] as const)("words the code %j as %s", (code, key) => {
|
||||
expect(inviteErrorKey(code)).toBe(key)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user