Skip to content

Commit

Permalink
userEntity&test, userRepository, userService&test
Browse files Browse the repository at this point in the history
  • Loading branch information
ttkmw authored and junbeomlee committed May 24, 2019
1 parent 32da5a0 commit 8e7de8a
Show file tree
Hide file tree
Showing 19 changed files with 712 additions and 78 deletions.
217 changes: 151 additions & 66 deletions server/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@nestjs/core": "^6.0.0",
"@nestjs/platform-express": "^6.0.0",
"@nestjs/typeorm": "^6.1.1",
"class-validator": "^0.9.1",
"nestjs-config": "^1.4.0",
"reflect-metadata": "^0.1.12",
"rimraf": "^2.6.2",
Expand Down
2 changes: 2 additions & 0 deletions server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { ConfigModule } from 'nestjs-config';
import { GhostService } from './app/ghost/ghost.service';
import { GhostModule } from './port/module/ghost.module';
import * as path from 'path';
import {UserModule} from './port/module/user.module';

@Module({
imports: [
ConfigModule.load(path.resolve(__dirname, 'config', '**/!(*.d).{ts,js}')),
GhostModule,
UserModule,
],
controllers: [AppController],
providers: [AppService, GhostService],
Expand Down
208 changes: 208 additions & 0 deletions server/src/app/user/user.service.impl.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
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 {UserRepository} from '../../port/persistence/repository/user.repository.impl';

describe('UserServiceImpl', () => {
const address = 'testAddress';
const name = 'testName';
const mockRepository = mock(UserRepository);
let user: User;
let service: UserServiceImpl;

beforeEach(() => {
user = new User(address, name);
});

describe('dependency resolve', () => {
it('should be defined', async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UserServiceImpl,
{
provide: 'IUserRepository',
useValue: instance(mockRepository),
},
],
}).compile();
service = module.get<UserServiceImpl>(UserServiceImpl);

expect(service).toBeDefined();
});
});
describe('#get()', () => {
let id: number;

it('should return user', async () => {
id = 1;
when(mockRepository.findById(id)).thenReturn(new Promise((resolve) => {
resolve(user);
}));
service = new UserServiceImpl(instance(mockRepository));

expect(await service.get(id)).toBe(user);
});
it('should return undefined', async () => {
when(mockRepository.findById(null)).thenReturn(undefined);
service = new UserServiceImpl(instance(mockRepository));

expect(await service.get(null)).toBeUndefined();
});
});
describe('#create()', () => {
let userDto: UserDto;

it('should return user', async () => {
when(mockRepository.findByAddress(address)).thenReturn(undefined);
when(mockRepository.save(anything())).thenReturn(new Promise((resolve) => {
resolve(user);
}));
service = new UserServiceImpl(instance(mockRepository));
userDto = new UserDto(address, name);

expect(await service.create(userDto)).toBe(user);
});
it('should throw "address should be defined"', async () => {
when(mockRepository.findByAddress(address)).thenReturn(
new Promise((resolve => {resolve(user); }),
),
);
service = new UserServiceImpl(instance(mockRepository));
userDto = new UserDto();

await expect(service.create(userDto))
.rejects
.toThrowError('address should be defined');
});
it('should throw "name should be defined"', async () => {
when(mockRepository.findByAddress(address)).thenReturn(
new Promise((resolve => {resolve(user); }),
),
);
service = new UserServiceImpl(instance(mockRepository));
userDto = new UserDto(address);

await expect(service.create(userDto))
.rejects
.toThrowError('name should be defined');
});
it('should throw "address is already registered"', async () => {
when(mockRepository.findByAddress(address)).thenReturn(
new Promise((resolve => {resolve(user); }),
),
);
service = new UserServiceImpl(instance(mockRepository));
userDto = new UserDto(address, name);

await expect(service.create(userDto))
.rejects
.toThrowError('address is already registered');
});
});
describe('#delete()', () => {
let id: number;

it('should return undefined with valid id', async () => {
id = 1;
when(mockRepository.delete(id)).thenReturn(undefined);
service = new UserServiceImpl(instance(mockRepository));

expect(await service.delete(id)).toBeUndefined();
});
it('should return undefined with invalid id', async () => {
when(mockRepository.delete(null)).thenReturn(undefined);
service = new UserServiceImpl(instance(mockRepository));

expect(await service.delete(null)).toBeUndefined();
});
});
describe('#increasePoint()', () => {
const id = 1;
const amount = 10;

it('should return user with increased point', async () => {
when(mockRepository.findById(id)).thenReturn(new Promise((resolve => resolve(user))));
service = new UserServiceImpl(instance(mockRepository));

const userReturned = await service.increasePoint(id, amount);

expect(userReturned).toBeDefined();
expect(userReturned.getPoint()).toBe(amount);
});
it('should throw error "user with the id is not found"', async () => {
when(mockRepository.findById(id)).thenReturn(undefined);
service = new UserServiceImpl(instance(mockRepository));

await expect(service.increasePoint(id, amount))
.rejects
.toThrowError('user with the id is not found');
});
});
describe('#decreasePoint()', () => {
const id = 1;
const point = 100;
const validAmount = 10;
const invalidAmount = 1000;

it('should return user with increased level', async () => {
user = new User(address, name, point);
when(mockRepository.findById(id)).thenReturn(new Promise((resolve => resolve(user))));
service = new UserServiceImpl(instance(mockRepository));

const userReturned = await service.decreasePoint(id, validAmount);

expect(userReturned).toBeDefined();
expect(userReturned.getPoint()).toBe(point - validAmount);
});
it('should throw error "user with the id is not found"', async () => {
when(mockRepository.findById(id)).thenReturn(undefined);
service = new UserServiceImpl(instance(mockRepository));

await expect(service.decreasePoint(id, validAmount))
.rejects
.toThrowError('user with the id is not found');
});
it('should throw error "can not decrease point"', async () => {
user = new User(address, name, point);
when(mockRepository.findById(id)).thenReturn(new Promise((resolve => resolve(user))));
service = new UserServiceImpl(instance(mockRepository));

await expect(service.decreasePoint(id, invalidAmount))
.rejects
.toThrowError('can not decrease point');
});
});
describe('#increaseLevel()', () => {
const id = 1;
const validAmount = 10;
const invalidAmount = 1000;

it('should return user with increased level', async () => {
when(mockRepository.findById(id)).thenReturn(new Promise((resolve => resolve(user))));
service = new UserServiceImpl(instance(mockRepository));

const userReturned = await service.increaseLevel(id, validAmount);

expect(userReturned).toBeDefined();
expect(userReturned.getLevel()).toBe(validAmount);
});
it('should throw error "user with the id is not found"', async () => {
when(mockRepository.findById(id)).thenReturn(undefined);
service = new UserServiceImpl(instance(mockRepository));

await expect(service.increaseLevel(id, validAmount))
.rejects
.toThrowError('user with the id is not found');
});
it('should throw error "can not increase level"', async () => {
when(mockRepository.findById(id)).thenReturn(new Promise((resolve => resolve(user))));
service = new UserServiceImpl(instance(mockRepository));

await expect(service.increaseLevel(id, invalidAmount))
.rejects
.toThrowError('can not increase level');
});
});
});
73 changes: 73 additions & 0 deletions server/src/app/user/user.service.impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {Inject, Injectable} from '@nestjs/common';
import {UserService} from './user.service';
import {UserDto} from '../../domain/user/dto/user.dto';
import {User} from '../../domain/user/user.entity';
import {DeleteResult} from 'typeorm';
import {IUserRepository} from '../../port/persistence/repository/user.repository';

@Injectable()
export class UserServiceImpl implements UserService {

constructor(@Inject('IUserRepository') private userRepository: IUserRepository) {}

async get(id: number): Promise<User> {
return await this.userRepository.findById(id);
}
async create(userDto: UserDto): Promise<User> {
if (userDto.address === undefined) {
throw new Error('address should be defined');
}
if (userDto.name === undefined) {
throw new Error('name should be defined');
}
const userRetrieved = await this.userRepository.findByAddress(userDto.address);
if (userRetrieved !== undefined) {
throw new Error('address is already registered');
}

const user = new User(userDto.address, userDto.name);
return await this.userRepository.save(user);
}
async delete(id: number): Promise<DeleteResult> {
return await this.userRepository.delete(id);
}
async increasePoint(id: number, amount: number): Promise<User> {
let user: User;
user = await this.userRepository.findById(id);
if (user === undefined) {
throw new Error('user with the id is not found');
}

return user.increasePoint(amount);
}
async decreasePoint(id: number, amount: number): Promise<User> {
let user: User;
user = await this.userRepository.findById(id);
if (user === undefined) {
throw new Error('user with the id is not found');
}

let errors: Error[];
errors = user.canDecreasePoint(amount);
if (errors.length !== 0) {
throw new Error('can not decrease point');
}

return await user.decreasePoint(amount);
}
async increaseLevel(id: number, amount: number): Promise<User> {
let user: User;
user = await this.userRepository.findById(id);
if (user === undefined) {
throw new Error('user with the id is not found');
}

let errors: Error[];
errors = user.canIncreaseLevel(amount);
if ( errors.length !== 0) {
throw new Error('can not increase level');
}

return await user.increaseLevel(amount);
}
}
12 changes: 12 additions & 0 deletions server/src/app/user/user.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {User} from '../../domain/user/user.entity';
import {UserDto} from '../../domain/user/dto/user.dto';
import {DeleteResult} from 'typeorm';

export interface UserService {
get(id: number): Promise<User>;
create(userDto: UserDto): Promise<User>;
delete(id: number): Promise<DeleteResult>;
increaseLevel(id: number, amount: number): Promise<User>;
increasePoint(id: number, amount: number): Promise<User>;
decreasePoint(id: number, amount: number): Promise<User>;
}
2 changes: 1 addition & 1 deletion server/src/config/web3.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default {
url: 'localhost:8545',
type: 'socket',
type: 'http',
};
7 changes: 7 additions & 0 deletions server/src/domain/user/dto/user.dto.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { UserDto } from './user.dto';

describe('User.Dto', () => {
it('should be defined', () => {
expect(new UserDto()).toBeDefined();
});
});
14 changes: 14 additions & 0 deletions server/src/domain/user/dto/user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export class UserDto {
address: string;
name: string;
point: number;
level: number;

constructor(address?: string, name?: string, point?: number, level?: number);
constructor(address?: string, name?: string, point?: number, level?: number) {
this.address = address;
this.name = name;
this.point = point;
this.level = level;
}
}
1 change: 1 addition & 0 deletions server/src/domain/user/level.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const MAX_LEVEL = 100;
1 change: 1 addition & 0 deletions server/src/domain/user/point.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const MIN_POINT = 0;
Loading

0 comments on commit 8e7de8a

Please sign in to comment.