Enable auth-service/api-gateway on production, build their images in CI
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import "reflect-metadata";
|
||||
import { ConflictException, UnauthorizedException } from "@nestjs/common";
|
||||
import { JwtService } from "@nestjs/jwt";
|
||||
import * as bcrypt from "bcrypt";
|
||||
import { AuthService } from "../src/auth/auth.service";
|
||||
|
||||
/** A fake `pg.Pool` — the goal here is auth logic (hashing, verification,
|
||||
* conflict handling, JWT claims), not exercising a real Postgres, which
|
||||
* `test_live_datastores.py`'s equivalent role covers for ai-service. */
|
||||
function fakePool(rows: unknown[] = [], rejectCode?: string) {
|
||||
return {
|
||||
query: jest.fn().mockImplementation(async () => {
|
||||
if (rejectCode) {
|
||||
const error = new Error("duplicate") as Error & { code: string };
|
||||
error.code = rejectCode;
|
||||
throw error;
|
||||
}
|
||||
return { rows };
|
||||
}),
|
||||
} as unknown as import("pg").Pool;
|
||||
}
|
||||
|
||||
const jwt = new JwtService({ secret: "test-secret-not-for-real-use" });
|
||||
|
||||
describe("AuthService", () => {
|
||||
it("registers a new user and returns username/role", async () => {
|
||||
const pool = fakePool([{ username: "demo", role: "user" }]);
|
||||
const service = new AuthService(pool, jwt);
|
||||
const result = await service.register("demo", "1");
|
||||
expect(result).toEqual({ username: "demo", role: "user" });
|
||||
});
|
||||
|
||||
it("rejects registering a username that already exists", async () => {
|
||||
const pool = fakePool([], "23505");
|
||||
const service = new AuthService(pool, jwt);
|
||||
await expect(service.register("admin", "1")).rejects.toBeInstanceOf(
|
||||
ConflictException
|
||||
);
|
||||
});
|
||||
|
||||
it("logs in with the correct password and issues a JWT carrying the role", async () => {
|
||||
const passwordHash = await bcrypt.hash("1", 12);
|
||||
const pool = fakePool([
|
||||
{ id: "u-1", username: "admin", password_hash: passwordHash, role: "admin" },
|
||||
]);
|
||||
const service = new AuthService(pool, jwt);
|
||||
const result = await service.login("admin", "1");
|
||||
expect(result.user).toEqual({ username: "admin", role: "admin" });
|
||||
const decoded = jwt.verify(result.token) as { sub: string; role: string };
|
||||
expect(decoded.sub).toBe("u-1");
|
||||
expect(decoded.role).toBe("admin");
|
||||
});
|
||||
|
||||
it("rejects a wrong password", async () => {
|
||||
const passwordHash = await bcrypt.hash("1", 12);
|
||||
const pool = fakePool([
|
||||
{ id: "u-1", username: "admin", password_hash: passwordHash, role: "admin" },
|
||||
]);
|
||||
const service = new AuthService(pool, jwt);
|
||||
await expect(service.login("admin", "wrong")).rejects.toBeInstanceOf(
|
||||
UnauthorizedException
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects a username that does not exist without leaking that distinction", async () => {
|
||||
const pool = fakePool([]);
|
||||
const service = new AuthService(pool, jwt);
|
||||
await expect(service.login("nobody", "1")).rejects.toBeInstanceOf(
|
||||
UnauthorizedException
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user