// 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, panelWidthOf, sidebarOpenOf, 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 browser's language when it names one the app serves, then to the app's default", () => { // A Lithuanian app and an English browser: English, and the other way round. expect(localeOf({ appLocale: "lt", acceptLanguage: "en-GB,en;q=0.9" })).toBe("en") expect(localeOf({ appLocale: "en", acceptLanguage: "lt-LT,en;q=0.8" })).toBe("lt") // The browser's own order, by weight, among the languages the app serves. expect(localeOf({ appLocale: "en", acceptLanguage: "en;q=0.4,lt;q=0.9" })).toBe("lt") expect(localeOf({ appLocale: "lt", acceptLanguage: "fr-FR,de;q=0.9,en;q=0.1" })).toBe("en") // A browser that names none of them, or none at all: the app's default. expect(localeOf({ appLocale: "lt", acceptLanguage: "fr-FR,de;q=0.9" })).toBe("lt") 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") }) it("keeps a person's or a visitor's own choice before the browser's", () => { expect(localeOf({ appLocale: "lt", userLocale: "lt", acceptLanguage: "en-GB" })).toBe("lt") expect(localeOf({ appLocale: "lt", cookieHeader: `${LOCALE_COOKIE}=lt`, acceptLanguage: "en-GB" })).toBe("lt") }) }) 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}=system`)).toBe("system") 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_revoked", "revoked"], ["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) }) }) describe("the frame's layout", () => { it("opens the sidebar unless the person closed it", () => { expect(sidebarOpenOf(null)).toBe(true) expect(sidebarOpenOf("app_sidebar=open")).toBe(true) expect(sidebarOpenOf("app_sidebar=closed")).toBe(false) }) it("keeps the panel's width only inside what the panel can take", () => { expect(panelWidthOf(null)).toBeUndefined() expect(panelWidthOf("app_panel_width=480")).toBe(480) expect(panelWidthOf("app_panel_width=9000")).toBeUndefined() expect(panelWidthOf("app_panel_width=wide")).toBeUndefined() }) })