diff --git a/.drone.yml b/.drone.yml index 9a2a300..fb4006f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,3 +1,23 @@ +--- +kind: pipeline +name: tests:node_latest +clone: + disable: true +steps: + - name: checkout pr + image: alpine/git + commands: + - git clone $DRONE_REMOTE_URL . + - git checkout $DRONE_SOURCE_BRANCH + - name: run tests + image: node:latest + commands: + - yarn + - yarn test:ci +trigger: + event: + - pull_request + --- kind: pipeline type: docker diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..91a2d2c --- /dev/null +++ b/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; \ No newline at end of file diff --git a/package.json b/package.json index a872e2b..5c44558 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,11 @@ "licenses:export": "license-exporter --markdown", "release": "release-it --only-version", "translations:sort": "node ./scripts/sort_translations.js", - "test:generate_env": "ts-node ./scripts/create_testenv.ts" + "test": "jest", + "test:watch": "jest --watchAll", + "test:generate_env": "ts-node ./scripts/create_testenv.ts", + "test:ci": "npm run test:generate_env && npm run test:ci:run", + "test:ci:run": "start-server-and-test dev http://localhost:4010/docs/openapi.json test" }, "repository": { "type": "git", @@ -58,13 +62,17 @@ "devDependencies": { "@odit/license-exporter": "^0.0.10", "@types/express": "^4.17.11", + "@types/jest": "^26.0.20", "@types/node": "^14.14.22", "@types/nodemailer": "^6.4.0", + "axios": "^0.21.1", "cp-cli": "^2.0.0", + "jest": "^26.6.3", "nodemon": "^2.0.7", "release-it": "^14.2.2", "rimraf": "^3.0.2", "start-server-and-test": "^1.12.0", + "ts-jest": "^26.5.2", "ts-node": "^9.1.1", "typescript": "^4.1.3" }, diff --git a/src/tests/api_docs.spec.ts b/src/tests/api_docs.spec.ts new file mode 100644 index 0000000..9e9444a --- /dev/null +++ b/src/tests/api_docs.spec.ts @@ -0,0 +1,34 @@ +import axios from 'axios'; +import { config } from '../config'; +const base = "http://localhost:" + config.internal_port + +describe('GET /docs/openapi.json', () => { + it('OpenAPI Spec is availdable 200', async () => { + const res = await axios.get(base + '/docs/openapi.json'); + expect(res.status).toEqual(200); + }); +}); +describe('GET /docs/swagger.json', () => { + it('OpenAPI Spec is availdable 200', async () => { + const res = await axios.get(base + '/docs/swagger.json'); + expect(res.status).toEqual(200); + }); +}); +describe('GET /docs/swaggerui', () => { + it('swaggerui is availdable 200', async () => { + const res = await axios.get(base + '/docs/swaggerui'); + expect(res.status).toEqual(200); + }); +}); +describe('GET /docs/redoc', () => { + it('redoc is availdable 200', async () => { + const res = await axios.get(base + '/docs/redoc'); + expect(res.status).toEqual(200); + }); +}); +describe('GET /docs/rapidoc', () => { + it('rapidoc is availdable 200', async () => { + const res = await axios.get(base + '/docs/rapidoc'); + expect(res.status).toEqual(200); + }); +}); diff --git a/src/tests/pw_reset_mail.spec.ts b/src/tests/pw_reset_mail.spec.ts new file mode 100644 index 0000000..d43f3a3 --- /dev/null +++ b/src/tests/pw_reset_mail.spec.ts @@ -0,0 +1,72 @@ +import axios from 'axios'; +import { config } from '../config'; +const base = "http://localhost:" + config.internal_port + +const axios_config = { + validateStatus: undefined +}; + +describe('POST /reset without auth', () => { + it('Post without auth should return 401', async () => { + const res = await axios.post(base + '/reset', null, axios_config); + expect(res.status).toEqual(401); + }); +}); + +describe('POST /reset with auth but wrong body', () => { + it('Post with auth but no body should return 400', async () => { + const res = await axios.post(base + '/reset?key=' + config.api_key, null, axios_config); + expect(res.status).toEqual(400); + }); + it('Post with auth but no mail should return 400', async () => { + const res = await axios.post(base + '/reset?key=' + config.api_key, { resetKey: "test" }, axios_config); + expect(res.status).toEqual(400); + }); + it('Post with auth but no reset key should return 400', async () => { + const res = await axios.post(base + '/reset?key=' + config.api_key, { address: "test@dev.lauf-fuer-kaya.de" }, axios_config); + expect(res.status).toEqual(400); + }); + it('Post with auth but invalid mail should return 400', async () => { + const res = await axios.post(base + '/reset?key=' + config.api_key, { resetKey: "test", address: "testdev.l.de" }, axios_config); + expect(res.status).toEqual(400); + }); +}); + +describe('POST /reset with auth and vaild body', () => { + it('Post with auth, body and no locale should return 200', async () => { + const res = await axios.post(base + '/reset?key=' + config.api_key, { + resetKey: "test", + address: "test@dev.lauf-fuer-kaya.de" + }, axios_config); + expect(res.status).toEqual(200); + expect(res.data).toEqual({ + success: true, + message: "Sent!", + locale: "en" + }) + }); + it('Post with auth, body and locale=en should return 200', async () => { + const res = await axios.post(base + '/reset?locale=en&key=' + config.api_key, { + resetKey: "test", + address: "test@dev.lauf-fuer-kaya.de" + }, axios_config); + expect(res.status).toEqual(200); + expect(res.data).toEqual({ + success: true, + message: "Sent!", + locale: "en" + }) + }); + it('Post with auth, body and locale=de should return 200', async () => { + const res = await axios.post(base + '/reset?locale=de&key=' + config.api_key, { + resetKey: "test", + address: "test@dev.lauf-fuer-kaya.de" + }, axios_config); + expect(res.status).toEqual(200); + expect(res.data).toEqual({ + success: true, + message: "Sent!", + locale: "de" + }) + }); +}); \ No newline at end of file diff --git a/src/tests/test_mail.spec.ts b/src/tests/test_mail.spec.ts new file mode 100644 index 0000000..ff3dac6 --- /dev/null +++ b/src/tests/test_mail.spec.ts @@ -0,0 +1,44 @@ +import axios from 'axios'; +import { config } from '../config'; +const base = "http://localhost:" + config.internal_port + +const axios_config = { + validateStatus: undefined +}; + +describe('POST /test without auth', () => { + it('Post without auth should return 401', async () => { + const res = await axios.post(base + '/test', null, axios_config); + expect(res.status).toEqual(401); + }); +}); + +describe('POST /test with auth', () => { + it('Post with auth and no locale should return 200', async () => { + const res = await axios.post(base + '/test?key=' + config.api_key, null, axios_config); + expect(res.status).toEqual(200); + expect(res.data).toEqual({ + success: true, + message: "Sent!", + locale: "en" + }) + }); + it('Post with auth and locale=en should return 200', async () => { + const res = await axios.post(base + '/test?locale=en&key=' + config.api_key, null, axios_config); + expect(res.status).toEqual(200); + expect(res.data).toEqual({ + success: true, + message: "Sent!", + locale: "en" + }) + }); + it('Post with auth and locale=de should return 200', async () => { + const res = await axios.post(base + '/test?locale=de&key=' + config.api_key, null, axios_config); + expect(res.status).toEqual(200); + expect(res.data).toEqual({ + success: true, + message: "Sent!", + locale: "de" + }) + }); +}); \ No newline at end of file