import { describe, expect, it } from "vitest"; import { buildSocialSignInRequest } from "@/client/lib/social"; // The body shape sent to /api/sign-in/social. The contract is: // - turnstileToken is always required and round-trips verbatim. // - oauth_query is forwarded as a top-level field if and only if the user // came from an RP-initiated /authorize redirect. // - The wrapper handler attaches `additionalData.oauth_query` server-side // so oauth-provider's before-hook can capture it into oAuthState; the // client-facing body keeps oauth_query at the top level so the wrapper // has explicit ownership of the upstream Better Auth shape. describe("buildSocialSignInRequest", () => { it("omits oauth_query when there is no signed query", () => { const body = buildSocialSignInRequest({ provider: "github", callbackURL: "/account", errorCallbackURL: "/sign-in?error=social_unavailable", turnstileToken: "tk-abc", oauthQuery: null, }); expect(body).toEqual({ provider: "github", callbackURL: "/account", errorCallbackURL: "/sign-in?error=social_unavailable", turnstileToken: "tk-abc", }); expect("oauth_query" in body).toBe(false); }); it("forwards oauth_query at the top level when present", () => { const oauthQuery = "client_id=abc&response_type=code&state=xyz&sig=signed"; const body = buildSocialSignInRequest({ provider: "google", callbackURL: "/account", errorCallbackURL: "/sign-in?error=social_unavailable", turnstileToken: "tk-xyz", oauthQuery, }); expect(body.provider).toBe("google"); expect(body.callbackURL).toBe("/account"); expect(body.errorCallbackURL).toBe("/sign-in?error=social_unavailable"); expect(body.turnstileToken).toBe("tk-xyz"); expect(body.oauth_query).toBe(oauthQuery); }); it("treats empty-string oauthQuery as none", () => { const body = buildSocialSignInRequest({ provider: "github", callbackURL: "/account", errorCallbackURL: "/sign-in", turnstileToken: "tk-empty", oauthQuery: "", }); expect(body.oauth_query).toBeUndefined(); }); });