diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..8fc1c71 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,7 @@ +## Proposal + +Hello world! + +## How do test it? + +Try say hello world. diff --git a/.github/workflows/dev-specs.yaml b/.github/workflows/dev-specs.yaml index 87ce051..135f1b3 100644 --- a/.github/workflows/dev-specs.yaml +++ b/.github/workflows/dev-specs.yaml @@ -1,6 +1,6 @@ name: CI-Specs -on: [push, pull_request] +on: [push] jobs: specs-dev: diff --git a/specs/entity.e2e.spec.ts b/specs/entity.e2e.spec.ts deleted file mode 100644 index 183f2b6..0000000 --- a/specs/entity.e2e.spec.ts +++ /dev/null @@ -1,163 +0,0 @@ -import request from 'supertest'; -import WebCore from '../src/web/core'; -import express from 'express'; -import { createEntity } from './helpers'; - -const app = new WebCore(3000, express()).app; - -test('GET /entity', async () => { - await request(app) - .get('/entity?page=1&perPage=10') - .expect(200) - .expect({ - page: 1, - perPage: 10, - totalPages: 1, - entries: [] - }) -}) - -test('GET /entity with data', async () => { - await Promise.all(Array.from({ length: 20 }, createEntity)) - const response = await request(app) - .get('/entity?page=1&perPage=10') - expect(response.status).toEqual(200) - expect(response.body.page).toEqual(1) - expect(response.body.perPage).toEqual(10) - expect(response.body.totalPages).toEqual(2) - - const response2 = await request(app) - .get('/entity?page=1&perPage=20') - expect(response2.status).toEqual(200) - expect(response2.body.page).toEqual(1) - expect(response2.body.perPage).toEqual(20) -}) - -test('GET /entity without page and perPage', async () => { - await request(app) - .get('/entity') - .expect(400) -}) - -test('GET /entity with invalid page and perPage', async () => { - await request(app) - .get('/entity?page=invalid&perPage=invalid') - .expect(400) -}) - -test('GET /entity/:id', async () => { - const entity = await createEntity() - const response = await request(app) - .get(`/entity/${entity.id}`) - - expect(response.status).toEqual(200) - expect(response.body.title).toEqual(entity.title) -}) - -test('GET /entity/:id with invalid id', async () => { - await request(app) - .get('/entity/invalid') - .expect(400) -}) - -test('GET /entity/:id with non existent id', async () => { - await request(app) - .get('/entity/999999') - .expect(404) -}) - -describe('POST /entity', () => { - test('should create', async () => { - const entity = { - "title": "foo", - "properties": { - "strength": 10 - }, - "description": "Lorem lorem lorem", - "author": "John Doe", - "image": { - "src": "url", - "alt": "alt" - }, - "sections": "markdown content", - "type": "item" - } - const response = await request(app) - .post('/entity') - .send(entity) - - expect(response.statusCode).toEqual(201) - expect(response.body).toEqual(entity) - }) - test('should reject invalid entity', async () => { - await request(app) - .post('/entity') - .send({}) - .expect(400) - }) - test('should reject entity with invalid properties', async () => { - await request(app) - .post('/entity') - .send({ - "title": 1, - "properties": "invalid", - "description": "Lorem lorem lorem", - "author": "John Doe", - "image": { - "src": "url", - "alt": "alt" - }, - "sections": "markdown content", - "type": "item" - }) - .expect(400) - }) -}) - -describe('DELETE /entity/:id', () => { - test('should delete', async () => { - const entity = await createEntity() - await request(app) - .delete(`/entity/${entity.id}`) - .expect(204) - }) - test('should reject invalid id', async () => { - await request(app) - .delete('/entity/invalid') - .expect(400) - }) - test('should reject non existent id', async () => { - await request(app) - .delete('/entity/999999') - .expect(404) - }) -}) - -describe('PUT /entity/:id', () => { - test('should update', async () => { - const entity = await createEntity() - const update = { - "title": "foo 777" - } - - const updateResponse = await request(app) - .put(`/entity/${entity.id}`) - .send(update) - - expect(updateResponse.status).toEqual(204) - - const entityUpdated = await request(app).get(`/entity/${entity.id}`) - - expect(entityUpdated.body.title).toEqual("foo 777") - }) - test('should reject invalid id', async () => { - await request(app) - .put('/entity/invalid') - .expect(400) - }) - test('should reject non existent id', async () => { - await request(app) - .put('/entity/999999') - .expect(404) - }) -}) diff --git a/specs/entity/delete.e2e.spec.ts b/specs/entity/delete.e2e.spec.ts new file mode 100644 index 0000000..07390c2 --- /dev/null +++ b/specs/entity/delete.e2e.spec.ts @@ -0,0 +1,22 @@ +import request from 'supertest'; +import { app } from '../global' +import { createEntity } from '../helpers'; + +describe('DELETE /entity/:id', () => { + test('should delete', async () => { + const entity = await createEntity() + await request(app) + .delete(`/entity/${entity.id}`) + .expect(204) + }) + test('should reject invalid id', async () => { + await request(app) + .delete('/entity/invalid') + .expect(400) + }) + test('should reject non existent id', async () => { + await request(app) + .delete('/entity/999999') + .expect(404) + }) +}) diff --git a/specs/entity/get.e2e.spec.ts b/specs/entity/get.e2e.spec.ts new file mode 100644 index 0000000..1c4be25 --- /dev/null +++ b/specs/entity/get.e2e.spec.ts @@ -0,0 +1,64 @@ +import request from 'supertest'; +import { app } from '../global' +import { createEntity } from '../helpers'; + +test('GET /entity', async () => { + await request(app) + .get('/entity?page=1&perPage=10') + .expect(200) + .expect({ + page: 1, + perPage: 10, + totalPages: 1, + entries: [] + }) +}) + +test('GET /entity with data', async () => { + await Promise.all(Array.from({ length: 20 }, createEntity)) + const response = await request(app) + .get('/entity?page=1&perPage=10') + expect(response.status).toEqual(200) + expect(response.body.page).toEqual(1) + expect(response.body.perPage).toEqual(10) + expect(response.body.totalPages).toEqual(2) + + const response2 = await request(app) + .get('/entity?page=1&perPage=20') + expect(response2.status).toEqual(200) + expect(response2.body.page).toEqual(1) + expect(response2.body.perPage).toEqual(20) +}) + +test('GET /entity without page and perPage', async () => { + await request(app) + .get('/entity') + .expect(400) +}) + +test('GET /entity with invalid page and perPage', async () => { + await request(app) + .get('/entity?page=invalid&perPage=invalid') + .expect(400) +}) + +test('GET /entity/:id', async () => { + const entity = await createEntity() + const response = await request(app) + .get(`/entity/${entity.id}`) + + expect(response.status).toEqual(200) + expect(response.body.title).toEqual(entity.title) +}) + +test('GET /entity/:id with invalid id', async () => { + await request(app) + .get('/entity/invalid') + .expect(400) +}) + +test('GET /entity/:id with non existent id', async () => { + await request(app) + .get('/entity/999999') + .expect(404) +}) diff --git a/specs/entity/post.e2e.spec.ts b/specs/entity/post.e2e.spec.ts new file mode 100644 index 0000000..487f3a4 --- /dev/null +++ b/specs/entity/post.e2e.spec.ts @@ -0,0 +1,50 @@ +import request from 'supertest'; +import { app } from '../global' + +describe('POST /entity', () => { + test('should create', async () => { + const entity = { + "title": "foo", + "properties": { + "strength": 10 + }, + "description": "Lorem lorem lorem", + "author": "John Doe", + "image": { + "src": "url", + "alt": "alt" + }, + "sections": "markdown content", + "type": "item" + } + const response = await request(app) + .post('/entity') + .send(entity) + + expect(response.statusCode).toEqual(201) + expect(response.body).toEqual(entity) + }) + test('should reject invalid entity', async () => { + await request(app) + .post('/entity') + .send({}) + .expect(400) + }) + test('should reject entity with invalid properties', async () => { + await request(app) + .post('/entity') + .send({ + "title": 1, + "properties": "invalid", + "description": "Lorem lorem lorem", + "author": "John Doe", + "image": { + "src": "url", + "alt": "alt" + }, + "sections": "markdown content", + "type": "item" + }) + .expect(400) + }) +}) diff --git a/specs/entity/put.e2e.spec.ts b/specs/entity/put.e2e.spec.ts new file mode 100644 index 0000000..e357790 --- /dev/null +++ b/specs/entity/put.e2e.spec.ts @@ -0,0 +1,32 @@ +import request from 'supertest'; +import { app } from '../global' +import { createEntity } from '../helpers'; + +describe('PUT /entity/:id', () => { + test('should update', async () => { + const entity = await createEntity() + const update = { + "title": "foo 777" + } + + const updateResponse = await request(app) + .put(`/entity/${entity.id}`) + .send(update) + + expect(updateResponse.status).toEqual(204) + + const entityUpdated = await request(app).get(`/entity/${entity.id}`) + + expect(entityUpdated.body.title).toEqual("foo 777") + }) + test('should reject invalid id', async () => { + await request(app) + .put('/entity/invalid') + .expect(400) + }) + test('should reject non existent id', async () => { + await request(app) + .put('/entity/999999') + .expect(404) + }) +}) diff --git a/specs/global.ts b/specs/global.ts new file mode 100644 index 0000000..2064a3a --- /dev/null +++ b/specs/global.ts @@ -0,0 +1,4 @@ +import WebCore from '../src/web/core'; +import express from 'express'; + +export const app = new WebCore(3000, express()).app; diff --git a/specs/helpers.ts b/specs/helpers.ts index 67ce099..3b8c29a 100644 --- a/specs/helpers.ts +++ b/specs/helpers.ts @@ -5,6 +5,7 @@ import { LogModel } from '../src/models/logs/log.model'; import * as bcrypt from 'bcrypt' export const createEntity = async () => { + await EntityModel.sync({ force: true }) const createdEntity = await EntityModel.create({ "title": faker.string.uuid(), "properties": { @@ -40,7 +41,7 @@ export const findUser = async (id: number) => { return foundUser as unknown as User | null } -export const createLog = async (customType = null) => { +export const createLog = async (customType: null | any = null) => { const createdLog = await LogModel.create({ "type": customType || faker.string.uuid(), "content": "test" diff --git a/specs/logs.e2e.spec.ts b/specs/logs/get.e2e.spec.ts similarity index 85% rename from specs/logs.e2e.spec.ts rename to specs/logs/get.e2e.spec.ts index 5050f4d..00f67bd 100644 --- a/specs/logs.e2e.spec.ts +++ b/specs/logs/get.e2e.spec.ts @@ -1,10 +1,6 @@ import request from 'supertest' -import express from 'express' -import WebCore from "../src/web/core"; -import { createLog } from './helpers'; - - -const app = new WebCore(3000, express()).app +import { app } from '../global' +import { createLog } from '../helpers'; test('GET /log', async () => { diff --git a/specs/user/delete.e2e.spec.ts b/specs/user/delete.e2e.spec.ts new file mode 100644 index 0000000..585a17e --- /dev/null +++ b/specs/user/delete.e2e.spec.ts @@ -0,0 +1,22 @@ +import request from 'supertest'; +import { app } from '../global' +import { createUser } from '../helpers'; + +describe('DELETE /user/:id', () => { + test('should delete', async () => { + const user = await createUser() + await request(app) + .delete(`/user/${user.id}`) + .expect(204) + }) + test('should return 400 with invalid id', async () => { + await request(app) + .delete('/user/invalid') + .expect(400) + }) + test('should return 404 with non existent id', async () => { + await request(app) + .delete('/user/999999') + .expect(404) + }) +}) diff --git a/specs/user/get.e2e.spec.ts b/specs/user/get.e2e.spec.ts new file mode 100644 index 0000000..43c77f7 --- /dev/null +++ b/specs/user/get.e2e.spec.ts @@ -0,0 +1,31 @@ +import request from 'supertest'; +import { app } from '../global' +import { createUser } from '../helpers'; + +test('GET /user', async () => { + await request(app) + .get('/user?page=1&perPage=10') + .expect(200) + .expect([]) +}) + +test('GET /user/:id', async () => { + const user = await createUser() + const response = await request(app) + .get(`/user/${user.id}`) + + expect(response.status).toEqual(200) + expect(response.body.username).toEqual(user.username) +}) + +test('GET /user/:id with invalid id', async () => { + await request(app) + .get('/user/invalid') + .expect(400) +}) + +test('GET /user/:id with non existent id', async () => { + await request(app) + .get('/user/999999') + .expect(404) +}) diff --git a/specs/user.e2e.spec.ts b/specs/user/post.e2e.spec.ts similarity index 56% rename from specs/user.e2e.spec.ts rename to specs/user/post.e2e.spec.ts index 28236ba..3aeae01 100644 --- a/specs/user.e2e.spec.ts +++ b/specs/user/post.e2e.spec.ts @@ -1,37 +1,5 @@ import request from 'supertest'; -import WebCore from '../src/web/core'; -import express from 'express'; -import { createUser, findUser } from './helpers'; - -const app = new WebCore(3000, express()).app; - -test('GET /user', async () => { - await request(app) - .get('/user?page=1&perPage=10') - .expect(200) - .expect([]) -}) - -test('GET /user/:id', async () => { - const user = await createUser() - const response = await request(app) - .get(`/user/${user.id}`) - - expect(response.status).toEqual(200) - expect(response.body.username).toEqual(user.username) -}) - -test('GET /user/:id with invalid id', async () => { - await request(app) - .get('/user/invalid') - .expect(400) -}) - -test('GET /user/:id with non existent id', async () => { - await request(app) - .get('/user/999999') - .expect(404) -}) +import { app } from '../global' describe('POST /user', () => { test('should create', async () => { @@ -117,72 +85,6 @@ describe('POST /user', () => { }) }) -describe('DELETE /user/:id', () => { - test('should delete', async () => { - const user = await createUser() - await request(app) - .delete(`/user/${user.id}`) - .expect(204) - }) - test('should return 400 with invalid id', async () => { - await request(app) - .delete('/user/invalid') - .expect(400) - }) - test('should return 404 with non existent id', async () => { - await request(app) - .delete('/user/999999') - .expect(404) - }) -}) - -describe('PUT /user/:id', () => { - test('should update', async () => { - const user = await createUser() - await request(app) - .put(`/user/${user.id}`) - .send({ - "username": "John Doe 23" - }) - .expect(204) - - const updatedUser = await request(app).get(`/user/${user.id}`) - - expect(updatedUser.body.username).toEqual('John Doe 23') - }) - test('should return 400 with invalid id', async () => { - await request(app) - .put('/user/invalid') - .expect(400) - }) - test('should return 404 with non existent id', async () => { - await request(app) - .put('/user/999999') - .expect(404) - }) - test('should not update an user with an username that already exists', async () => { - const user = await createUser() - const user2 = await createUser() - - await request(app) - .put(`/user/${user.id}`) - .send({ - "username": user2.username - }) - .expect(409) - }) - test('should not update the password.', async () => { - const user = await createUser() - await request(app).put(`/user/${user.id}`).send({ - name: 'foo', - password: 'bar' - }).expect(204) - const foundUser = await findUser(user.id) - expect(foundUser.password).not.toEqual('bar') - expect(foundUser.name).toEqual('foo') - }) -}) - describe('POST /user/sign-in', () => { test('should sign-in', async () => { await request(app).post('/user').send({ username: 'foo-sigin', password: 'password' }) diff --git a/specs/user/put.e2e.spec.ts b/specs/user/put.e2e.spec.ts new file mode 100644 index 0000000..791f96c --- /dev/null +++ b/specs/user/put.e2e.spec.ts @@ -0,0 +1,49 @@ +import request from 'supertest'; +import { app } from '../global' +import { createUser, findUser } from '../helpers'; +describe('PUT /user/:id', () => { + test('should update', async () => { + const user = await createUser() + await request(app) + .put(`/user/${user.id}`) + .send({ + "username": "John Doe 23" + }) + .expect(204) + + const updatedUser = await request(app).get(`/user/${user.id}`) + + expect(updatedUser.body.username).toEqual('John Doe 23') + }) + test('should return 400 with invalid id', async () => { + await request(app) + .put('/user/invalid') + .expect(400) + }) + test('should return 404 with non existent id', async () => { + await request(app) + .put('/user/999999') + .expect(404) + }) + test('should not update an user with an username that already exists', async () => { + const user = await createUser() + const user2 = await createUser() + + await request(app) + .put(`/user/${user.id}`) + .send({ + "username": user2.username + }) + .expect(409) + }) + test('should not update the password.', async () => { + const user = await createUser() + await request(app).put(`/user/${user.id}`).send({ + name: 'foo', + password: 'bar' + }).expect(204) + const foundUser = await findUser(user.id) + expect(foundUser!.password).not.toEqual('bar') + expect(foundUser!.name).toEqual('foo') + }) +}) diff --git a/src/models/entity.model.ts b/src/models/entity.model.ts index afff0bd..6fb3665 100644 --- a/src/models/entity.model.ts +++ b/src/models/entity.model.ts @@ -1,6 +1,6 @@ import { DataTypes } from 'sequelize' import { storageSequelize } from '../database/connection' -import { isEnableLogging } from '../constants' +import { isEnableLogging, isTestingEnvironment } from '../constants' export type Entity = { id: number @@ -53,4 +53,4 @@ export const EntityModel = storageSequelize.define('entity', { } }) -EntityModel.sync({ force: true, logging: isEnableLogging }) +EntityModel.sync({ force: isTestingEnvironment, logging: isEnableLogging }) diff --git a/tsconfig.json b/tsconfig.json index ffe4e79..93ea3c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,11 @@ { "compilerOptions": { "esModuleInterop": true - } -} \ No newline at end of file + }, + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "specs/*.ts", + "specs/**/*.*.spec.ts" + ], +}