🎉 init: 小龙的工作空间
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
// ApprovalStep CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/approval_steps", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/approval_steps",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/approval_steps", () => {
|
||||
it("creates a approval_step", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/approval_steps",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
"approvalId": "00000000-0000-0000-0000-000000000001",
|
||||
"approverId": "00000000-0000-0000-0000-000000000001",
|
||||
"stepOrder": 1,
|
||||
"status": "sample-status",
|
||||
"comment": "sample-comment",
|
||||
"actedAt": "sample-actedat"
|
||||
},
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/approval_steps/:id", () => {
|
||||
it("returns the created approval_step", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/approval_steps/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/approval_steps/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/approval_steps/:id", () => {
|
||||
it("updates the approval_step", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/approval_steps/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
"approvalId": "00000000-0000-0000-0000-000000000001",
|
||||
"approverId": "00000000-0000-0000-0000-000000000001",
|
||||
"stepOrder": 1,
|
||||
"status": "sample-status",
|
||||
"comment": "sample-comment",
|
||||
"actedAt": "sample-actedat"
|
||||
},
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/approval_steps/:id", () => {
|
||||
it("deletes the approval_step", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/approval_steps/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/approval_steps/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,121 @@
|
||||
// Approval CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
let payload: Record<string, unknown>;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
|
||||
// Resolve user FK references with the registered user's real ID
|
||||
payload = {
|
||||
"userId": regRes.json().user.id,
|
||||
"entityType": "sample-entitytype",
|
||||
"entityId": "sample-entityid",
|
||||
"applicantId": regRes.json().user.id,
|
||||
"status": "sample-status",
|
||||
"formData": "sample-formdata"
|
||||
};
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/approvals", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/approvals",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/approvals", () => {
|
||||
it("creates a approval", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/approvals",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/approvals/:id", () => {
|
||||
it("returns the created approval", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/approvals/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/approvals/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/approvals/:id", () => {
|
||||
it("updates the approval", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/approvals/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/approvals/:id", () => {
|
||||
it("deletes the approval", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/approvals/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/approvals/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,124 @@
|
||||
// Attendance CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/attendance", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/attendance",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/attendance", () => {
|
||||
it("creates a attendance", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/attendance",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
"userId": "00000000-0000-0000-0000-000000000001",
|
||||
"checkInAt": "sample-checkinat",
|
||||
"checkOutAt": "sample-checkoutat",
|
||||
"location": "sample-location",
|
||||
"type": "sample-type",
|
||||
"UNIQUE(userId, DATE(checkInAt))": "sample-unique(userid, date(checkinat))"
|
||||
},
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/attendance/:id", () => {
|
||||
it("returns the created attendance", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/attendance/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/attendance/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/attendance/:id", () => {
|
||||
it("updates the attendance", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/attendance/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
"userId": "00000000-0000-0000-0000-000000000001",
|
||||
"checkInAt": "sample-checkinat",
|
||||
"checkOutAt": "sample-checkoutat",
|
||||
"location": "sample-location",
|
||||
"type": "sample-type",
|
||||
"UNIQUE(userId, DATE(checkInAt))": "sample-unique(userid, date(checkinat))"
|
||||
},
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/attendance/:id", () => {
|
||||
it("deletes the attendance", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/attendance/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/attendance/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,96 @@
|
||||
// Auth routes test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("POST /api/auth/register", () => {
|
||||
it("registers a new user", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: "testuser", password: "password123" },
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.token);
|
||||
assert.equal(body.user.username, "testuser");
|
||||
token = body.token;
|
||||
});
|
||||
|
||||
it("rejects duplicate username", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: "testuser", password: "password123" },
|
||||
});
|
||||
assert.equal(res.statusCode, 409);
|
||||
});
|
||||
|
||||
it("rejects short password", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: "user2", password: "123" },
|
||||
});
|
||||
assert.equal(res.statusCode, 400);
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/auth/login", () => {
|
||||
it("logs in with correct credentials", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/login",
|
||||
payload: { username: "testuser", password: "password123" },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(body.token);
|
||||
token = body.token;
|
||||
});
|
||||
|
||||
it("rejects wrong password", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/login",
|
||||
payload: { username: "testuser", password: "wrongpassword" },
|
||||
});
|
||||
assert.equal(res.statusCode, 401);
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/auth/me", () => {
|
||||
it("returns current user with valid token", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/auth/me",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.username, "testuser");
|
||||
});
|
||||
|
||||
it("rejects without token", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/auth/me",
|
||||
});
|
||||
assert.equal(res.statusCode, 401);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,124 @@
|
||||
// Contract CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
let payload: Record<string, unknown>;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
|
||||
// Resolve user FK references with the registered user's real ID
|
||||
payload = {
|
||||
"userId": regRes.json().user.id,
|
||||
"title": "sample-title",
|
||||
"partyA": "sample-partya",
|
||||
"partyB": "sample-partyb",
|
||||
"amount": 1,
|
||||
"signedAt": "sample-signedat",
|
||||
"expiresAt": "sample-expiresat",
|
||||
"status": "sample-status",
|
||||
"fileUrl": "sample-fileurl"
|
||||
};
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/contracts", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/contracts",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/contracts", () => {
|
||||
it("creates a contract", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/contracts",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/contracts/:id", () => {
|
||||
it("returns the created contract", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/contracts/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/contracts/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/contracts/:id", () => {
|
||||
it("updates the contract", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/contracts/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/contracts/:id", () => {
|
||||
it("deletes the contract", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/contracts/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/contracts/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,122 @@
|
||||
// Customer CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
let payload: Record<string, unknown>;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
|
||||
// Resolve user FK references with the registered user's real ID
|
||||
payload = {
|
||||
"userId": regRes.json().user.id,
|
||||
"name": "sample-name",
|
||||
"email": "sample-email",
|
||||
"phone": "sample-phone",
|
||||
"company": "sample-company",
|
||||
"source": "sample-source",
|
||||
"tags": "sample-tags"
|
||||
};
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/customers", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/customers",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/customers", () => {
|
||||
it("creates a customer", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/customers",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/customers/:id", () => {
|
||||
it("returns the created customer", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/customers/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/customers/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/customers/:id", () => {
|
||||
it("updates the customer", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/customers/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/customers/:id", () => {
|
||||
it("deletes the customer", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/customers/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/customers/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,118 @@
|
||||
// Department CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/departments", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/departments",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/departments", () => {
|
||||
it("creates a department", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/departments",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
"name": "sample-name",
|
||||
"parentId": "00000000-0000-0000-0000-000000000001",
|
||||
"managerId": "00000000-0000-0000-0000-000000000001"
|
||||
},
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/departments/:id", () => {
|
||||
it("returns the created department", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/departments/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/departments/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/departments/:id", () => {
|
||||
it("updates the department", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/departments/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
"name": "sample-name",
|
||||
"parentId": "00000000-0000-0000-0000-000000000001",
|
||||
"managerId": "00000000-0000-0000-0000-000000000001"
|
||||
},
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/departments/:id", () => {
|
||||
it("deletes the department", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/departments/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/departments/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,119 @@
|
||||
// Items CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
let payload: Record<string, unknown>;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
|
||||
// Resolve user FK references with the registered user's real ID
|
||||
payload = {
|
||||
"userId": regRes.json().user.id,
|
||||
"title": "sample-title",
|
||||
"description": "sample-description",
|
||||
"data": "sample-data"
|
||||
};
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/items", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/items",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/items", () => {
|
||||
it("creates a item", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/items",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/items/:id", () => {
|
||||
it("returns the created item", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/items/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/items/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/items/:id", () => {
|
||||
it("updates the item", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/items/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/items/:id", () => {
|
||||
it("deletes the item", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/items/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/items/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,121 @@
|
||||
// Reminder CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
let payload: Record<string, unknown>;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
|
||||
// Resolve user FK references with the registered user's real ID
|
||||
payload = {
|
||||
"userId": regRes.json().user.id,
|
||||
"entityType": "sample-entitytype",
|
||||
"entityId": "sample-entityid",
|
||||
"remindAt": "sample-remindat",
|
||||
"message": "sample-message",
|
||||
"sent": true
|
||||
};
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/reminders", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/reminders",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/reminders", () => {
|
||||
it("creates a reminder", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/reminders",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/reminders/:id", () => {
|
||||
it("returns the created reminder", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/reminders/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/reminders/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/reminders/:id", () => {
|
||||
it("updates the reminder", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/reminders/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/reminders/:id", () => {
|
||||
it("deletes the reminder", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/reminders/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/reminders/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,120 @@
|
||||
// Tickets CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
let payload: Record<string, unknown>;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
|
||||
// Resolve user FK references with the registered user's real ID
|
||||
payload = {
|
||||
"userId": regRes.json().user.id,
|
||||
"title": "sample-title",
|
||||
"description": "sample-description",
|
||||
"assigneeId": "sample-assigneeid",
|
||||
"category": "sample-category"
|
||||
};
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/tickets", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/tickets",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/tickets", () => {
|
||||
it("creates a ticket", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/tickets",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/tickets/:id", () => {
|
||||
it("returns the created ticket", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/tickets/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/tickets/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/tickets/:id", () => {
|
||||
it("updates the ticket", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/tickets/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload,
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/tickets/:id", () => {
|
||||
it("deletes the ticket", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/tickets/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/tickets/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,118 @@
|
||||
// User CRUD test
|
||||
import { describe, it, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildApp } from "../index.js";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
|
||||
let app: FastifyInstance;
|
||||
let token: string;
|
||||
let createdId: string;
|
||||
|
||||
before(async () => {
|
||||
process.env.JWT_SECRET = "test-secret";
|
||||
process.env.DATABASE_URL = ":memory:";
|
||||
app = await buildApp();
|
||||
await app.ready();
|
||||
|
||||
// Register and login to get a token
|
||||
const regRes = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/auth/register",
|
||||
payload: { username: `test_${Date.now()}`, password: "password123" },
|
||||
});
|
||||
token = regRes.json().token;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe("GET /api/users", () => {
|
||||
it("returns empty list", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: "/api/users",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.ok(Array.isArray(body.data));
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/users", () => {
|
||||
it("creates a user", async () => {
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: "/api/users",
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
"phone": "sample-phone",
|
||||
"nickname": "sample-nickname",
|
||||
"avatarUrl": "sample-avatarurl"
|
||||
},
|
||||
});
|
||||
assert.equal(res.statusCode, 201);
|
||||
const body = res.json();
|
||||
assert.ok(body.data.id);
|
||||
createdId = body.data.id;
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/users/:id", () => {
|
||||
it("returns the created user", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/users/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
const body = res.json();
|
||||
assert.equal(body.data.id, createdId);
|
||||
});
|
||||
|
||||
it("returns 404 for nonexistent id", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/users/nonexistent`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PUT /api/users/:id", () => {
|
||||
it("updates the user", async () => {
|
||||
const res = await app.inject({
|
||||
method: "PUT",
|
||||
url: `/api/users/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
"phone": "sample-phone",
|
||||
"nickname": "sample-nickname",
|
||||
"avatarUrl": "sample-avatarurl"
|
||||
},
|
||||
});
|
||||
assert.equal(res.statusCode, 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe("DELETE /api/users/:id", () => {
|
||||
it("deletes the user", async () => {
|
||||
const res = await app.inject({
|
||||
method: "DELETE",
|
||||
url: `/api/users/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 204);
|
||||
});
|
||||
|
||||
it("returns 404 after delete", async () => {
|
||||
const res = await app.inject({
|
||||
method: "GET",
|
||||
url: `/api/users/${createdId}`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
});
|
||||
assert.equal(res.statusCode, 404);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user