From 88608a24091997f78a1fd74fc0da8b994fd3fed3 Mon Sep 17 00:00:00 2001 From: Pedro Hernandez-Mora de Fuentes Date: Sun, 13 Dec 2020 14:14:59 +0100 Subject: [PATCH 1/3] DEV-43: wip --- src/OAuth/Application/CreateGoogleUser.ts | 10 ++----- src/OAuth/Application/DeleteGithubUser.ts | 30 +++++++++++++++++++ src/OAuth/Application/DeleteGoogleUser.ts | 30 +++++++++++++++++++ src/OAuth/Application/DeleteSlackUser.ts | 30 +++++++++++++++++++ src/OAuth/Infraestructure/GithubController.ts | 15 +++++++++- src/OAuth/Infraestructure/GoogleController.ts | 15 +++++++++- src/OAuth/Infraestructure/SlackController.ts | 15 +++++++++- typeorm/migration/1607289614568-user-orm.ts | 2 +- 8 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 src/OAuth/Application/DeleteGithubUser.ts create mode 100644 src/OAuth/Application/DeleteSlackUser.ts diff --git a/src/OAuth/Application/CreateGoogleUser.ts b/src/OAuth/Application/CreateGoogleUser.ts index 832c8f5..84d41d6 100644 --- a/src/OAuth/Application/CreateGoogleUser.ts +++ b/src/OAuth/Application/CreateGoogleUser.ts @@ -2,9 +2,9 @@ import { inject } from 'inversify'; import TYPES from '../../constant/types'; import { InputService } from '../../InputService'; import { Logger } from '../../Logger'; -//import { InvalidUserCreate } from '../Domain/InvalidUserCreate'; import { User } from '../Domain/User'; import { UserRepository } from '../Domain/UserRepository'; +import { ValidUser } from '../Domain/ValidUser'; export class CreateGoogleUser implements InputService { private readonly logger: Logger; @@ -18,14 +18,8 @@ export class CreateGoogleUser implements InputService { this.logger = logger; } - //@ts-ignore - async execute(googleUser: ValidUser): any { + async execute(googleUser: ValidUser): Promise { try { - //const repoPromise = this.repo.findUserByEmail(googleUser.email); - //const user = await repoPromise.then(userdata => userdata); - /*if (user) { - throw new InvalidUserCreate(`El usuario ${user.email} ya se encuentra registrado`); - }*/ this.logger.log(`Intentando almacenar ${JSON.stringify(googleUser)}`); await this.repo.createUser(new User(googleUser)); return { success: 'true' }; diff --git a/src/OAuth/Application/DeleteGithubUser.ts b/src/OAuth/Application/DeleteGithubUser.ts new file mode 100644 index 0000000..d0f116c --- /dev/null +++ b/src/OAuth/Application/DeleteGithubUser.ts @@ -0,0 +1,30 @@ +import { inject } from 'inversify'; +import TYPES from '../../constant/types'; +import { InputService } from '../../InputService'; +import { Logger } from '../../Logger'; +import { UserRepository } from '../Domain/UserRepository'; + +export class DeleteGithubUser implements InputService { + private readonly logger: Logger; + private readonly repo: UserRepository; + + constructor( + @inject(TYPES.UserRepository) repo: UserRepository, + @inject(TYPES.Logger) logger: Logger, + ) { + this.repo = repo; + this.logger = logger; + } + + //@ts-ignore + async execute(id: string): Promise { + try { + this.logger.log(`Intentando borrar ${JSON.stringify(id)}`); + await this.repo.deleteUser(id); + return { success: 'true' }; + } catch (err) { + this.logger.error(err); + throw err; + } + } +} diff --git a/src/OAuth/Application/DeleteGoogleUser.ts b/src/OAuth/Application/DeleteGoogleUser.ts index e69de29..10a4315 100644 --- a/src/OAuth/Application/DeleteGoogleUser.ts +++ b/src/OAuth/Application/DeleteGoogleUser.ts @@ -0,0 +1,30 @@ +import { inject } from 'inversify'; +import TYPES from '../../constant/types'; +import { InputService } from '../../InputService'; +import { Logger } from '../../Logger'; +import { UserRepository } from '../Domain/UserRepository'; + +export class DeleteGoogleUser implements InputService { + private readonly logger: Logger; + private readonly repo: UserRepository; + + constructor( + @inject(TYPES.UserRepository) repo: UserRepository, + @inject(TYPES.Logger) logger: Logger, + ) { + this.repo = repo; + this.logger = logger; + } + + //@ts-ignore + async execute(id: string): Promise { + try { + this.logger.log(`Intentando borrar ${JSON.stringify(id)}`); + await this.repo.deleteUser(id); + return { success: 'true' }; + } catch (err) { + this.logger.error(err); + throw err; + } + } +} diff --git a/src/OAuth/Application/DeleteSlackUser.ts b/src/OAuth/Application/DeleteSlackUser.ts new file mode 100644 index 0000000..c39f6c4 --- /dev/null +++ b/src/OAuth/Application/DeleteSlackUser.ts @@ -0,0 +1,30 @@ +import { inject } from 'inversify'; +import TYPES from '../../constant/types'; +import { InputService } from '../../InputService'; +import { Logger } from '../../Logger'; +import { UserRepository } from '../Domain/UserRepository'; + +export class DeleteSlackUser implements InputService { + private readonly logger: Logger; + private readonly repo: UserRepository; + + constructor( + @inject(TYPES.UserRepository) repo: UserRepository, + @inject(TYPES.Logger) logger: Logger, + ) { + this.repo = repo; + this.logger = logger; + } + + //@ts-ignore + async execute(id: string): Promise { + try { + this.logger.log(`Intentando borrar ${JSON.stringify(id)}`); + await this.repo.deleteUser(id); + return { success: 'true' }; + } catch (err) { + this.logger.error(err); + throw err; + } + } +} diff --git a/src/OAuth/Infraestructure/GithubController.ts b/src/OAuth/Infraestructure/GithubController.ts index c00b91d..560eb85 100644 --- a/src/OAuth/Infraestructure/GithubController.ts +++ b/src/OAuth/Infraestructure/GithubController.ts @@ -1,5 +1,5 @@ import { UserRepository } from './../Domain/UserRepository'; -import { controller, httpGet } from 'inversify-express-utils'; +import { controller, httpGet, response, requestParam } from 'inversify-express-utils'; import { Request, Response, NextFunction } from 'express'; import { OauthMiddleware } from './OauthMiddleware'; import { Logger } from '../../Logger'; @@ -7,6 +7,7 @@ import { inject } from 'inversify'; import TYPES from '../../constant/types'; import { CreateGithubUser } from '../Application/CreateGithubUser'; import PROVIDER from '../../constant/providers'; +import { DeleteGithubUser } from '../Application/DeleteGithubUser'; const OAUTH_PROVIDER = 'github'; const OAUTH_CONFIG = { scope: ['user:email'], @@ -54,4 +55,16 @@ export class GithubController { provider: PROVIDER.GITHUB, }); } + + @httpGet('/delete/:id') + public async delete(@response() response: Response, @requestParam('id') idParam: string) { + const deleteGithubUser = new DeleteGithubUser(this.repo, this.logger); + + try { + return await deleteGithubUser.execute(idParam); + } catch (error) { + this.logger.error(error); + response.sendStatus(500); + } + } } diff --git a/src/OAuth/Infraestructure/GoogleController.ts b/src/OAuth/Infraestructure/GoogleController.ts index 4a8ed97..7efdf03 100644 --- a/src/OAuth/Infraestructure/GoogleController.ts +++ b/src/OAuth/Infraestructure/GoogleController.ts @@ -1,4 +1,4 @@ -import { controller, httpGet } from 'inversify-express-utils'; +import { controller, httpGet, response, requestParam } from 'inversify-express-utils'; import { Request, Response, NextFunction } from 'express'; import { inject } from 'inversify'; import TYPES from '../../constant/types'; @@ -7,6 +7,7 @@ import { CreateGoogleUser } from '../Application/CreateGoogleUser'; import { OauthMiddleware } from './OauthMiddleware'; import { UserRepository } from '../Domain/UserRepository'; import PROVIDER from '../../constant/providers'; +import { DeleteGoogleUser } from '../Application/DeleteGoogleUser'; const OAUTH_PROVIDER = 'google'; const OAUTH_CONFIG = { scope: ['profile', 'email'] }; @@ -56,4 +57,16 @@ export class GoogleController { response.sendStatus(500); } } + + @httpGet('/delete/:id') + public async delete(@response() response: Response, @requestParam('id') idParam: string) { + const deleteGoogleUser = new DeleteGoogleUser(this.repo, this.logger); + + try { + return await deleteGoogleUser.execute(idParam); + } catch (error) { + this.logger.error(error); + response.sendStatus(500); + } + } } diff --git a/src/OAuth/Infraestructure/SlackController.ts b/src/OAuth/Infraestructure/SlackController.ts index df3d29d..cf86227 100644 --- a/src/OAuth/Infraestructure/SlackController.ts +++ b/src/OAuth/Infraestructure/SlackController.ts @@ -1,5 +1,5 @@ import { UserRepository } from './../Domain/UserRepository'; -import { controller, httpGet } from 'inversify-express-utils'; +import { controller, httpGet, response, requestParam } from 'inversify-express-utils'; import { Request, Response, NextFunction } from 'express'; import { OauthMiddleware } from './OauthMiddleware'; import { CreateSlackUser } from '../Application/CreateSlackUser'; @@ -7,6 +7,7 @@ import { Logger } from '../../Logger'; import { inject } from 'inversify'; import TYPES from '../../constant/types'; import PROVIDER from '../../constant/providers'; +import { DeleteSlackUser } from '../Application/DeleteSlackUser'; const OAUTH_PROVIDER = 'Slack'; const OAUTH_CONFIG = { scope: ['identity.basic', 'identity.email', 'identity.avatar', 'identity.team'], @@ -51,4 +52,16 @@ export class SlackController { provider: PROVIDER.SLACK, }); } + + @httpGet('/delete/:id') + public async delete(@response() response: Response, @requestParam('id') idParam: string) { + const deleteSlackUser = new DeleteSlackUser(this.repo, this.logger); + + try { + return await deleteSlackUser.execute(idParam); + } catch (error) { + this.logger.error(error); + response.sendStatus(500); + } + } } diff --git a/typeorm/migration/1607289614568-user-orm.ts b/typeorm/migration/1607289614568-user-orm.ts index 49c9eb8..efe7e12 100644 --- a/typeorm/migration/1607289614568-user-orm.ts +++ b/typeorm/migration/1607289614568-user-orm.ts @@ -5,7 +5,7 @@ export class userOrm1607289614568 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query( - 'CREATE TABLE `user_orm` (`id` varchar(36) NOT NULL, `displayName` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, `image` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `provider` varchar(255) NOT NULL, `createAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `deleteAt` timestamp NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB', + 'CREATE TABLE `user_orm` (`id` varchar(255) NOT NULL, `displayName` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, `image` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `provider` varchar(255) NOT NULL, `createAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `deleteAt` timestamp NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB', ); } From 8979d149b3597a798b825400d150d7ae7635cc04 Mon Sep 17 00:00:00 2001 From: Emmanuel Valverde Ramos Date: Sun, 13 Dec 2020 17:18:02 +0100 Subject: [PATCH 2/3] =?UTF-8?q?WIP=20=F0=9F=94=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 12 ++++---- package-lock.json | 29 ++++++++----------- package.json | 3 +- src/OAuth/Domain/UUID.ts | 13 +++++++++ src/OAuth/Domain/User.ts | 17 +++++++---- src/OAuth/Domain/ValidUser.ts | 2 +- .../Infraestructure/TypeORMUserRepository.ts | 1 + src/OAuth/Infraestructure/UserORM.entity.ts | 1 + .../Application/CreateGoogleUser.test.ts | 4 +-- src/__test__/OAuth/Domain/User.test.ts | 24 +++++++-------- .../TypeORMUserRepository.test.ts | 6 ++-- typeorm/migration/1607289614568-user-orm.ts | 2 +- 12 files changed, 65 insertions(+), 49 deletions(-) create mode 100644 src/OAuth/Domain/UUID.ts diff --git a/.env.example b/.env.example index 648c0be..209407c 100644 --- a/.env.example +++ b/.env.example @@ -19,6 +19,7 @@ MYSQL_PASSWD_DEV= SQL_DUMP= ## MYSQL TEST +MYSQL_TEST_NAME= MYSQL_VERSION_TEST= MYSQL_HOST_TEST= MYSQL_PORT_TEST= @@ -28,6 +29,8 @@ MYSQL_PASSWD_TEST= MYSQL_USER_DEV_TEST= MYSQL_PASSWD_DEV_TEST= +LOCALHOST= + DOMAIN_URL= #DEV @@ -35,7 +38,7 @@ NODE_ENV= ORM_TYPE_OF_DB= # sudo apt-get install uuid-runtime # Random UUID generated with uuidgen -r - +COOKIE_UUID_KEY1= COOKIE_UUID_KEY2= # Google OAuth @@ -47,10 +50,5 @@ CALLBACK_URL= SLACK_CLIENT_ID= SLACK_CLIENT_SECRET= -# Github OAuth GITHUB_CLIENT_ID= -GITHUB_CLIENT_SECRET= - -LOCALHOST= -MYSQL_TEST_NAME= -COOKIE_UUID_KEY1= +GITHUB_CLIENT_SECRET= \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d76b7e1..6569579 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,8 @@ "passport-slack": "0.0.7", "passport-slack-oauth2": "^1.0.2", "reflect-metadata": "^0.1.10", - "typeorm": "0.2.29" + "typeorm": "0.2.29", + "uuid": "^8.3.2" }, "devDependencies": { "@commitlint/cli": "^11.0.0", @@ -3649,7 +3650,8 @@ "version": "3.6.5", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", - "dev": true + "dev": true, + "hasInstallScript": true }, "node_modules/core-util-is": { "version": "1.0.2", @@ -5662,6 +5664,7 @@ "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.5.tgz", "integrity": "sha512-E5S/1HMoDDaqsH8kDF5zeKEQbYqe3wL9zJDyqyYqc8I4vHBtAoxkDBGXox0lZ9RI+k5GyB728vZdmnM4bYap+g==", "dev": true, + "hasInstallScript": true, "dependencies": { "chalk": "^4.0.0", "ci-info": "^2.0.0", @@ -8564,6 +8567,7 @@ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.6.tgz", "integrity": "sha512-4I3YDSKXg6ltYpcnZeHompqac4E6JeAMpGm8tJnB9Y3T0ehasLa4139dJOcCrB93HHrUMsCrKtoAlXTqT5n4AQ==", "dev": true, + "hasInstallScript": true, "dependencies": { "chokidar": "^3.2.2", "debug": "^3.2.6", @@ -10628,11 +10632,6 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, "engines": { "node": ">=0.10.0" } @@ -11866,11 +11865,9 @@ } }, "node_modules/uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", - "dev": true, - "optional": true, + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" } @@ -21919,11 +21916,9 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", - "dev": true, - "optional": true + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-to-istanbul": { "version": "7.0.0", diff --git a/package.json b/package.json index cee2da9..37d06d3 100644 --- a/package.json +++ b/package.json @@ -136,7 +136,8 @@ "passport-slack": "0.0.7", "passport-slack-oauth2": "^1.0.2", "reflect-metadata": "^0.1.10", - "typeorm": "0.2.29" + "typeorm": "0.2.29", + "uuid": "^8.3.2" }, "devDependencies": { "@commitlint/cli": "^11.0.0", diff --git a/src/OAuth/Domain/UUID.ts b/src/OAuth/Domain/UUID.ts new file mode 100644 index 0000000..36081a9 --- /dev/null +++ b/src/OAuth/Domain/UUID.ts @@ -0,0 +1,13 @@ +import { v4 as uuidv4 } from 'uuid'; + +export class UUID { + readonly value: string; + + constructor() { + this.value = uuidv4(); + } + + equals(id: UUID) { + return this.value === id.value; + } +} diff --git a/src/OAuth/Domain/User.ts b/src/OAuth/Domain/User.ts index 7889f12..670bff4 100644 --- a/src/OAuth/Domain/User.ts +++ b/src/OAuth/Domain/User.ts @@ -6,9 +6,11 @@ import { Email } from './Email'; import { InvalidUserError } from './InvalidUserError'; import { ValidUser } from './ValidUser'; import { UserName } from './UsesrName'; +import { UUID } from './UUID'; export class User { - _id: Id; + _id: UUID; + _idFromProvider: Id; _displayName: Name; _username: UserName; _image: Image; @@ -18,7 +20,8 @@ export class User { constructor(user: ValidUser) { // TODO: Refactor it should be able to handle multiple errors try { - this.id = user.id; + this._id = new UUID(); + this.idFromProvider = user.idFromProvider; this.displayName = user.displayName; this.username = user.username; this.image = user.image; @@ -37,8 +40,12 @@ export class User { return this._id.value; } - set id(id: string) { - this._id = new Id(id); + get idFromProvider(): string { + return this._idFromProvider.value; + } + + set idFromProvider(idFromProvider: string) { + this._idFromProvider = new Id(idFromProvider); } get displayName(): string { @@ -84,7 +91,7 @@ export class User { equals(user: ValidUser): boolean { const comparator = new User(user); return ( - this._id.equals(comparator._id) && + this._idFromProvider.equals(comparator._idFromProvider) && this._displayName.equals(comparator._displayName) && this._image.equals(comparator._image) && this._username.equals(comparator._username) && diff --git a/src/OAuth/Domain/ValidUser.ts b/src/OAuth/Domain/ValidUser.ts index 771a254..ad58c8c 100644 --- a/src/OAuth/Domain/ValidUser.ts +++ b/src/OAuth/Domain/ValidUser.ts @@ -1,5 +1,5 @@ interface ValidUser { - readonly id: string; + readonly idFromProvider: string; readonly displayName: string; readonly username: string; readonly image: string; diff --git a/src/OAuth/Infraestructure/TypeORMUserRepository.ts b/src/OAuth/Infraestructure/TypeORMUserRepository.ts index 10ceb7e..9285d10 100644 --- a/src/OAuth/Infraestructure/TypeORMUserRepository.ts +++ b/src/OAuth/Infraestructure/TypeORMUserRepository.ts @@ -58,6 +58,7 @@ class TypeORMUserRepository implements UserRepository { domainUserToOrmUserData(user: User): object { return { id: user.id, + idFromProvider: user.idFromProvider, displayName: user.displayName, username: user.username, image: user.image, diff --git a/src/OAuth/Infraestructure/UserORM.entity.ts b/src/OAuth/Infraestructure/UserORM.entity.ts index 2e87a36..a72bfd7 100644 --- a/src/OAuth/Infraestructure/UserORM.entity.ts +++ b/src/OAuth/Infraestructure/UserORM.entity.ts @@ -3,6 +3,7 @@ import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; @Entity() class UserORM { @PrimaryGeneratedColumn('uuid') id: string; + @Column() idFromProvider: string; @Column() displayName: string; @Column() username: string; @Column() image: string; diff --git a/src/__test__/OAuth/Application/CreateGoogleUser.test.ts b/src/__test__/OAuth/Application/CreateGoogleUser.test.ts index d53878b..e446e2a 100644 --- a/src/__test__/OAuth/Application/CreateGoogleUser.test.ts +++ b/src/__test__/OAuth/Application/CreateGoogleUser.test.ts @@ -7,7 +7,7 @@ import PROVIDER from '../../../constant/providers'; const USERS_DATA: ValidUser[] = [ { - id: '1dfgsdfg', + idFromProvider: '1dfgsdfg', displayName: 'Della', username: 'Cox', image: 'https://goole.com', @@ -15,7 +15,7 @@ const USERS_DATA: ValidUser[] = [ provider: PROVIDER.GOOGLE, }, { - id: 'sdfsdf', + idFromProvider: 'sdfsdf', displayName: 'Denn', username: 'dsfgff', image: 'https://twitter.com', diff --git a/src/__test__/OAuth/Domain/User.test.ts b/src/__test__/OAuth/Domain/User.test.ts index dd97fb4..7e0908d 100644 --- a/src/__test__/OAuth/Domain/User.test.ts +++ b/src/__test__/OAuth/Domain/User.test.ts @@ -4,7 +4,7 @@ import { ValidUser } from '../../../OAuth/Domain/ValidUser'; const DATA = [ { - id: '1', + idFromProvider: '1', displayName: 'Della', username: '@Cox', email: 'DellaDCox@superrito.com', @@ -12,7 +12,7 @@ const DATA = [ provider: PROVIDER.GOOGLE, }, { - id: '2', + idFromProvider: '2', displayName: 'ksjdfh kasjdfh ', username: '@lsdkfjlksjdf', email: 'DellaDCox@superrito.com', @@ -20,7 +20,7 @@ const DATA = [ provider: PROVIDER.GITHUB, }, { - id: '3', + idFromProvider: '3', displayName: 'sdf kasjdfh ', username: '@sdfsdf', email: 'DellaDCox@superrito.com', @@ -33,7 +33,7 @@ const VALID_USER_DATA: ValidUser[] = new Array(...DATA); const INVALID_DATA = [ { - id: '', + idFromProvider: '', displayName: 'ksjdfh kasjdfh ', username: '@lsdkfjlksjdf', email: 'DellaDCox@superrito.com', @@ -41,7 +41,7 @@ const INVALID_DATA = [ provider: 'google', }, { - id: '2', + idFromProvider: '2', displayName: '', username: '@lsdkfjlksjdf', email: 'DellaDCox@superrito.com', @@ -49,7 +49,7 @@ const INVALID_DATA = [ provider: 'google', }, { - id: '3', + idFromProvider: '3', displayName: 'ksjdfh kasjdfh ', username: '', email: 'DellaDCox@superrito.com', @@ -57,7 +57,7 @@ const INVALID_DATA = [ provider: 'google', }, { - id: '4', + idFromProvider: '4', displayName: 'ksjdfh kasjdfh ', username: '@lsdkfjlksjdf', email: '@superrito.com', @@ -65,7 +65,7 @@ const INVALID_DATA = [ provider: 'google', }, { - id: '5', + idFromProvider: '5', displayName: 'ksjdfh kasjdfh ', username: '@lsdkfjlksjdf', email: 'DellaDCox@superrito.com', @@ -73,7 +73,7 @@ const INVALID_DATA = [ provider: 'google', }, { - id: '6', + idFromProvider: '6', displayName: 'ksjdfh kasjdfh ', username: '@lsdkfjlksjdf', email: 'DellaDCox@superrito.com', @@ -81,7 +81,7 @@ const INVALID_DATA = [ provider: 'GOOGLE', }, { - id: '7', + idFromProvider: '7', displayName: 'ksjdfh kasjdfh ', username: '@lsdkfjlksjdf', email: 'DellaDCox@superrito.com', @@ -93,7 +93,7 @@ const INVALID_DATA = [ const INVALID_USER_DATA: ValidUser[] = new Array(...INVALID_DATA); const USER_JSON: ValidUser = { - id: '1', + idFromProvider: '1', displayName: 'Della', username: '@Cox', email: 'DellaDCox@superrito.com', @@ -111,7 +111,7 @@ describe('It should create users with the correct data', () => { it('should return a valid JSON from a user', () => { expect( new User({ - id: '1', + idFromProvider: '1', displayName: 'Della', username: '@Cox', email: 'DellaDCox@superrito.com', diff --git a/src/__test__/OAuth/Infraestructure/TypeORMUserRepository.test.ts b/src/__test__/OAuth/Infraestructure/TypeORMUserRepository.test.ts index 80c774c..7dc0968 100644 --- a/src/__test__/OAuth/Infraestructure/TypeORMUserRepository.test.ts +++ b/src/__test__/OAuth/Infraestructure/TypeORMUserRepository.test.ts @@ -26,7 +26,7 @@ describe('[Integration] TypeORMUserRepository', () => { describe('[Integration] TypeORMUserRepository trying to use all the methods of the repository', () => { it('should insert a new user', async () => { const userToInsert: User = new User({ - id: '1', + idFromProvider: '1', displayName: 'Della', username: '@Coxi', email: 'DellaDCox@superrito.com', @@ -35,12 +35,12 @@ describe('[Integration] TypeORMUserRepository', () => { }); await repo.createUser(userToInsert); - const userFromDb: User = await repo.findUserByID('1'); + const userFromDb: User = await repo.findUserByID(userToInsert.id); expect(await userFromDb.equals(userToInsert)).toBe(true); }); it('should delete a user', async () => { const userToInsert: User = new User({ - id: '2', + idFromProvider: '2', displayName: 'Antonio', username: '@Chj', email: 'AntonioChj@superrito.com', diff --git a/typeorm/migration/1607289614568-user-orm.ts b/typeorm/migration/1607289614568-user-orm.ts index efe7e12..db49387 100644 --- a/typeorm/migration/1607289614568-user-orm.ts +++ b/typeorm/migration/1607289614568-user-orm.ts @@ -5,7 +5,7 @@ export class userOrm1607289614568 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query( - 'CREATE TABLE `user_orm` (`id` varchar(255) NOT NULL, `displayName` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, `image` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `provider` varchar(255) NOT NULL, `createAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `deleteAt` timestamp NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB', + 'CREATE TABLE `user_orm` (`id` varchar(36) NOT NULL, `idFromProvider` varchar(255) NOT NULL, `displayName` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, `image` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `provider` varchar(255) NOT NULL, `createAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `deleteAt` timestamp NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB', ); } From 0eec69d4abee309ba9b5a133197d21700b7677c6 Mon Sep 17 00:00:00 2001 From: Pedro Hernandez-Mora de Fuentes Date: Sun, 13 Dec 2020 18:17:45 +0100 Subject: [PATCH 3/3] DEV-43: new unit test and modify integration test --- .env.example | 12 +++--- src/OAuth/Domain/UserNotExists.ts | 8 ++++ src/OAuth/Infraestructure/GithubController.ts | 4 +- src/OAuth/Infraestructure/GoogleController.ts | 4 +- src/OAuth/Infraestructure/SlackController.ts | 4 +- .../Infraestructure/TypeORMUserRepository.ts | 8 +++- .../Application/CreateGithubUser.test.ts | 38 +++++++++++++++++++ .../OAuth/Application/CreateSlackUser.test.ts | 38 +++++++++++++++++++ .../Application/DeleteGithubUser.test.ts | 17 +++++++++ .../OAuth/Application/DeleteSlackUser.test.ts | 17 +++++++++ .../TypeORMUserRepository.test.ts | 3 +- 11 files changed, 138 insertions(+), 15 deletions(-) create mode 100644 src/OAuth/Domain/UserNotExists.ts create mode 100644 src/__test__/OAuth/Application/CreateGithubUser.test.ts create mode 100644 src/__test__/OAuth/Application/CreateSlackUser.test.ts create mode 100644 src/__test__/OAuth/Application/DeleteGithubUser.test.ts create mode 100644 src/__test__/OAuth/Application/DeleteSlackUser.test.ts diff --git a/.env.example b/.env.example index 209407c..648c0be 100644 --- a/.env.example +++ b/.env.example @@ -19,7 +19,6 @@ MYSQL_PASSWD_DEV= SQL_DUMP= ## MYSQL TEST -MYSQL_TEST_NAME= MYSQL_VERSION_TEST= MYSQL_HOST_TEST= MYSQL_PORT_TEST= @@ -29,8 +28,6 @@ MYSQL_PASSWD_TEST= MYSQL_USER_DEV_TEST= MYSQL_PASSWD_DEV_TEST= -LOCALHOST= - DOMAIN_URL= #DEV @@ -38,7 +35,7 @@ NODE_ENV= ORM_TYPE_OF_DB= # sudo apt-get install uuid-runtime # Random UUID generated with uuidgen -r -COOKIE_UUID_KEY1= + COOKIE_UUID_KEY2= # Google OAuth @@ -50,5 +47,10 @@ CALLBACK_URL= SLACK_CLIENT_ID= SLACK_CLIENT_SECRET= +# Github OAuth GITHUB_CLIENT_ID= -GITHUB_CLIENT_SECRET= \ No newline at end of file +GITHUB_CLIENT_SECRET= + +LOCALHOST= +MYSQL_TEST_NAME= +COOKIE_UUID_KEY1= diff --git a/src/OAuth/Domain/UserNotExists.ts b/src/OAuth/Domain/UserNotExists.ts new file mode 100644 index 0000000..19e0bed --- /dev/null +++ b/src/OAuth/Domain/UserNotExists.ts @@ -0,0 +1,8 @@ +class UserNotExists extends Error { + constructor(message: string) { + super(`UserNotExists: ${message}`); + Object.setPrototypeOf(this, UserNotExists.prototype); + } +} + +export { UserNotExists }; diff --git a/src/OAuth/Infraestructure/GithubController.ts b/src/OAuth/Infraestructure/GithubController.ts index 560eb85..299b35f 100644 --- a/src/OAuth/Infraestructure/GithubController.ts +++ b/src/OAuth/Infraestructure/GithubController.ts @@ -47,7 +47,7 @@ export class GithubController { const displayName = user.displayName ? user.displayName : user.username; return createGithubUser.execute({ - id: user.id, + idFromProvider: user.id, displayName: displayName, username: user.username, image: user.photos[0].value, @@ -64,7 +64,7 @@ export class GithubController { return await deleteGithubUser.execute(idParam); } catch (error) { this.logger.error(error); - response.sendStatus(500); + response.sendStatus(404); } } } diff --git a/src/OAuth/Infraestructure/GoogleController.ts b/src/OAuth/Infraestructure/GoogleController.ts index 7efdf03..08e2cf6 100644 --- a/src/OAuth/Infraestructure/GoogleController.ts +++ b/src/OAuth/Infraestructure/GoogleController.ts @@ -45,7 +45,7 @@ export class GoogleController { const createGoogleUser = new CreateGoogleUser(this.repo, this.logger); try { return await createGoogleUser.execute({ - id: user._json.sub, + idFromProvider: user._json.sub, displayName: user._json.name, username: user._json.email, image: user._json.picture, @@ -66,7 +66,7 @@ export class GoogleController { return await deleteGoogleUser.execute(idParam); } catch (error) { this.logger.error(error); - response.sendStatus(500); + response.sendStatus(404); } } } diff --git a/src/OAuth/Infraestructure/SlackController.ts b/src/OAuth/Infraestructure/SlackController.ts index cf86227..0013ca2 100644 --- a/src/OAuth/Infraestructure/SlackController.ts +++ b/src/OAuth/Infraestructure/SlackController.ts @@ -44,7 +44,7 @@ export class SlackController { const createSlackUser = new CreateSlackUser(this.repo, this.logger); return createSlackUser.execute({ - id: user.id, + idFromProvider: user.id, displayName: user.name, username: user.name, image: user.image_512, @@ -61,7 +61,7 @@ export class SlackController { return await deleteSlackUser.execute(idParam); } catch (error) { this.logger.error(error); - response.sendStatus(500); + response.sendStatus(404); } } } diff --git a/src/OAuth/Infraestructure/TypeORMUserRepository.ts b/src/OAuth/Infraestructure/TypeORMUserRepository.ts index 9285d10..285e942 100644 --- a/src/OAuth/Infraestructure/TypeORMUserRepository.ts +++ b/src/OAuth/Infraestructure/TypeORMUserRepository.ts @@ -12,6 +12,7 @@ import { injectable } from 'inversify'; import { inject } from 'inversify'; import TYPES from '../../constant/types'; import { DateTime } from '../Domain/DateTime'; +import { UserNotExists } from '../Domain/UserNotExists'; @injectable() class TypeORMUserRepository implements UserRepository { @@ -31,7 +32,10 @@ class TypeORMUserRepository implements UserRepository { async deleteUser(id: string) { const ORMRepo = await this.databaseConnection.getRepository(UserORM); - const user = await ORMRepo.findOne({ where: { id: id } }); + const user = await ORMRepo.findOne({ where: { id: id, deleteAt: IsNull() } }); + if (!user) { + throw new UserNotExists(`The user with id ${id} does not exists`); + } user.deleteAt = DateTime.now(); await ORMRepo.save(user); } @@ -40,7 +44,7 @@ class TypeORMUserRepository implements UserRepository { const ORMRepo = await this.databaseConnection.getRepository(UserORM); const user = await ORMRepo.findOne({ where: { id: id, deleteAt: IsNull() } }); if (!user) { - return null; + throw new UserNotExists(`The user with id ${id} does not exists`); } return this.ormUserToDomainUser(user); } diff --git a/src/__test__/OAuth/Application/CreateGithubUser.test.ts b/src/__test__/OAuth/Application/CreateGithubUser.test.ts new file mode 100644 index 0000000..5988046 --- /dev/null +++ b/src/__test__/OAuth/Application/CreateGithubUser.test.ts @@ -0,0 +1,38 @@ +import { ConsoleLogger } from '../../../OAuth/Infraestructure/ConsoleLogger'; +import { FakeUserRepository } from '../Infraestructure/FakeUserRepository'; +import { UserRepository } from '../../../OAuth/Domain/UserRepository'; +import { ValidUser } from '../../../OAuth/Domain/ValidUser'; +import { User } from '../../../OAuth/Domain/User'; +import PROVIDER from '../../../constant/providers'; + +const USERS_DATA: ValidUser[] = [ + { + idFromProvider: '1dfgsdfg', + displayName: 'Blanca', + username: 'white', + image: 'https://github.com', + email: 'White@superrito.com', + provider: PROVIDER.GITHUB, + }, + { + idFromProvider: 'sdfsdf', + displayName: 'Rosa', + username: 'pink', + image: 'https://github.com', + email: 'Rosa@dsfgff.com', + provider: PROVIDER.GITHUB, + }, +]; +describe('[UNIT] - CreateGithubUser application service', () => { + let repository: UserRepository; + beforeAll(() => { + const logger = new ConsoleLogger(); + repository = new FakeUserRepository(logger); + }); + + it('It should call the repository to create a new user', () => { + USERS_DATA.forEach(async user => { + expect(await repository.createUser(new User(user))).toBe(true); + }); + }); +}); diff --git a/src/__test__/OAuth/Application/CreateSlackUser.test.ts b/src/__test__/OAuth/Application/CreateSlackUser.test.ts new file mode 100644 index 0000000..690750e --- /dev/null +++ b/src/__test__/OAuth/Application/CreateSlackUser.test.ts @@ -0,0 +1,38 @@ +import { ConsoleLogger } from '../../../OAuth/Infraestructure/ConsoleLogger'; +import { FakeUserRepository } from '../Infraestructure/FakeUserRepository'; +import { UserRepository } from '../../../OAuth/Domain/UserRepository'; +import { ValidUser } from '../../../OAuth/Domain/ValidUser'; +import { User } from '../../../OAuth/Domain/User'; +import PROVIDER from '../../../constant/providers'; + +const USERS_DATA: ValidUser[] = [ + { + idFromProvider: '1dfgsdfg', + displayName: 'Francisco', + username: 'frank', + image: 'https://slack.com', + email: 'Frank@superrito.com', + provider: PROVIDER.SLACK, + }, + { + idFromProvider: 'sdfsdf', + displayName: 'Taza', + username: 'polimero', + image: 'https://slack.com', + email: 'Taza@dsfgff.com', + provider: PROVIDER.SLACK, + }, +]; +describe('[UNIT] - CreateSlackUser application service', () => { + let repository: UserRepository; + beforeAll(() => { + const logger = new ConsoleLogger(); + repository = new FakeUserRepository(logger); + }); + + it('It should call the repository to create a new user', () => { + USERS_DATA.forEach(async user => { + expect(await repository.createUser(new User(user))).toBe(true); + }); + }); +}); diff --git a/src/__test__/OAuth/Application/DeleteGithubUser.test.ts b/src/__test__/OAuth/Application/DeleteGithubUser.test.ts new file mode 100644 index 0000000..8edda89 --- /dev/null +++ b/src/__test__/OAuth/Application/DeleteGithubUser.test.ts @@ -0,0 +1,17 @@ +import { ConsoleLogger } from '../../../OAuth/Infraestructure/ConsoleLogger'; +import { FakeUserRepository } from '../Infraestructure/FakeUserRepository'; +import { UserRepository } from '../../../OAuth/Domain/UserRepository'; + +const USER_ID = 'r3ag4g5sw5g'; + +describe('[UNIT] - DeleteUser application service tests', () => { + let repository: UserRepository; + beforeAll(() => { + const logger = new ConsoleLogger(); + repository = new FakeUserRepository(logger); + }); + + it('DeleteUser application service should call the respository', async () => { + expect(await repository.deleteUser(USER_ID)).toBe(true); + }); +}); diff --git a/src/__test__/OAuth/Application/DeleteSlackUser.test.ts b/src/__test__/OAuth/Application/DeleteSlackUser.test.ts new file mode 100644 index 0000000..0956c54 --- /dev/null +++ b/src/__test__/OAuth/Application/DeleteSlackUser.test.ts @@ -0,0 +1,17 @@ +import { ConsoleLogger } from '../../../OAuth/Infraestructure/ConsoleLogger'; +import { FakeUserRepository } from '../Infraestructure/FakeUserRepository'; +import { UserRepository } from '../../../OAuth/Domain/UserRepository'; + +const USER_ID = 'msmt453gff23f'; + +describe('[UNIT] - DeleteUser application service tests', () => { + let repository: UserRepository; + beforeAll(() => { + const logger = new ConsoleLogger(); + repository = new FakeUserRepository(logger); + }); + + it('DeleteUser application service should call the respository', async () => { + expect(await repository.deleteUser(USER_ID)).toBe(true); + }); +}); diff --git a/src/__test__/OAuth/Infraestructure/TypeORMUserRepository.test.ts b/src/__test__/OAuth/Infraestructure/TypeORMUserRepository.test.ts index 7dc0968..8b2054e 100644 --- a/src/__test__/OAuth/Infraestructure/TypeORMUserRepository.test.ts +++ b/src/__test__/OAuth/Infraestructure/TypeORMUserRepository.test.ts @@ -50,8 +50,7 @@ describe('[Integration] TypeORMUserRepository', () => { await repo.createUser(userToInsert); await repo.deleteUser(userToInsert.id); - const userFromDb: User = await repo.findUserByID(userToInsert.id); - expect(await userFromDb).toBe(null); + await expect(repo.findUserByID(userToInsert.id)).rejects.toThrow(/^UserNotExists.*/); }); }); });