Merge branch 'add-backend-tests' into 'master'
Add backend tests See merge request saburly/senadibilal/domensis!1
This commit was merged in pull request #1.
This commit is contained in:
@@ -9,3 +9,10 @@ Note: execute commands from `backend` directory
|
|||||||
1. Copy `env.template` and rename it to `.env`. Set desired values
|
1. Copy `env.template` and rename it to `.env`. Set desired values
|
||||||
2. Run `yarn install`. To skip dev dependencies, run `yarn install --production`. More info : https://classic.yarnpkg.com/en/docs/cli/install/#toc-yarn-install-production-true-false
|
2. Run `yarn install`. To skip dev dependencies, run `yarn install --production`. More info : https://classic.yarnpkg.com/en/docs/cli/install/#toc-yarn-install-production-true-false
|
||||||
3. To start server, run `yarn start`
|
3. To start server, run `yarn start`
|
||||||
|
|
||||||
|
#### Tests
|
||||||
|
|
||||||
|
To execute tests, run `yarn test`. To speed up process, copy `.env` file to
|
||||||
|
`.test.env` and set smaller values for export/import times (e.g. 1 second).
|
||||||
|
If `.test.env` does not exist, values from `.env` file will be used.
|
||||||
|
If `.env.` does not exist, default values will be used.
|
||||||
|
|||||||
1
backend/.gitignore
vendored
1
backend/.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
dist
|
dist
|
||||||
node_modules
|
node_modules
|
||||||
.env
|
.env
|
||||||
|
.test.env
|
||||||
|
|||||||
4
backend/jest.config.js
Normal file
4
backend/jest.config.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
testEnvironment: 'node'
|
||||||
|
};
|
||||||
@@ -5,9 +5,9 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"prebuild": "tslint -c tslint.json -p tsconfig.json --fix",
|
"prebuild": "tslint -c tslint.json -p tsconfig.json --fix",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"prestart": "npm run build",
|
"prestart": "yarn run build",
|
||||||
"start": "node .",
|
"start": "node .",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
@@ -18,7 +18,12 @@
|
|||||||
"@types/dotenv": "^8.2.0",
|
"@types/dotenv": "^8.2.0",
|
||||||
"@types/express": "^4.17.2",
|
"@types/express": "^4.17.2",
|
||||||
"@types/express-validator": "^3.0.0",
|
"@types/express-validator": "^3.0.0",
|
||||||
|
"@types/jest": "^25.1.2",
|
||||||
"@types/node": "^13.7.1",
|
"@types/node": "^13.7.1",
|
||||||
|
"@types/supertest": "^2.0.8",
|
||||||
|
"jest": "^25.1.0",
|
||||||
|
"supertest": "^4.0.2",
|
||||||
|
"ts-jest": "^25.2.0",
|
||||||
"tslint": "^6.0.0",
|
"tslint": "^6.0.0",
|
||||||
"typescript": "^3.7.5"
|
"typescript": "^3.7.5"
|
||||||
}
|
}
|
||||||
|
|||||||
10
backend/src/__tests__/app.test.ts
Normal file
10
backend/src/__tests__/app.test.ts
Normal file
@@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
233
backend/src/__tests__/exportJob.test.ts
Normal file
233
backend/src/__tests__/exportJob.test.ts
Normal file
@@ -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));
|
||||||
|
});
|
||||||
|
});
|
||||||
283
backend/src/__tests__/importJob.test.ts
Normal file
283
backend/src/__tests__/importJob.test.ts
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
import request from "supertest";
|
||||||
|
import app from "../server";
|
||||||
|
import {ImportJobsList, ImportJob} from "../interfaces";
|
||||||
|
import {PROCESSING_TIME_IMPORT_ANY} from "../config";
|
||||||
|
|
||||||
|
describe ("App import 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("/import").send({});
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const memoryContents:ImportJobsList = {
|
||||||
|
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"},
|
||||||
|
{"location": "body", "msg": "url field should be a string", "param": "url"},
|
||||||
|
{"location": "body", "msg": "url field is required", "param": "url"},
|
||||||
|
];
|
||||||
|
|
||||||
|
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("/import").send({type:"pdf", url: "https://dummy.com"});
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const memoryContents:ImportJobsList = {
|
||||||
|
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("/import").send({bookId:0, type:"pdf", url: "https://dummy.com"});
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const memoryContents:ImportJobsList = {
|
||||||
|
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("/import").send({bookId:"1111", url:"https://dummy.com"});
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const memoryContents:ImportJobsList = {
|
||||||
|
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("/import").send({bookId:"111", type:0, url: "https://dummy.com"});
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const memoryContents:ImportJobsList = {
|
||||||
|
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("/import").send({bookId:"111", type:"invalid_type", url:"https://dummy.com"});
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const memoryContents:ImportJobsList = {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return array with errors if body is missing url field and request should not be saved", async () => {
|
||||||
|
const postResult = await request(app).post("/import").send({bookId:"11122", type:"pdf"});
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const memoryContents:ImportJobsList = {
|
||||||
|
pending: [],
|
||||||
|
finished: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedErrorsArray = [
|
||||||
|
{"location": "body", "msg": "url field should be a string", "param": "url"},
|
||||||
|
{"location": "body", "msg": "url field is required", "param": "url"},
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(getResult.status).toEqual(200);
|
||||||
|
expect(postResult.body).toEqual(expectedErrorsArray);
|
||||||
|
expect(getResult.body).toEqual(memoryContents);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return array with errors if url field is not a string and request should not be saved", async () => {
|
||||||
|
const postResult = await request(app).post("/import").send({bookId:"123", type:"pdf", url: 1});
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const memoryContents:ImportJobsList = {
|
||||||
|
pending: [],
|
||||||
|
finished: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedErrorsArray = [
|
||||||
|
{"location": "body", "msg": "url field should be a string", "param": "url", "value": 1}
|
||||||
|
];
|
||||||
|
|
||||||
|
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 ImportJobsList object with empty pending and finished arrays", async () => {
|
||||||
|
const result = await request(app).get("/import");
|
||||||
|
const initialMemoryContents:ImportJobsList = {
|
||||||
|
pending:[],
|
||||||
|
finished:[]
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(result.status).toEqual(200);
|
||||||
|
expect(result.body).toEqual(initialMemoryContents);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return ImportJobsList object containing pending pdf item", async () => {
|
||||||
|
const dummyImportJob:ImportJob = {
|
||||||
|
bookId: "12345",
|
||||||
|
type: "pdf",
|
||||||
|
url: "https://dummy.com",
|
||||||
|
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("/import").send(dummyImportJob);
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const newJob = postResult.body;
|
||||||
|
const pendingJobs = getResult.body.pending;
|
||||||
|
|
||||||
|
expect(getResult.status).toEqual(200);
|
||||||
|
expect(pendingJobs).toContainEqual(expect.objectContaining(newJob));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return ImportJobsList object containing pending word item", async () => {
|
||||||
|
const dummyImportJob:ImportJob = {
|
||||||
|
bookId: "990",
|
||||||
|
type: "word",
|
||||||
|
url: "https://dummy.com",
|
||||||
|
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("/import").send(dummyImportJob);
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const newJob = postResult.body;
|
||||||
|
const pendingJobs = getResult.body.pending;
|
||||||
|
|
||||||
|
expect(getResult.status).toEqual(200);
|
||||||
|
expect(pendingJobs).toContainEqual(expect.objectContaining(newJob));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return ImportJobsList object containing pending evernote item", async () => {
|
||||||
|
const dummyImportJob:ImportJob = {
|
||||||
|
bookId: "990",
|
||||||
|
type: "evernote",
|
||||||
|
url: "https://dummy.com",
|
||||||
|
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("/import").send(dummyImportJob);
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const newJob = postResult.body;
|
||||||
|
const pendingJobs = getResult.body.pending;
|
||||||
|
|
||||||
|
expect(getResult.status).toEqual(200);
|
||||||
|
expect(pendingJobs).toContainEqual(expect.objectContaining(newJob));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return ImportJobsList object containing pending wattpad item", async () => {
|
||||||
|
const dummyImportJob:ImportJob = {
|
||||||
|
bookId: "990",
|
||||||
|
type: "wattpad",
|
||||||
|
url: "https://dummy.com",
|
||||||
|
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("/import").send(dummyImportJob);
|
||||||
|
const getResult = await request(app).get("/import");
|
||||||
|
|
||||||
|
const newJob = postResult.body;
|
||||||
|
const pendingJobs = getResult.body.pending;
|
||||||
|
|
||||||
|
expect(getResult.status).toEqual(200);
|
||||||
|
expect(pendingJobs).toContainEqual(expect.objectContaining(newJob));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return ImportJobsList object with specific pdf-type item in finished array", async () => {
|
||||||
|
const dummyImportJob:ImportJob = {
|
||||||
|
bookId: "12345",
|
||||||
|
type: "pdf",
|
||||||
|
url: "https://dummy.com",
|
||||||
|
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("/import").send(dummyImportJob);
|
||||||
|
|
||||||
|
const exportJob:ImportJob = postResult.body;
|
||||||
|
const updatedAtUTC = new Date(exportJob.created_at);
|
||||||
|
const timeToAdd = PROCESSING_TIME_IMPORT_ANY;
|
||||||
|
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("/import");
|
||||||
|
const finishedJobs:ImportJob[] = 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));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,3 +1,17 @@
|
|||||||
|
import dotenv from "dotenv";
|
||||||
|
import fs from "fs";
|
||||||
|
dotenv.config();
|
||||||
|
if (process.env.NODE_ENV === "test"){
|
||||||
|
try{
|
||||||
|
const envConfig = dotenv.parse(fs.readFileSync('.test.env'));
|
||||||
|
for (const k of Object.keys(envConfig)) {
|
||||||
|
process.env[k] = envConfig[k];
|
||||||
|
}
|
||||||
|
}catch (e) {
|
||||||
|
//Use .env file values
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const SERVER_PORT:number = parseInt(process.env.SERVER_PORT, 10) || 8080;
|
const SERVER_PORT:number = parseInt(process.env.SERVER_PORT, 10) || 8080;
|
||||||
|
|
||||||
const VALID_EXPORT_TYPES: {[key:string]: string} = {
|
const VALID_EXPORT_TYPES: {[key:string]: string} = {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class ExportController {
|
|||||||
this.exportJobs[jobIndex].state = "finished";
|
this.exportJobs[jobIndex].state = "finished";
|
||||||
this.exportJobs[jobIndex].updated_at = new Date();
|
this.exportJobs[jobIndex].updated_at = new Date();
|
||||||
}, timeout, jobIndexToUpdate);
|
}, timeout, jobIndexToUpdate);
|
||||||
response.send();
|
response.send(fullExportJob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class ImportController {
|
|||||||
this.importJobs[jobIndex].updated_at = new Date();
|
this.importJobs[jobIndex].updated_at = new Date();
|
||||||
}, timeout, jobIndexToUpdate);
|
}, timeout, jobIndexToUpdate);
|
||||||
|
|
||||||
response.send();
|
response.send(fullImportJob);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,5 @@
|
|||||||
import express from "express";
|
|
||||||
import dotenv from "dotenv";
|
|
||||||
import * as bodyParser from 'body-parser';
|
|
||||||
|
|
||||||
import * as routes from "./routes"
|
|
||||||
import {SERVER_PORT} from "./config";
|
import {SERVER_PORT} from "./config";
|
||||||
|
import app from "./server";
|
||||||
dotenv.config();
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
app.use(bodyParser.json());
|
|
||||||
|
|
||||||
// Configure routes
|
|
||||||
routes.register(app);
|
|
||||||
|
|
||||||
// start the Express server
|
// start the Express server
|
||||||
app.listen(SERVER_PORT, () => {
|
app.listen(SERVER_PORT, () => {
|
||||||
|
|||||||
11
backend/src/server.ts
Normal file
11
backend/src/server.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import express from "express";
|
||||||
|
import * as bodyParser from 'body-parser';
|
||||||
|
import * as routes from "./routes"
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
|
||||||
|
// Configure routes
|
||||||
|
routes.register(app);
|
||||||
|
|
||||||
|
export default app;
|
||||||
2885
backend/yarn.lock
2885
backend/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user