Compare commits

...

2 Commits

Author SHA1 Message Date
9131a86262
feat: update tsc 2025-07-12 21:59:42 -04:00
10138352d9
feat: get working tests 2025-07-11 18:56:48 -04:00
9 changed files with 143 additions and 7 deletions

1
.gitignore vendored
View File

@ -17,6 +17,7 @@
!api/package.json
!api/bun.lock
!api/tsconfig.json
!api/drizzle*
!api/src/
!api/src/**
!api/drizzle/

View File

@ -14,6 +14,7 @@
"@biomejs/biome": "2.1.1",
"@types/bun": "latest",
"drizzle-kit": "^0.31.4",
"typescript": "^5.8.3",
},
},
},

View File

@ -1,5 +1,6 @@
{
"name": "api",
"type": "module",
"scripts": {
"dev": "bun run --hot src/index.ts"
},
@ -13,6 +14,7 @@
"devDependencies": {
"@biomejs/biome": "2.1.1",
"@types/bun": "latest",
"drizzle-kit": "^0.31.4"
"drizzle-kit": "^0.31.4",
"typescript": "^5.8.3"
}
}

80
api/src/index.test.ts Normal file
View File

@ -0,0 +1,80 @@
import { beforeAll, describe, expect, it } from "bun:test";
import { migrate } from "drizzle-orm/bun-sql/migrator";
import app from ".";
import { db } from "./db";
import { auth } from "./lib/auth";
import { buildHeaders } from "./test/utils";
beforeAll(async () => {
await migrate(db, { migrationsFolder: "./drizzle" });
});
describe("First Test", () => {
it("should return 200 Response", async () => {
const req = new Request("http://localhost:3000/");
const res = await app.fetch(req);
expect(res.status).toBe(200);
});
});
describe("Auth", () => {
const user = {
email: "yadunand@yadunut.com",
password: "password123",
name: "Yadunand Prem",
username: "yadunut",
};
let authHeaders: Headers;
it("creates a new user", async () => {
const res = await auth.api.signUpEmail({
body: {
...user,
},
});
expect(res.user.email).toBe("yadunand@yadunut.com");
const foundUser = await db.query.user.findFirst();
expect(foundUser).not.toBeNull();
expect(foundUser?.email).toBe(user.email);
});
it("logs in user and stores auth headers", async () => {
const { headers: signInHeaders, response: signInRes } =
await auth.api.signInEmail({
body: {
email: user.email,
password: user.password,
},
returnHeaders: true,
});
expect(signInRes.token).not.toBeNull();
expect(signInRes.user.name).toBe(user.name);
// Store the auth headers for subsequent tests
authHeaders = buildHeaders(signInHeaders);
// Verify session works with stored headers
const res = await auth.api.getSession({ headers: authHeaders });
expect(res?.user.username).toBe(user.username);
});
it("creates auth token using stored headers", async () => {
const data = await auth.api.createApiKey({
headers: authHeaders,
body: {},
});
// Add expectations based on what createApiKey should return
expect(data).toBeDefined();
});
it("deletes user using stored headers", async () => {
const deleteRes = await auth.api.deleteUser({
headers: authHeaders,
body: {
password: user.password,
},
});
expect(deleteRes.success).toBe(true);
});
});

View File

@ -4,6 +4,9 @@ import { apiKey, username } from "better-auth/plugins";
import { db } from "@/db";
export const auth = betterAuth({
logger: {
level: "debug",
},
database: drizzleAdapter(db, {
provider: "pg",
}),
@ -11,4 +14,9 @@ export const auth = betterAuth({
emailAndPassword: {
enabled: true,
},
user: {
deleteUser: {
enabled: true,
},
},
});

7
api/src/test/utils.ts Normal file
View File

@ -0,0 +1,7 @@
export function buildHeaders(signInHeaders: Headers) {
const headers = new Headers();
for (const cookie of signInHeaders.getSetCookie() ?? []) {
headers.append("cookie", cookie);
}
return headers;
}

View File

@ -1,13 +1,31 @@
{
"compilerOptions": {
"strict": true,
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx",
"module": "NodeNext",
"moduleResolution": "nodenext",
"lib": ["ESNext"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
"jsx": "react-jsx",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noPropertyAccessFromIndexSignature": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
"@/*": ["./src/*"]
}
}
}

View File

@ -15,7 +15,13 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true
"recommended": true,
"correctness": {
"noUnusedImports": {
"level": "warn",
"fix": "safe"
}
}
}
},
"javascript": {

View File

@ -14,5 +14,18 @@ services:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
postgres-test:
image: postgres:15
container_name: postgres-test
environment:
POSTGRES_DB: system_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
ports:
- "5433:5432"
tmpfs:
- /var/lib/postgresql/data
restart: unless-stopped
volumes:
postgres_data: