132 lines
4.3 KiB
TypeScript
132 lines
4.3 KiB
TypeScript
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 { applyBetterAuthSchema } from "../../src/schema/schema.js";
|
|
|
|
let fixture: SurrealDBFixture | null = null;
|
|
let client: SurrealAdapter | null = null;
|
|
let adapter: ReturnType<typeof createBetterAuthSurrealAdapter>;
|
|
|
|
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();
|
|
await applyBetterAuthSchema(client);
|
|
// Bootstrap the user table — schema only extends it.
|
|
await client.execute("DEFINE TABLE OVERWRITE user SCHEMAFULL;");
|
|
await client.execute(
|
|
"DEFINE FIELD OVERWRITE email ON user TYPE option<string>;"
|
|
);
|
|
await client.execute(
|
|
"DEFINE FIELD OVERWRITE phoneNumber ON user TYPE option<string>;"
|
|
);
|
|
adapter = createBetterAuthSurrealAdapter({ client });
|
|
}, 120_000);
|
|
|
|
afterAll(async () => {
|
|
if (client) {
|
|
await client.disconnect();
|
|
client = null;
|
|
}
|
|
if (fixture) {
|
|
await fixture.stop();
|
|
fixture = null;
|
|
}
|
|
}, 60_000);
|
|
|
|
describe("schema write compatibility", () => {
|
|
it("applied schema accepts canonical Better-Auth row writes", {
|
|
timeout: 60000,
|
|
}, async () => {
|
|
await adapter.create({
|
|
model: "user",
|
|
data: {
|
|
id: "u_compat_1",
|
|
email: "compat@x",
|
|
emailVerified: false,
|
|
} as unknown as Record<string, unknown>,
|
|
});
|
|
|
|
// session — record<user> userId
|
|
const session = (await adapter.create({
|
|
model: "session",
|
|
data: {
|
|
id: "s_compat_1",
|
|
userId: "u_compat_1",
|
|
token: "tok",
|
|
} as unknown as Record<string, unknown>,
|
|
})) as { id: string; userId: string };
|
|
expect(session.userId).toBe("u_compat_1");
|
|
|
|
// account — string userId
|
|
const account = (await adapter.create({
|
|
model: "account",
|
|
data: {
|
|
id: "a_compat_1",
|
|
userId: "u_compat_1",
|
|
providerId: "p",
|
|
accountId: "a",
|
|
password: "",
|
|
} as unknown as Record<string, unknown>,
|
|
})) as { id: string; userId: string };
|
|
expect(account.userId).toBe("u_compat_1");
|
|
|
|
// organization + member — record<user>, record<organization>
|
|
await adapter.create({
|
|
model: "organization",
|
|
data: {
|
|
id: "o_compat_1",
|
|
name: "Acme",
|
|
slug: "acme-compat",
|
|
} as unknown as Record<string, unknown>,
|
|
});
|
|
const member = (await adapter.create({
|
|
model: "member",
|
|
data: {
|
|
id: "m_compat_1",
|
|
userId: "u_compat_1",
|
|
organizationId: "o_compat_1",
|
|
role: "admin",
|
|
} as unknown as Record<string, unknown>,
|
|
})) as { userId: string; organizationId: string };
|
|
expect(member.userId).toBe("u_compat_1");
|
|
expect(member.organizationId).toBe("o_compat_1");
|
|
|
|
// oauth_access_token — string userId (not in default linkFields)
|
|
const tok = (await adapter.create({
|
|
model: "oauth_access_token",
|
|
data: {
|
|
id: "t_compat_1",
|
|
userId: "u_compat_1",
|
|
accessToken: "a",
|
|
refreshToken: "r",
|
|
} as unknown as Record<string, unknown>,
|
|
})) as { userId: string };
|
|
expect(tok.userId).toBe("u_compat_1");
|
|
});
|
|
|
|
it("applyBetterAuthSchema is idempotent against real SurrealDB", {
|
|
timeout: 60000,
|
|
}, async () => {
|
|
if (!client) throw new Error("client not ready");
|
|
await applyBetterAuthSchema(client);
|
|
await applyBetterAuthSchema(client);
|
|
// Re-application succeeds; idempotency proven by no throw.
|
|
expect(true).toBe(true);
|
|
});
|
|
});
|