Skip to content

Instantly share code, notes, and snippets.

@DenisMedeirosSDK
Created May 8, 2020 14:57
Show Gist options
  • Save DenisMedeirosSDK/a82d93b16d87b8d090457fb466e1bf69 to your computer and use it in GitHub Desktop.
Save DenisMedeirosSDK/a82d93b16d87b8d090457fb466e1bf69 to your computer and use it in GitHub Desktop.
import AppError from '@shared/errors/AppError';
import FakeHashProvider from '../providers/HashProvider/fakes/FakeHashProvider';
import FakeUsersRepository from '../repositories/Fakes/FakeUsersRepository';
import CreateUserService from './CreateUserService';
describe('CreateUser', () => {
it('should be able to create a new user', async () => {
const fakeUsersRepository = new FakeUsersRepository();
const fakeHashProvider = new FakeHashProvider();
const createUser = new CreateUserService(
fakeUsersRepository,
fakeHashProvider,
);
const user = await createUser.excute({
name: 'John Doe',
email: '[email protected]',
password: '123123',
});
expect(user).toHaveProperty('id');
});
it('should not be able to create a new user with same email from another', async () => {
const fakeUsersRepository = new FakeUsersRepository();
const fakeHashProvider = new FakeHashProvider();
const createUser = new CreateUserService(
fakeUsersRepository,
fakeHashProvider,
);
await createUser.excute({
name: 'John Doe',
email: '[email protected]',
password: '123123',
});
await expect(
createUser.excute({
name: 'John Doe',
email: '[email protected]',
password: '123123',
}),
).rejects.toBeInstanceOf(AppError);
});
});
import { inject, injectable } from 'tsyringe';
import AppError from '@shared/errors/AppError';
import IHashProvider from '../providers/HashProvider/models/IHashProvider';
import User from '../infra/typeorm/entities/User';
import IUsersRepository from '../repositories/IUsersRepository';
interface IRequest {
name: string;
email: string;
password: string;
}
@injectable()
class CreateUserService {
constructor(
@inject('UsersRepository')
private usersRepository: IUsersRepository,
@inject('HashProvider')
private hashProvider: IHashProvider,
) {}
public async excute({ name, email, password }: IRequest): Promise<User> {
const checkUserExists = await this.usersRepository.findByEmail(email);
if (checkUserExists) {
throw new AppError('Email addres already used');
}
const hashedPassword = await this.hashProvider.generateHash(password);
const user = await this.usersRepository.create({
name,
email,
password: hashedPassword,
});
return user;
}
}
export default CreateUserService;
import User from '../infra/typeorm/entities/User';
import ICreateUserDTO from '../dtos/ICreateUserDTO';
export default interface IUserRepository {
findById(id: string): Promise<User | undefined>;
findByEmail(email: string): Promise<User | undefined>;
create(data: ICreateUserDTO): Promise<User>;
save(user: User): Promise<User>;
}
import 'reflect-metadata';
import express, { Response, Request, NextFunction } from 'express';
import 'express-async-errors';
import cors from 'cors';
import uploadConfig from '@config/upload';
import AppError from '@shared/errors/AppError';
import routes from './routes';
import '@shared/infra/typeorm';
import '@shared/container';
const app = express();
app.use(cors());
app.use(express.json());
app.use('/files', express.static(uploadConfig.uploadsFolder));
app.use(routes);
app.use((err: Error, request: Request, response: Response, _: NextFunction) => {
if (err instanceof AppError) {
return response.status(err.statusCode).json({
status: 'error',
message: err.message,
});
}
console.log(err);
return response.status(500).json({
status: 'error',
message: 'Internal server error',
});
});
app.listen(3333, () => {
console.log('Server started on port 3333');
});
import {
Entity,
Column,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity('users')
class User {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
name: string;
@Column()
email: string;
@Column()
password: string;
@Column()
avatar: string;
@CreateDateColumn()
created_at: Date;
@UpdateDateColumn()
updated_at: Date;
}
export default User;
import { Response, Request } from 'express';
import { container } from 'tsyringe';
import CreateUserService from '@modules/users/services/CreateUserService';
export default class UsersController {
public async create(response: Response, request: Request): Promise<Response> {
const { name, email, password } = request.body;
const createUser = container.resolve(CreateUserService);
const user = await createUser.excute({
name,
email,
password,
});
delete user.password;
return response.json(user);
}
}
import { getRepository, Repository } from 'typeorm';
import IUsersRepository from '@modules/users/repositories/IUsersRepository';
import ICreateUserDTO from '@modules/users/dtos/ICreateUserDTO';
import User from '../entities/User';
class UsersRepository implements IUsersRepository {
private ormRepository: Repository<User>;
constructor() {
this.ormRepository = getRepository(User);
}
public async findById(id: string): Promise<User | undefined> {
const user = await this.ormRepository.findOne(id);
return user;
}
public async findByEmail(email: string): Promise<User | undefined> {
const user = await this.ormRepository.findOne({
where: { email },
});
return user;
}
public async create(userData: ICreateUserDTO): Promise<User> {
const appointment = this.ormRepository.create(userData);
await this.ormRepository.save(appointment);
return appointment;
}
public async save(user: User): Promise<User> {
return this.ormRepository.save(user);
}
}
export default UsersRepository;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment