diff --git a/server/.env.test b/server/.env.test index fe52f65..ee3f0cb 100644 --- a/server/.env.test +++ b/server/.env.test @@ -1 +1,3 @@ -DATABASE_URL="file:./test.sqlite" \ No newline at end of file +DATABASE_URL="file:./test.sqlite" + +POST_LIMIT=9999 diff --git a/server/package.json b/server/package.json index be2219f..03e6fc1 100644 --- a/server/package.json +++ b/server/package.json @@ -5,10 +5,10 @@ "main": "server.js", "scripts": { "test-watch": "vitest", - "test": "vitest run", + "test": "vitest run unit", "test:unit": "vitest run unit", "test:integration": "run-s db:test:migrate test:integration:test db:test:cleanup", - "test:integration:test": "dotenv -e .env.test -- vitest run integration --coverage --no-threads", + "test:integration:test": "dotenv -e .env.test -- vitest run --coverage --no-threads", "db:test:migrate": "dotenv -e .env.test -- npx prisma db push", "db:test:cleanup": "rm ./prisma/test.sqlite", "coverage": "vitest run --coverage", diff --git a/server/src/app.integration.test.ts b/server/src/app.integration.test.ts index 50e1e46..4771bf7 100644 --- a/server/src/app.integration.test.ts +++ b/server/src/app.integration.test.ts @@ -1,14 +1,95 @@ import app from "./app"; import request from "supertest"; import { describe, it, expect } from "vitest"; +import prisma from "./client"; + +const testNote = { + ciphertext: "sample_ciphertext", + hmac: "sample_hmac", +}; describe("GET /api/test", () => { - it('should respond "Hello world!"', () => { - return request(app) - .get("/api/test") - .then((res) => { - expect(res.statusCode).toBe(200); - expect(res.text).toBe("Hello world!"); - }); + it('should respond "Hello world!"', async () => { + const res = await request(app).get("/api/test"); + expect(res.statusCode).toBe(200); + expect(res.text).toBe("Hello world!"); + }); +}); + +describe("GET /api/note", () => { + it("returns a note for valid ID", async () => { + // Insert a note + const { id } = await prisma.encryptedNote.create({ + data: testNote, + }); + + // Make get request + const res = await request(app).get(`/api/note/${id}`); + + // Validate returned note + expect(res.statusCode).toBe(200); + expect(res.body).toHaveProperty("id"); + expect(res.body).toHaveProperty("expire_time"); + expect(res.body).toHaveProperty("insert_time"); + expect(res.body).toHaveProperty("ciphertext"); + expect(res.body).toHaveProperty("hmac"); + expect(res.body.id).toEqual(id); + expect(res.body.ciphertext).toEqual(testNote.ciphertext); + expect(res.body.hmac).toEqual(testNote.hmac); + }); + + it("responds 404 for invalid ID", async () => { + // Insert a note + // Make get request + const res = await request(app).get(`/api/note/NaN`); + + // Validate returned note + expect(res.statusCode).toBe(404); + }); +}); + +describe("POST /api/note", () => { + it("returns a view_url on correct POST body", async () => { + const res = await request(app).post("/api/note").send(testNote); + expect(res.statusCode).toBe(200); + + // Returned body has correct fields + expect(res.body).toHaveProperty("expire_time"); + expect(res.body).toHaveProperty("view_url"); + + // View URL is properly formed + expect(res.body.view_url).toMatch(/^http[s]?:\/\//); + + // A future expiry date is assigned + expect(new Date(res.body.expire_time).getTime()).toBeGreaterThan( + new Date().getTime() + ); + }); + + it("returns a valid view_url on correct POST body", async () => { + // Make post request + let res = await request(app).post("/api/note").send(testNote); + + // Extract note id from post response + expect(res.statusCode).toBe(200); + expect(res.body).toHaveProperty("view_url"); + const match = (res.body.view_url as string).match(/note\/(.+)$/); + expect(match).not.toBeNull(); + expect(match).toHaveLength(2); + const note_id = (match as RegExpMatchArray)[1]; + + // Make get request + res = await request(app).get(`/api/note/${note_id}`); + + // Validate returned note + expect(res.statusCode).toBe(200); + expect(res.body).toHaveProperty("id"); + expect(res.body).toHaveProperty("expire_time"); + expect(res.body).toHaveProperty("insert_time"); + expect(res.body).toHaveProperty("ciphertext"); + expect(res.body).toHaveProperty("hmac"); + expect(res.body.id).toEqual(note_id); + expect(res.body.ciphertext).toEqual(testNote.ciphertext); + expect(res.body.hmac).toEqual(testNote.hmac); }); }); diff --git a/server/src/util.unit.test.ts b/server/src/util.unit.test.ts new file mode 100644 index 0000000..d78d8bf --- /dev/null +++ b/server/src/util.unit.test.ts @@ -0,0 +1,10 @@ +import { describe, it, expect } from "vitest"; +import { addDays } from "./util"; + +describe("addDays()", () => { + it("Should add n days to the input date", () => { + const date = new Date("2022-01-01"); + const expectedDate = new Date("2022-01-31"); + expect(addDays(date, 30)).toEqual(expectedDate); + }); +});