import { SurrealAdapter } from "@suaveplan/surrealdb"; import { afterAll, beforeAll, describe, expect, it, } from "@suaveplan/testing/runner"; import { SurrealDBFixture } from "@suaveplan/testing-integration-surrealdb"; import { createBetterAuthSurrealAdapter } from "../../src/adapter/adapter.js"; import { betterAuthSurrealAdapter } from "../../src/adapter/v1.6.js"; import { applyBetterAuthSchema } from "../../src/schema/schema.js"; import { runAdapterConformance } from "../../src/testing/run-adapter-conformance.js"; let fixture: SurrealDBFixture | null = null; let client: SurrealAdapter | null = null; beforeAll(async () => { fixture = new SurrealDBFixture(); const cfg = await fixture.start(); client = new SurrealAdapter({ url: cfg.url, namespace: cfg.namespace, database: cfg.database, username: cfg.username, password: cfg.password, }); await client.connect(); // Bootstrap the `user` table — the bundled schema only extends fields. await client.execute("DEFINE TABLE OVERWRITE user SCHEMAFULL;"); await client.execute( "DEFINE FIELD OVERWRITE email ON user TYPE option;" ); await client.execute( "DEFINE FIELD OVERWRITE phoneNumber ON user TYPE option;" ); await applyBetterAuthSchema(client); }, 120_000); afterAll(async () => { if (client) { await client.disconnect(); client = null; } if (fixture) { await fixture.stop(); fixture = null; } }, 60_000); describe("runAdapterConformance pins every Better-Auth scenario against real SurrealDB", () => { it("harness boots before scenarios run (sanity)", { timeout: 5000 }, () => { // The actual conformance scenarios are registered below via the // imported harness. This anchor it() exists to surface clear test // names in the runner output when the harness is empty. }); }); describe("v1.4-shape adapter passes conformance", () => { it("anchor — registers v1.4 conformance block", { timeout: 5000 }, () => { expect(true).toBe(true); }); }); runAdapterConformance(() => { if (client === null) { throw new Error("SurrealAdapter not ready — beforeAll did not run"); } const c = client; return { client: c, adapter: createBetterAuthSurrealAdapter({ client: c }), }; }); /** * v1.6 wrapper smoke conformance — exercises the wrapper's full path from * factory invocation through Better-Auth's `createAdapterFactory` layer. * * The shipped 17-table SurrealDB schema uses column names (e.g. * `verification.val`) that differ from Better-Auth's default in-memory * schema (`verification.value`). Better-Auth's `transformInput` whitelists * fields against the in-memory schema, so the v1.4-shape * `runAdapterConformance` harness — which writes to `val` directly — * cannot be reused verbatim against the v1.6 DBAdapter without a custom * Better-Auth schema override. The end-to-end test in * `better-auth-end-to-end.test.ts` covers the canonical Better-Auth flow * (signUpEmail / signInEmail / getSession) against a real Better-Auth * instance using the wrapper, which is the production signal that * matters. This smoke test asserts the wrapper builds, accepts a valid * Better-Auth `BetterAuthOptions` payload, and exposes every method * Better-Auth invokes. */ describe("v1.6 DBAdapter via wrapper passes conformance", () => { it("factory build + DBAdapter shape smoke check (full flow lives in better-auth-end-to-end.test.ts)", { timeout: 60_000, }, () => { if (client === null) { throw new Error("SurrealAdapter not ready — beforeAll did not run"); } const factory = betterAuthSurrealAdapter({ client }); const dbAdapter = factory({ secret: "test-secret-at-least-32-chars-long-for-better-auth", baseURL: "http://localhost:3000", emailAndPassword: { enabled: true }, } as Parameters[0]); for (const method of [ "create", "findOne", "findMany", "update", "updateMany", "delete", "deleteMany", "count", "consumeOne", "transaction", "createSchema", ]) { expect( typeof (dbAdapter as unknown as Record)[method] ).toBe("function"); } }); });