From 6f3586a47bbad18cf6d30a83de15f4d842c8229f Mon Sep 17 00:00:00 2001 From: junk-sound Date: Tue, 4 Jun 2019 00:49:15 +0900 Subject: [PATCH] feat: userController&test --- server/package-lock.json | 37 ++--- server/src/app/user/dto/signUp.dto.spec.ts | 7 + .../dto/{signUp.payload.ts => signUp.dto.ts} | 2 +- .../src/app/user/dto/signUp.payload.spec.ts | 7 - .../{domain => app}/user/dto/user.dto.spec.ts | 0 .../src/{domain => app}/user/dto/user.dto.ts | 0 server/src/app/user/user.service.impl.spec.ts | 9 +- server/src/app/user/user.service.impl.ts | 8 +- server/src/app/user/user.service.ts | 2 +- server/src/domain/user/validation.service.ts | 4 +- .../ethereum/web3/web3.bridge.service.ts | 1 - server/src/port/module/user.module.ts | 4 +- server/src/web/user/user.controller.spec.ts | 150 ++++++++++++++++++ server/src/web/user/user.controller.ts | 46 ++++++ 14 files changed, 240 insertions(+), 37 deletions(-) create mode 100644 server/src/app/user/dto/signUp.dto.spec.ts rename server/src/app/user/dto/{signUp.payload.ts => signUp.dto.ts} (89%) delete mode 100644 server/src/app/user/dto/signUp.payload.spec.ts rename server/src/{domain => app}/user/dto/user.dto.spec.ts (100%) rename server/src/{domain => app}/user/dto/user.dto.ts (100%) create mode 100644 server/src/web/user/user.controller.spec.ts create mode 100644 server/src/web/user/user.controller.ts diff --git a/server/package-lock.json b/server/package-lock.json index a1b8e72..53d6df4 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -41,9 +41,9 @@ } }, "@nestjs/common": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-6.2.0.tgz", - "integrity": "sha512-0svQuCrG6ofMYgHzk/GzJ+vpIkLq4vZmTeww1qLipggS40IjQ0+NzwEBOTr6TeHVDmsM2YDmIU1DJiaGy2o9Hw==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-6.2.4.tgz", + "integrity": "sha512-YZvJ6/S7yVQZK+9rupCzMCg4tpbc9DyVvLoTx0NBDqExTCUNcNEcCtn0AZrO/hLqbeYODnJwGE2NxkH1R/qw+w==", "requires": { "axios": "0.18.0", "cli-color": "1.4.0", @@ -51,9 +51,9 @@ } }, "@nestjs/core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-6.2.0.tgz", - "integrity": "sha512-K5Wje2unjStkA7AG5sTSD9trx2BEf8asL5xOFT4DwG+ICB04JLebTwqwbQNi3RNZ3buL/pXNXIOOleOgqK7fGw==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-6.2.4.tgz", + "integrity": "sha512-aYKi3QGKmpxF6w32STAcobIqOHFqSUXrU8nF+Y9dOlStRkXFBTuVchsoJk94sY+3y4SJAlHH4Q/8R4yFaixrug==", "requires": { "@nuxtjs/opencollective": "0.2.1", "fast-safe-stringify": "2.0.6", @@ -75,9 +75,9 @@ } }, "@nestjs/testing": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-6.2.0.tgz", - "integrity": "sha512-sAdXmZugvhYyp6tze5FdcH6tuIoDI0R8l7nI+PFDXuwxUSvfm8eHOloRbmYRD8ULGfY6OEvmO5uzoz/73IcMMw==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-6.2.4.tgz", + "integrity": "sha512-l5uxeNz+CksHaVcHxSlpo0vyJxvZP7BM1vS6BKuqtn/lNlIITAkdWmCVfBldN8Okayj3B2yhc04Zq6imU3aX9w==", "dev": true, "requires": { "optional": "0.1.4" @@ -1869,9 +1869,9 @@ } }, "consola": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.6.2.tgz", - "integrity": "sha512-GNJhwvF4bJ8eiAlyB8r4WNM8kBqkl+y4DvMehMbyywoJiv37N0M6/xrKqrrZw/5maZA+UagQV8UZ+XBeuGMzUg==" + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.7.1.tgz", + "integrity": "sha512-u7JYs+HnMbZPD2cEuS1XHsLeqtazA0kd5lAk8r8DnnGdgNhOdb7DSubJ+QLdQkbtpmmxgp7gs8Ug44sCyY4FCQ==" }, "content-disposition": { "version": "0.5.2", @@ -8842,23 +8842,24 @@ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" }, "tslint": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", - "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.17.0.tgz", + "integrity": "sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w==", "dev": true, "requires": { - "babel-code-frame": "^6.22.0", + "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", "chalk": "^2.3.0", "commander": "^2.12.1", "diff": "^3.2.0", "glob": "^7.1.1", - "js-yaml": "^3.7.0", + "js-yaml": "^3.13.1", "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", "resolve": "^1.3.2", "semver": "^5.3.0", "tslib": "^1.8.0", - "tsutils": "^2.27.2" + "tsutils": "^2.29.0" } }, "tsutils": { diff --git a/server/src/app/user/dto/signUp.dto.spec.ts b/server/src/app/user/dto/signUp.dto.spec.ts new file mode 100644 index 0000000..6d1bddf --- /dev/null +++ b/server/src/app/user/dto/signUp.dto.spec.ts @@ -0,0 +1,7 @@ +import {SignUpDto} from './signUp.dto'; + +describe('SignUpPayload', () => { + it('should be defined', () => { + expect(new SignUpDto({address: 'address', message: 'message'}, 'signature')).toBeDefined(); + }); +}); diff --git a/server/src/app/user/dto/signUp.payload.ts b/server/src/app/user/dto/signUp.dto.ts similarity index 89% rename from server/src/app/user/dto/signUp.payload.ts rename to server/src/app/user/dto/signUp.dto.ts index 87198fd..92fb14a 100644 --- a/server/src/app/user/dto/signUp.payload.ts +++ b/server/src/app/user/dto/signUp.dto.ts @@ -1,4 +1,4 @@ -export class SignUpPayload { +export class SignUpDto { data: { address: string, diff --git a/server/src/app/user/dto/signUp.payload.spec.ts b/server/src/app/user/dto/signUp.payload.spec.ts deleted file mode 100644 index d15b09c..0000000 --- a/server/src/app/user/dto/signUp.payload.spec.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { SignUpPayload } from './signUp.payload'; - -describe('SignUpPayload', () => { - it('should be defined', () => { - expect(new SignUpPayload({address: 'address', message: 'message'}, 'signature')).toBeDefined(); - }); -}); diff --git a/server/src/domain/user/dto/user.dto.spec.ts b/server/src/app/user/dto/user.dto.spec.ts similarity index 100% rename from server/src/domain/user/dto/user.dto.spec.ts rename to server/src/app/user/dto/user.dto.spec.ts diff --git a/server/src/domain/user/dto/user.dto.ts b/server/src/app/user/dto/user.dto.ts similarity index 100% rename from server/src/domain/user/dto/user.dto.ts rename to server/src/app/user/dto/user.dto.ts diff --git a/server/src/app/user/user.service.impl.spec.ts b/server/src/app/user/user.service.impl.spec.ts index 1619a85..f896181 100644 --- a/server/src/app/user/user.service.impl.spec.ts +++ b/server/src/app/user/user.service.impl.spec.ts @@ -2,8 +2,9 @@ import {UserServiceImpl} from './user.service.impl'; import {anything, instance, mock, when} from 'ts-mockito'; import {TestingModule, Test} from '@nestjs/testing'; import {User} from '../../domain/user/user.entity'; -import {UserDto} from '../../domain/user/dto/user.dto'; +import {UserDto} from './dto/user.dto'; import {UserRepository} from '../../port/persistence/repository/user.repository.impl'; +import {BadRequestException} from '@nestjs/common'; describe('UserServiceImpl', () => { const address = 'testAddress'; @@ -44,11 +45,13 @@ describe('UserServiceImpl', () => { expect(await service.get(id)).toBe(user); }); - it('should return undefined', async () => { + it('should throw BadRequestException', async () => { when(mockRepository.findById(null)).thenReturn(undefined); service = new UserServiceImpl(instance(mockRepository)); - expect(await service.get(null)).toBeUndefined(); + await expect(service.get(null)) + .rejects + .toThrowError(BadRequestException); }); }); describe('#create()', () => { diff --git a/server/src/app/user/user.service.impl.ts b/server/src/app/user/user.service.impl.ts index 9ef8e42..8f8f1c1 100644 --- a/server/src/app/user/user.service.impl.ts +++ b/server/src/app/user/user.service.impl.ts @@ -1,6 +1,6 @@ -import {Inject, Injectable} from '@nestjs/common'; +import {BadRequestException, Inject, Injectable} from '@nestjs/common'; import {UserService} from './user.service'; -import {UserDto} from '../../domain/user/dto/user.dto'; +import {UserDto} from './dto/user.dto'; import {User} from '../../domain/user/user.entity'; import {DeleteResult} from 'typeorm'; import {IUserRepository} from '../../port/persistence/repository/user.repository'; @@ -11,6 +11,10 @@ export class UserServiceImpl implements UserService { constructor(@Inject('IUserRepository') private userRepository: IUserRepository) {} async get(id: number): Promise { + const user = await this.userRepository.findById(id); + if (user === undefined) { + throw new BadRequestException('no user with the id'); + } return await this.userRepository.findById(id); } async create(userDto: UserDto): Promise { diff --git a/server/src/app/user/user.service.ts b/server/src/app/user/user.service.ts index 877c02e..9a37769 100644 --- a/server/src/app/user/user.service.ts +++ b/server/src/app/user/user.service.ts @@ -1,5 +1,5 @@ import {User} from '../../domain/user/user.entity'; -import {UserDto} from '../../domain/user/dto/user.dto'; +import {UserDto} from './dto/user.dto'; import {DeleteResult} from 'typeorm'; export interface UserService { diff --git a/server/src/domain/user/validation.service.ts b/server/src/domain/user/validation.service.ts index 20cc5b3..c2aaea6 100644 --- a/server/src/domain/user/validation.service.ts +++ b/server/src/domain/user/validation.service.ts @@ -1,5 +1,3 @@ -import {Data} from './data'; - export interface ValidationService { - verify(data: Data, signature: string): boolean; + verify(data: {address: string, message: string}, signature: string): boolean; } diff --git a/server/src/port/adapter/service/blockchain/ethereum/web3/web3.bridge.service.ts b/server/src/port/adapter/service/blockchain/ethereum/web3/web3.bridge.service.ts index 58b38e0..fad5255 100644 --- a/server/src/port/adapter/service/blockchain/ethereum/web3/web3.bridge.service.ts +++ b/server/src/port/adapter/service/blockchain/ethereum/web3/web3.bridge.service.ts @@ -1,7 +1,6 @@ import {BridgeService} from '../../../../../../domain/user/bridge.service'; import {Inject, Injectable} from '@nestjs/common'; import Web3 from 'web3'; -import {SignUpPayload} from '../../../../../../app/user/dto/signUp.payload'; @Injectable() export class Web3BridgeService implements BridgeService { diff --git a/server/src/port/module/user.module.ts b/server/src/port/module/user.module.ts index e77fd49..59ef166 100644 --- a/server/src/port/module/user.module.ts +++ b/server/src/port/module/user.module.ts @@ -1,10 +1,12 @@ import { Module } from '@nestjs/common'; import {UserServiceImpl} from '../../app/user/user.service.impl'; import {UserRepository} from '../persistence/repository/user.repository.impl'; +import {UserController} from '../../web/user/user.controller'; @Module({ + controllers: [UserController], providers: [ - UserServiceImpl, + {provide: 'UserService', useClass: UserServiceImpl}, {provide: 'IUserRepository', useClass: UserRepository}, ], }) diff --git a/server/src/web/user/user.controller.spec.ts b/server/src/web/user/user.controller.spec.ts new file mode 100644 index 0000000..180adea --- /dev/null +++ b/server/src/web/user/user.controller.spec.ts @@ -0,0 +1,150 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { UserController } from './user.controller'; +import {instance, mock, when} from 'ts-mockito'; +import {UserService} from '../../app/user/user.service'; +import {UserServiceImpl} from '../../app/user/user.service.impl'; +import {User} from '../../domain/user/user.entity'; +import {UserDto} from '../../app/user/dto/user.dto'; +import {BadRequestException} from '@nestjs/common'; + +describe('User Controller', () => { + const mockUserService = mock(UserServiceImpl); + const address = 'testAddress'; + const name = 'name'; + let user: User; + let controller: UserController; + + beforeEach(() => { + user = new User(address, name); + }); + + describe('dependency resolve', () => { + it('should be defined', async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [ + UserController, + ], + providers: [ + { + provide: 'UserService', + useValue: instance(mockUserService), + }, + ], + }).compile(); + + controller = module.get(UserController); + expect(controller).toBeDefined(); + }); + }); + describe('#get()', () => { + const id = 1; + + it('should return user', async () => { + when(mockUserService.get(id)).thenReturn(new Promise((resolve) => { + resolve(user); + })); + controller = new UserController(instance(mockUserService)); + + expect(await controller.get(id)).toBe(user); + + }); + it('should return undefined', async () => { + when(mockUserService.get(id)).thenThrow(new BadRequestException('no user with the id')); + controller = new UserController(instance(mockUserService)); + + await expect(controller.get(id)) + .rejects + .toThrowError(BadRequestException); + }); + }); + describe('#create()', () => { + let userDto: UserDto; + + it('should return user', async () => { + userDto = new UserDto(address, name); + when(mockUserService.create(userDto)).thenReturn(new Promise((resolve => { + resolve(user); + }))); + controller = new UserController(instance(mockUserService)); + + expect(await controller.create(userDto)).toBe(user); + + }); + it('should return undefined', async () => { + userDto = new UserDto(); + when(mockUserService.create(userDto)).thenThrow(new Error('some errors')); + controller = new UserController(instance(mockUserService)); + + await expect(controller.create(userDto)) + .rejects + .toThrowError('some errors'); + }); + }); + describe('#delete()', () => { + const id = 1; + + it('should return undefined', async () => { + when(mockUserService.delete(id)).thenReturn(new Promise((resolve => resolve(undefined)))); + controller = new UserController(instance(mockUserService)); + + expect(await controller.delete(id)).toBe(undefined); + }); + }); + describe('#increaseLevel()', () => { + const id = 1; + const amount = 10; + + it('should return user', async () => { + when(mockUserService.increaseLevel(id, amount)).thenReturn(new Promise((resolve => resolve(user)))); + controller = new UserController(instance(mockUserService)); + + expect(await controller.increaseLevel(id, {amount})).toBe(user); + }); + it('should throw error', async () => { + when(mockUserService.increaseLevel(id, amount)).thenThrow(new Error('some errors')); + controller = new UserController(instance(mockUserService)); + + await expect(controller.increaseLevel(id, {amount})) + .rejects + .toThrowError('some errors'); + }); + }); + describe('#increasePoint()', () => { + const id = 1; + const amount = 10; + + it('should return user', async () => { + when(mockUserService.increasePoint(id, amount)).thenReturn(new Promise((resolve => resolve(user)))); + controller = new UserController(instance(mockUserService)); + + expect(await controller.increasePoint(id, {amount})).toBe(user); + }); + it('should throw error', async () => { + when(mockUserService.increasePoint(id, amount)).thenThrow(new Error('some errors')); + controller = new UserController(instance(mockUserService)); + + await expect(controller.increasePoint(id, {amount})) + .rejects + .toThrowError('some errors'); + }); + }); + describe('#decreasePoint()', () => { + const id = 1; + const amount = 10; + + it('should return user', async () => { + when(mockUserService.decreasePoint(id, amount)).thenReturn(new Promise((resolve => resolve(user)))); + controller = new UserController(instance(mockUserService)); + + expect(await controller.decreasePoint(id, {amount})).toBe(user); + }); + it('should throw error', async () => { + when(mockUserService.decreasePoint(id, amount)).thenThrow(new Error('some errors')); + controller = new UserController(instance(mockUserService)); + + await expect(controller.decreasePoint(id, {amount})) + .rejects + .toThrowError('some errors'); + }); + }); +}); diff --git a/server/src/web/user/user.controller.ts b/server/src/web/user/user.controller.ts new file mode 100644 index 0000000..aa49ed7 --- /dev/null +++ b/server/src/web/user/user.controller.ts @@ -0,0 +1,46 @@ +import { + Body, + Controller, + Delete, + Get, + Inject, + Injectable, + Param, + Post, Put, + Query, +} from '@nestjs/common'; +import {User} from '../../domain/user/user.entity'; +import {UserDto} from '../../app/user/dto/user.dto'; +import {DeleteResult} from 'typeorm'; +import {UserService} from '../../app/user/user.service'; + +@Injectable() +@Controller('users') +export class UserController { + constructor(@Inject('UserService') private service: UserService) {} + + @Get(':id') + async get(@Param('id') id: number): Promise { + return await this.service.get(id); + } + @Post() + async create(@Body() userDto: UserDto): Promise { + return await this.service.create(userDto); + } + @Delete(':id') + async delete(@Param('id') id: number): Promise { + return await this.service.delete(id); + } + @Put(':id/increase-level') + async increaseLevel(@Param('id') id: number, @Query() query): Promise { + return await this.service.increaseLevel(id, query.amount); + } + @Put(':id/increase-point') + async increasePoint(@Param('id') id: number, @Query() query): Promise { + return await this.service.increasePoint(id, query.amount); + } + @Put(':id/decrease-point') + async decreasePoint(@Param('id') id: number, @Query() query): Promise { + return await this.service.decreasePoint(id, query.amount); + } +}