Files
local-cal/tests/auth.test.ts

197 lines
6.6 KiB
TypeScript

import { describe, expect, test } from "bun:test";
// ---------------------------------------------------------------------------
// Slice 1: buildSocialProviders — conditional provider registration
//
// Public interface under test: buildSocialProviders(env) → object
// Behaviour: only registers providers whose env vars are all present.
// ---------------------------------------------------------------------------
import { buildSocialProviders } from "@/lib/build-social-providers";
describe("buildSocialProviders", () => {
test("returns empty object when no OAuth env vars are set", () => {
const result = buildSocialProviders({});
expect(result).toEqual({});
});
test("registers google when both Google vars are present", () => {
const result = buildSocialProviders({
AUTH_GOOGLE_CLIENT_ID: "gid",
AUTH_GOOGLE_CLIENT_SECRET: "gsecret",
});
expect(result).toHaveProperty("google");
expect(result.google).toMatchObject({
clientId: "gid",
clientSecret: "gsecret",
});
});
test("does NOT register google when only clientId is present", () => {
const result = buildSocialProviders({
AUTH_GOOGLE_CLIENT_ID: "gid",
});
expect(result).not.toHaveProperty("google");
});
test("does NOT register google when only clientSecret is present", () => {
const result = buildSocialProviders({
AUTH_GOOGLE_CLIENT_SECRET: "gsecret",
});
expect(result).not.toHaveProperty("google");
});
test("registers apple when all four Apple vars are present", () => {
const result = buildSocialProviders({
AUTH_APPLE_CLIENT_ID: "aid",
AUTH_APPLE_CLIENT_SECRET: "asecret",
AUTH_APPLE_TEAM_ID: "TEAM1",
AUTH_APPLE_KEY_ID: "KEY1",
AUTH_APPLE_PRIVATE_KEY: "-----BEGIN PRIVATE KEY-----\nfake\n-----END PRIVATE KEY-----",
});
expect(result).toHaveProperty("apple");
expect(result.apple).toMatchObject({
clientId: "aid",
clientSecret: "asecret",
});
});
test("does NOT register apple when any Apple var is missing", () => {
const result = buildSocialProviders({
AUTH_APPLE_CLIENT_ID: "aid",
AUTH_APPLE_CLIENT_SECRET: "asecret",
AUTH_APPLE_TEAM_ID: "TEAM1",
// AUTH_APPLE_KEY_ID missing
AUTH_APPLE_PRIVATE_KEY: "-----BEGIN PRIVATE KEY-----\nfake\n-----END PRIVATE KEY-----",
});
expect(result).not.toHaveProperty("apple");
});
test("registers both google and apple when all vars are present", () => {
const result = buildSocialProviders({
AUTH_GOOGLE_CLIENT_ID: "gid",
AUTH_GOOGLE_CLIENT_SECRET: "gsecret",
AUTH_APPLE_CLIENT_ID: "aid",
AUTH_APPLE_CLIENT_SECRET: "asecret",
AUTH_APPLE_TEAM_ID: "TEAM1",
AUTH_APPLE_KEY_ID: "KEY1",
AUTH_APPLE_PRIVATE_KEY: "-----BEGIN PRIVATE KEY-----\nfake\n-----END PRIVATE KEY-----",
});
expect(result).toHaveProperty("google");
expect(result).toHaveProperty("apple");
});
});
// ---------------------------------------------------------------------------
// Slice 2: auth-client — signIn.social is available
//
// Public interface under test: authClient.signIn.social
// Behaviour: the function exists and is callable (no plugin wiring needed
// for socialProviders on the client — it's built into createAuthClient).
// ---------------------------------------------------------------------------
import { authClient } from "@/lib/auth-client";
describe("authClient", () => {
test("exposes signIn.social as a function", () => {
expect(typeof authClient.signIn.social).toBe("function");
});
test("exposes useSession hook", () => {
expect(typeof authClient.useSession).toBe("function");
});
});
// ---------------------------------------------------------------------------
// Slice 3: getSignInProviders — sign-in page provider list
//
// Public interface under test: getSignInProviders()
// Behaviour: returns the ordered list of available sign-in providers with
// their labels and ids, based on which env vars are configured.
// The component consumes this list to render buttons — testing the list
// verifies the button-to-provider mapping without needing a DOM.
// ---------------------------------------------------------------------------
import { getSignInProviders } from "@/lib/get-sign-in-providers";
describe("getSignInProviders", () => {
test("returns authentik when Authentik vars are set", () => {
const providers = getSignInProviders({
AUTH_AUTHENTIK_CLIENT_ID: "id",
AUTH_AUTHENTIK_CLIENT_SECRET: "secret",
AUTH_AUTHENTIK_ISSUER: "https://auth.example.com",
});
const ids = providers.map((p) => p.id);
expect(ids).toContain("authentik");
});
test("returns google when Google vars are set", () => {
const providers = getSignInProviders({
AUTH_GOOGLE_CLIENT_ID: "gid",
AUTH_GOOGLE_CLIENT_SECRET: "gsecret",
});
const ids = providers.map((p) => p.id);
expect(ids).toContain("google");
});
test("returns apple when Apple vars are set", () => {
const providers = getSignInProviders({
AUTH_APPLE_CLIENT_ID: "aid",
AUTH_APPLE_CLIENT_SECRET: "asecret",
AUTH_APPLE_TEAM_ID: "TEAM1",
AUTH_APPLE_KEY_ID: "KEY1",
AUTH_APPLE_PRIVATE_KEY: "-----BEGIN PRIVATE KEY-----\nfake\n-----END PRIVATE KEY-----",
});
const ids = providers.map((p) => p.id);
expect(ids).toContain("apple");
});
test("returns empty list when no vars are set", () => {
const providers = getSignInProviders({});
expect(providers).toHaveLength(0);
});
test("each provider has id, label, and signInMethod", () => {
const providers = getSignInProviders({
AUTH_GOOGLE_CLIENT_ID: "gid",
AUTH_GOOGLE_CLIENT_SECRET: "gsecret",
});
expect(providers[0]).toMatchObject({
id: expect.any(String),
label: expect.any(String),
signInMethod: expect.any(String),
});
});
test("google provider uses 'social' signInMethod", () => {
const providers = getSignInProviders({
AUTH_GOOGLE_CLIENT_ID: "gid",
AUTH_GOOGLE_CLIENT_SECRET: "gsecret",
});
const google = providers.find((p) => p.id === "google");
expect(google?.signInMethod).toBe("social");
});
test("apple provider uses 'social' signInMethod", () => {
const providers = getSignInProviders({
AUTH_APPLE_CLIENT_ID: "aid",
AUTH_APPLE_CLIENT_SECRET: "asecret",
AUTH_APPLE_TEAM_ID: "TEAM1",
AUTH_APPLE_KEY_ID: "KEY1",
AUTH_APPLE_PRIVATE_KEY: "-----BEGIN PRIVATE KEY-----\nfake\n-----END PRIVATE KEY-----",
});
const apple = providers.find((p) => p.id === "apple");
expect(apple?.signInMethod).toBe("social");
});
test("authentik provider uses 'oauth2' signInMethod", () => {
const providers = getSignInProviders({
AUTH_AUTHENTIK_CLIENT_ID: "id",
AUTH_AUTHENTIK_CLIENT_SECRET: "secret",
AUTH_AUTHENTIK_ISSUER: "https://auth.example.com",
});
const authentik = providers.find((p) => p.id === "authentik");
expect(authentik?.signInMethod).toBe("oauth2");
});
});