From d6f0e5e617dbf296ad6f8ca97ccd82c72690a83b Mon Sep 17 00:00:00 2001 From: Bilal Catic Date: Tue, 18 Feb 2020 11:08:01 +0100 Subject: [PATCH] add tests --- backend/src/__tests__/app.test.ts | 10 + backend/src/__tests__/exportJob.test.ts | 233 ++++++++++++++++++++++++ 2 files changed, 243 insertions(+) create mode 100644 backend/src/__tests__/app.test.ts create mode 100644 backend/src/__tests__/exportJob.test.ts diff --git a/backend/src/__tests__/app.test.ts b/backend/src/__tests__/app.test.ts new file mode 100644 index 0000000..8d36474 --- /dev/null +++ b/backend/src/__tests__/app.test.ts @@ -0,0 +1,10 @@ +import request from "supertest"; +import app from "../server"; + +describe ("App", () => { + it("should return error response on GET /", async () => { + const result = await request(app).get("/"); + expect(result.status).toEqual(404); + }); +}); + diff --git a/backend/src/__tests__/exportJob.test.ts b/backend/src/__tests__/exportJob.test.ts new file mode 100644 index 0000000..90ff5af --- /dev/null +++ b/backend/src/__tests__/exportJob.test.ts @@ -0,0 +1,233 @@ +import request from "supertest"; +import app from "../server"; +import {ExportJobsList, ExportJob} from "../interfaces"; +import {PROCESSING_TIME_EXPORT} from "../config"; + +describe ("App export jobs endpoint with invalid body", () => { + it("should return array with errors if body is empty and request should not be saved", async () => { + const postResult = await request(app).post("/export").send({}); + const getResult = await request(app).get("/export"); + + const memoryContents:ExportJobsList = { + pending: [], + finished: [] + }; + + const expectedErrorsArray = [ + {"location": "body", "msg": "bookId field should be a string", "param": "bookId"}, + {"location": "body", "msg": "bookId field is required", "param": "bookId"}, + {"location": "body", "msg": "type field should be a string", "param": "type"}, + {"location": "body", "msg": "type field is required", "param": "type"}, + {"location": "body", "msg": "type is not valid", "param": "type"} + ]; + + expect(getResult.status).toEqual(200); + expect(postResult.body).toEqual(expectedErrorsArray); + expect(getResult.body).toEqual(memoryContents); + }); + + it("should return array with errors if body is missing bookId field and request should not be saved", async () => { + const postResult = await request(app).post("/export").send({type:"pdf"}); + const getResult = await request(app).get("/export"); + + const memoryContents:ExportJobsList = { + pending: [], + finished: [] + }; + + const expectedErrorsArray = [ + {"location": "body", "msg": "bookId field should be a string", "param": "bookId"}, + {"location": "body", "msg": "bookId field is required", "param": "bookId"}, + ]; + + expect(getResult.status).toEqual(200); + expect(postResult.body).toEqual(expectedErrorsArray); + expect(getResult.body).toEqual(memoryContents); + }); + + it("should return array with errors if bookId field is not a string and request should not be saved", async () => { + const postResult = await request(app).post("/export").send({bookId:0, type:"pdf"}); + const getResult = await request(app).get("/export"); + + const memoryContents:ExportJobsList = { + pending: [], + finished: [] + }; + + const expectedErrorsArray = [ + {"location": "body", "msg": "bookId field should be a string", "param": "bookId", "value": 0} + ]; + + expect(getResult.status).toEqual(200); + expect(postResult.body).toEqual(expectedErrorsArray); + expect(getResult.body).toEqual(memoryContents); + }); + + it("should return array with errors if body is missing type field and request should not be saved", async () => { + const postResult = await request(app).post("/export").send({bookId:"1111"}); + const getResult = await request(app).get("/export"); + + const memoryContents:ExportJobsList = { + pending: [], + finished: [] + }; + + const expectedErrorsArray = [ + {"location": "body", "msg": "type field should be a string", "param": "type"}, + {"location": "body", "msg": "type field is required", "param": "type"}, + {"location": "body", "msg": "type is not valid", "param": "type"} + ]; + + expect(postResult.body).toEqual(expectedErrorsArray); + expect(getResult.status).toEqual(200); + expect(getResult.body).toEqual(memoryContents); + }); + + it("should return array with errors if type field is not a string and request should not be saved", async () => { + const postResult = await request(app).post("/export").send({bookId:"111", type:0}); + const getResult = await request(app).get("/export"); + + const memoryContents:ExportJobsList = { + pending: [], + finished: [] + }; + + const expectedErrorsArray = [ + {"location": "body", "msg": "type field should be a string", "param": "type", "value": 0}, + {"location": "body", "msg": "type is not valid", "param": "type", "value": 0} + ]; + + expect(getResult.status).toEqual(200); + expect(postResult.body).toEqual(expectedErrorsArray); + expect(getResult.body).toEqual(memoryContents); + }); + + it("should return array with errors if type field has invalid value and request should not be saved", async () => { + const postResult = await request(app).post("/export").send({bookId:"111", type:"invalid_type"}); + const getResult = await request(app).get("/export"); + + const memoryContents:ExportJobsList = { + pending: [], + finished: [] + }; + + const expectedErrorsArray = [ + {"location": "body", "msg": "type is not valid", "param": "type", "value": "invalid_type"} + ]; + + expect(getResult.status).toEqual(200); + expect(postResult.body).toEqual(expectedErrorsArray); + expect(getResult.body).toEqual(memoryContents); + }); +}); + +describe ("App export jobs endpoint with valid body", () => { + it("should return ExportJobsList object with empty pending and finished arrays", async () => { + const result = await request(app).get("/export"); + const initialMemoryContents:ExportJobsList = { + pending:[], + finished:[] + }; + + expect(result.status).toEqual(200); + expect(result.body).toEqual(initialMemoryContents); + }); + + it("should return ExportJobsList object containing pending pdf item", async () => { + const dummyExportJob:ExportJob = { + bookId: "12345", + type: "pdf", + state: "pending", // this will be ignored + created_at: new Date(), // this will be ignored + updated_at: new Date() // this will be ignored + }; + const postResult = await request(app).post("/export").send(dummyExportJob); + const getResult = await request(app).get("/export"); + + const newJob = postResult.body; + const pendingJobs = getResult.body.pending; + + expect(getResult.status).toEqual(200); + expect(pendingJobs).toContainEqual(expect.objectContaining(newJob)); + }); + + it("should return ExportJobsList object containing pending epub item", async () => { + const dummyExportJob:ExportJob = { + bookId: "990", + type: "epub", + state: "pending", // this will be ignored + created_at: new Date(), // this will be ignored + updated_at: new Date() // this will be ignored + }; + const postResult = await request(app).post("/export").send(dummyExportJob); + const getResult = await request(app).get("/export"); + + const newJob = postResult.body; + const pendingJobs = getResult.body.pending; + + expect(getResult.status).toEqual(200); + expect(pendingJobs).toContainEqual(expect.objectContaining(newJob)); + }); + + it("should return ExportJobsList object with specific pdf-type item in finished array", async () => { + const dummyExportJob:ExportJob = { + bookId: "12345", + type: "pdf", + state: "finished", // this will be ignored + created_at: new Date(), // this will be ignored + updated_at: new Date() // this will be ignored + }; + const postResult = await request(app).post("/export").send(dummyExportJob); + + const exportJob:ExportJob = postResult.body; + const updatedAtUTC = new Date(exportJob.created_at); + const timeToAdd = PROCESSING_TIME_EXPORT.pdf; + updatedAtUTC.setSeconds(updatedAtUTC.getSeconds() + timeToAdd); + updatedAtUTC.setMilliseconds(0); + exportJob.updated_at = updatedAtUTC; + exportJob.state = "finished"; + await new Promise(resolve => setTimeout(resolve, timeToAdd*1000)); + + const getResult = await request(app).get("/export"); + const finishedJobs:ExportJob[] = getResult.body.finished; + + finishedJobs.forEach((finishedJob) => { + finishedJob.updated_at = new Date(finishedJob.updated_at); + finishedJob.updated_at.setMilliseconds(0); + }); + + expect(getResult.status).toEqual(200); + expect(finishedJobs).toContainEqual(expect.objectContaining(exportJob)); + }); + + it("should return ExportJobsList object with specific epub-type item in finished array", async () => { + const dummyExportJob:ExportJob = { + bookId: "1000", + type: "epub", + state: "finished", // this will be ignored + created_at: new Date(), // this will be ignored + updated_at: new Date() // this will be ignored + }; + const postResult = await request(app).post("/export").send(dummyExportJob); + + const exportJob:ExportJob = postResult.body; + const updatedAtUTC = new Date(exportJob.created_at); + const timeToAdd = PROCESSING_TIME_EXPORT.epub; + updatedAtUTC.setSeconds(updatedAtUTC.getSeconds() + timeToAdd); + updatedAtUTC.setMilliseconds(0); + exportJob.updated_at = updatedAtUTC; + exportJob.state = "finished"; + await new Promise(resolve => setTimeout(resolve, timeToAdd*1000)); + + const getResult = await request(app).get("/export"); + const finishedJobs:ExportJob[] = getResult.body.finished; + + finishedJobs.forEach((finishedJob) => { + finishedJob.updated_at = new Date(finishedJob.updated_at); + finishedJob.updated_at.setMilliseconds(0); + }); + + expect(getResult.status).toEqual(200); + expect(finishedJobs).toContainEqual(expect.objectContaining(exportJob)); + }); +});