80 lines
4.7 KiB
TypeScript
80 lines
4.7 KiB
TypeScript
import { expect } from "bun:test";
|
|
import type { Db } from "@stc/db";
|
|
import { bunSqlAdapter } from "../src/server/auth/adapter";
|
|
import { forEachDb } from "./helpers";
|
|
|
|
// biome-ignore lint/suspicious/noExplicitAny: adapter is generic over Better Auth options
|
|
const make = (db: Db): any => bunSqlAdapter(db)({});
|
|
|
|
async function seed(a: ReturnType<typeof make>) {
|
|
const people = [
|
|
{ name: "Ada", email: "[email protected]", emailVerified: true },
|
|
{ name: "Bob", email: "[email protected]", emailVerified: false },
|
|
{ name: "Cyd", email: "[email protected]", emailVerified: false },
|
|
];
|
|
const out = [];
|
|
for (const p of people) out.push(await a.create({ model: "user", data: { ...p, createdAt: new Date(), updatedAt: new Date() } }));
|
|
return out;
|
|
}
|
|
|
|
forEachDb("adapter create and findOne round-trip types", async (db) => {
|
|
const a = make(db);
|
|
const [ada] = await seed(a);
|
|
expect(typeof ada.id).toBe("string");
|
|
const found = await a.findOne({ model: "user", where: [{ field: "email", value: "[email protected]" }] });
|
|
expect(found.name).toBe("Ada");
|
|
expect(found.emailVerified).toBe(true);
|
|
expect(found.createdAt).toBeInstanceOf(Date);
|
|
expect(await a.findOne({ model: "user", where: [{ field: "email", value: "nobody@x" }] })).toBeNull();
|
|
});
|
|
|
|
forEachDb("adapter where operators", async (db) => {
|
|
const a = make(db);
|
|
await seed(a);
|
|
const names = async (where: unknown[], extra: Record<string, unknown> = {}) =>
|
|
(await a.findMany({ model: "user", where, sortBy: { field: "name", direction: "asc" }, ...extra })).map((u: { name: string }) => u.name);
|
|
expect(await names([{ field: "name", operator: "ne", value: "Ada" }])).toEqual(["Bob", "Cyd"]);
|
|
expect(await names([{ field: "name", operator: "in", value: ["Ada", "Cyd"] }])).toEqual(["Ada", "Cyd"]);
|
|
expect(await names([{ field: "name", operator: "not_in", value: ["Ada"] }])).toEqual(["Bob", "Cyd"]);
|
|
expect(await names([{ field: "name", operator: "in", value: [] }])).toEqual([]);
|
|
expect(await names([{ field: "email", operator: "contains", value: "example" }])).toEqual(["Ada", "Cyd"]);
|
|
expect(await names([{ field: "email", operator: "contains", value: "Example" }])).toEqual(["Bob"]);
|
|
expect(await names([{ field: "email", operator: "contains", value: "EXAMPLE.ORG", mode: "insensitive" }])).toEqual(["Bob"]);
|
|
expect(await names([{ field: "email", operator: "starts_with", value: "cy" }])).toEqual(["Cyd"]);
|
|
expect(await names([{ field: "email", operator: "ends_with", value: ".com" }])).toEqual(["Ada", "Cyd"]);
|
|
expect(await names([{ field: "email", value: "[email protected]", mode: "insensitive" }])).toEqual(["Bob"]);
|
|
expect(await names([{ field: "name", operator: "gt", value: "Ada" }])).toEqual(["Bob", "Cyd"]);
|
|
expect(await names([{ field: "name", operator: "lte", value: "Bob" }])).toEqual(["Ada", "Bob"]);
|
|
expect(await names([{ field: "emailVerified", value: false }])).toEqual(["Bob", "Cyd"]);
|
|
// AND clauses AND-ed, OR clauses grouped
|
|
expect(await names([
|
|
{ field: "emailVerified", value: false },
|
|
{ field: "name", value: "Ada", connector: "OR" },
|
|
{ field: "name", value: "Cyd", connector: "OR" },
|
|
])).toEqual(["Cyd"]);
|
|
expect(await names([], { limit: 1, offset: 1 })).toEqual(["Bob"]);
|
|
expect(await names([], { limit: 2, sortBy: { field: "name", direction: "desc" } })).toEqual(["Cyd", "Bob"]);
|
|
expect(await names([{ field: "image", value: null }])).toEqual(["Ada", "Bob", "Cyd"]);
|
|
});
|
|
|
|
forEachDb("adapter update, count, delete, consume, increment", async (db) => {
|
|
const a = make(db);
|
|
const [ada, bob] = await seed(a);
|
|
const up = await a.update({ model: "user", where: [{ field: "id", value: ada.id }], update: { name: "Ada L." } });
|
|
expect(up.name).toBe("Ada L.");
|
|
expect(await a.updateMany({ model: "user", where: [{ field: "emailVerified", value: false }], update: { image: "x.png" } })).toBe(2);
|
|
expect(await a.count({ model: "user", where: [{ field: "image", value: "x.png" }] })).toBe(2);
|
|
expect(await a.count({ model: "user" })).toBe(3);
|
|
await a.delete({ model: "user", where: [{ field: "id", value: bob.id }] });
|
|
expect(await a.count({ model: "user" })).toBe(2);
|
|
expect(await a.deleteMany({ model: "user", where: [{ field: "image", value: "x.png" }] })).toBe(1);
|
|
|
|
const exp = new Date(Date.now() + 60_000);
|
|
await a.create({ model: "verification", data: { identifier: "k", value: "v1", expiresAt: exp, createdAt: new Date(), updatedAt: new Date() } });
|
|
const consumed = await a.consumeOne({ model: "verification", where: [{ field: "identifier", value: "k" }] });
|
|
expect(consumed?.value).toBe("v1");
|
|
expect(await a.consumeOne({ model: "verification", where: [{ field: "identifier", value: "k" }] })).toBeNull();
|
|
const live = await a.findMany({ model: "verification", where: [{ field: "expiresAt", operator: "gt", value: new Date() }] });
|
|
expect(live.length).toBe(0);
|
|
});
|