Commit ee7b464d authored by ncastejon's avatar ncastejon
Browse files

Refactor model entity/dto. Add exception handling.

parent 549470dc
......@@ -73,9 +73,9 @@
}
},
"@nestjs/testing": {
"version": "5.3.8",
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-5.3.8.tgz",
"integrity": "sha512-4rqZWvAHhz8P/BCTXF6wXQqTM3goHNXbJJSl5r8MTqx1cipGOuljNN6UwctTFD6Orww4mjwvpXJIEnlXX+RTrw==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-5.4.0.tgz",
"integrity": "sha512-goZk+ACEUxu8MG2xRlqYPW8SkIX74Xn4G3ozUsdkapTBR60XG1DpNucuWSISePS+ytaUKaaaRKARgbXx417DIw==",
"dev": true,
"requires": {
"deprecate": "1.0.0",
......
......@@ -37,7 +37,7 @@
"typescript": "^3.0.1"
},
"devDependencies": {
"@nestjs/testing": "^5.1.0",
"@nestjs/testing": "^5.4.0",
"@types/amqplib": "^0.5.8",
"@types/express": "^4.16.0",
"@types/jest": "^23.3.1",
......
import { ApiModelProperty, ApiModelPropertyOptional } from '@nestjs/swagger';
export class Link {
@ApiModelPropertyOptional()
name?: string;
@ApiModelProperty()
url: string;
@ApiModelProperty()
organizationId?: number;
}
\ No newline at end of file
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';
import { IsString, IsOptional } from 'class-validator';
import { ApiModelProperty } from '@nestjs/swagger';
import { Organization } from '../organizations/organization.entity';
@Entity()
export class Link {
@Entity('link')
export class LinkEntity {
@ApiModelProperty()
@PrimaryGeneratedColumn()
id: number;
@ApiModelProperty()
@IsString()
@IsOptional()
@Column({ length: 100, nullable: true})
name: string;
@ApiModelProperty()
@IsString()
@Column({ length: 300})
url: string;
......@@ -25,7 +21,6 @@ export class Link {
@IsOptional()
organizationId: number;
@ApiModelProperty()
@ManyToOne(type => Organization, organization => organization.links, { onDelete: 'CASCADE'})
@JoinColumn({name: 'organizationId'})
organization: Organization;
......@@ -33,6 +28,6 @@ export class Link {
}
export interface LinksRO {
links: Link[];
links: LinkEntity[];
linksCount: number;
}
import { Repository } from 'typeorm';
import { LinkEntity } from './link.entity';
export class LinkRepository extends Repository<LinkEntity> {
}
\ No newline at end of file
import { Controller, Get, Body, Post, Param, Delete, Put, Query, Response, Request, Req, Res } from '@nestjs/common';
import { LinksService } from './links.service';
import { Link } from './link.entity';
import { LinkEntity } from './link.entity';
import { ApiUseTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { Link } from './link.dto';
@ApiUseTags('links')
@Controller('links')
......@@ -14,7 +15,7 @@ export class LinksController {
@ApiOperation({ title: 'Get all links' })
@ApiResponse({ status: 200, description: 'Return all links.' })
@Get()
async findAll(@Query() query, @Response() res): Promise<Link[]> {
async findAll(@Query() query, @Response() res): Promise<LinkEntity[]> {
const { links, linksCount } = await this.linksService.findAll(query);
res.append('Content-range', linksCount);
res.send(links);
......
import { Module } from '@nestjs/common';
import { LinksController } from './links.controller';
import { LinksService } from './links.service';
import { Link } from './link.entity';
import { LinkEntity } from './link.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [TypeOrmModule.forFeature([Link])],
imports: [TypeOrmModule.forFeature([LinkEntity])],
controllers: [LinksController],
providers: [LinksService],
})
......
import { Injectable, Logger } from '@nestjs/common';
import { Link, LinksRO } from './link.entity';
import { LinkEntity, LinksRO } from './link.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Link } from './link.dto';
import { LinkRepository } from './link.repository';
@Injectable()
export class LinksService {
constructor(
@InjectRepository(Link)
private linkRepository: Repository<Link>,
@InjectRepository(LinkEntity)
private linkRepository: LinkRepository,
) { }
async findAll(query): Promise<LinksRO> {
......@@ -67,6 +68,7 @@ export class LinksService {
async deleteOrphans() {
const orphanRO = await this.findAll({where: '"organizationId" IS NULL'});
orphanRO.links.forEach(orphan => {
this.linkRepository.delete(orphan);
});
......
import { Organization } from './organization.entity';
import { Link } from '../links/link.dto';
import { ApiModelProperty, ApiModelPropertyOptional } from '@nestjs/swagger';
import { IsString, IsOptional, IsArray, MaxLength, IsDefined } from 'class-validator';
export class OrganizationDTO {
@ApiModelProperty()
@IsString()
@MaxLength(200)
name: string;
@ApiModelProperty()
@IsString()
description: string;
@ApiModelPropertyOptional()
@IsOptional()
@IsString()
logo?: string;
@ApiModelPropertyOptional({type: [Link]})
@IsOptional()
@IsArray()
links?: [Link];
}
export interface OrganizationsRO {
organizations: Organization[];
organizationsCount: number;
}
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
import { IsString, IsOptional, IsArray } from 'class-validator';
import { ApiModelProperty, ApiModelPropertyOptional } from '@nestjs/swagger';
import { Link } from '../links/link.entity';
import { LinkEntity } from '../links/link.entity';
@Entity()
@Entity('organization')
export class Organization {
@ApiModelProperty()
@PrimaryGeneratedColumn()
id: number;
@ApiModelProperty()
@IsString()
@Column({ length: 200})
name: string;
@ApiModelProperty()
@IsString()
@Column('text')
description: string;
@ApiModelPropertyOptional()
@IsOptional()
@IsArray()
@OneToMany(type => Link, link => link.organization, {
@OneToMany(type => LinkEntity, link => link.organization, {
eager: true,
cascade: true,
})
links: Link[];
links: LinkEntity[];
@ApiModelPropertyOptional()
@IsOptional()
@IsString()
@Column ('text', {nullable: true})
logo: string;
}
export interface OrganizationsRO {
organizations: Organization[];
organizationsCount: number;
}
import { Repository } from 'typeorm';
import { Organization } from './organization.entity';
export class OrganizationRepository extends Repository<Organization> {
}
\ No newline at end of file
import { Test, TestingModule } from '@nestjs/testing';
import { OrganizationsController } from './organizations.controller';
describe('Organizations Controller', () => {
let module: TestingModule;
beforeAll(async () => {
module = await Test.createTestingModule({
controllers: [OrganizationsController],
}).compile();
});
it('should be defined', () => {
const controller: OrganizationsController = module.get<OrganizationsController>(OrganizationsController);
expect(controller).toBeDefined();
});
});
......@@ -2,6 +2,7 @@ import { Controller, Get, Body, Post, Param, Delete, Put, Query, Response, Reque
import { OrganizationsService } from './organizations.service';
import { Organization } from './organization.entity';
import { ApiUseTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { OrganizationDTO } from './organization.dto';
@ApiUseTags('organizations')
@Controller('organizations')
......@@ -14,7 +15,7 @@ export class OrganizationsController {
@ApiOperation({ title: 'Get all organizations' })
@ApiResponse({ status: 200, description: 'Return all organizations.' })
@Get()
async findAll(@Query() query, @Response() res): Promise<Organization[]> {
async findAll(@Query() query, @Response() res): Promise<OrganizationDTO[]> {
const { organizations, organizationsCount } = await this.organizationsService.findAll(query);
res.append('Content-range', organizationsCount);
res.send(organizations);
......@@ -22,6 +23,7 @@ export class OrganizationsController {
}
@ApiOperation({ title: 'Get one organization' })
@ApiResponse({ status: 200, description: 'Return one organization.' })
@Get(':id')
findOne(@Param('id') id: number) {
return this.organizationsService.findOne(id);
......@@ -34,23 +36,31 @@ export class OrganizationsController {
@ApiOperation({ title: 'Create one organization' })
@ApiResponse({ status: 201, description: 'The record has been successfully created.' })
@ApiResponse({ status: 400, description: 'The values of one or many fields are not correct.' })
@Post()
async create(@Body() organizationDTo: Organization) {
async create(@Body() organizationDTo: OrganizationDTO) {
return this.organizationsService.create(organizationDTo).then((organization) => {
return organization;
}).catch((err) => {
return err;
throw err;
});
}
@ApiOperation({ title: 'Update one organization' })
@ApiResponse({ status: 201, description: 'The record has been successfully updated.' })
@ApiResponse({ status: 400, description: 'No item exists with the given id.' })
@Put(':id')
async update(@Param('id') id: number, @Body() organization: Organization) {
return this.organizationsService.update(id, organization);
async update(@Param('id') id: number, @Body() organizationDTo: OrganizationDTO) {
return this.organizationsService.update(id, organizationDTo).then((organization) => {
return organization;
}).catch((err) => {
throw err;
});
}
@ApiOperation({ title: 'Delete one organization' })
@ApiResponse({ status: 400, description: 'No item exists with the given id.' })
@ApiResponse({ status: 204, description: 'The organization has been deleted successfully.' })
@Delete(':id')
delete(@Param('id') id: number) {
return this.organizationsService.delete(id);
......
......@@ -3,7 +3,6 @@ import { OrganizationsController } from './organizations.controller';
import { OrganizationsService } from './organizations.service';
import { Organization } from './organization.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Link } from '../links/link.entity';
import { LinksService } from 'links/links.service';
import { LinksModule } from 'links/links.module';
......
import { Test, TestingModule } from '@nestjs/testing';
import { OrganizationsService } from './organizations.service';
import { LinksService } from '../links/links.service';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Organization } from './organization.entity';
import { OrganizationRepository } from './organization.repository';
import { LinkEntity } from '../links/link.entity';
import { LinkRepository } from '../links/link.repository';
describe('OrganizationsService', () => {
let service: OrganizationsService;
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [OrganizationsService],
providers: [
OrganizationsService,
LinksService,
{
provide: getRepositoryToken(Organization),
useClass: OrganizationRepository,
},
{
provide: getRepositoryToken(LinkEntity),
useClass: LinkRepository,
},
],
}).compile();
service = module.get<OrganizationsService>(OrganizationsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
import { Injectable, Logger } from '@nestjs/common';
import { Organization, OrganizationsRO } from './organization.entity';
import { Injectable, Logger, BadRequestException, HttpStatus } from '@nestjs/common';
import { Organization } from './organization.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Link } from 'links/link.entity';
import { LinksService } from 'links/links.service';
import { LinksService } from '../links/links.service';
import { OrganizationsRO, OrganizationDTO } from './organization.dto';
import { OrganizationRepository } from './organization.repository';
@Injectable()
export class OrganizationsService {
constructor(
@InjectRepository(Organization)
private organizationRepository: Repository<Organization>,
private organizationRepository: OrganizationRepository,
private linksService: LinksService,
) { }
async findAll(query): Promise<OrganizationsRO> {
async findAll(query?): Promise<OrganizationsRO> {
const qb = await this.organizationRepository
.createQueryBuilder('organization')
.leftJoinAndSelect('organization.links', 'links');
......@@ -52,18 +52,22 @@ export class OrganizationsService {
return organization.links;
}
async create(organization: Organization) {
async create(organization: OrganizationDTO) {
const organizationCreated = await this.organizationRepository.save(organization);
return organizationCreated;
}
async update(id, organization: Organization) {
async update(id, organization: OrganizationDTO) {
const toUpdate = await this.organizationRepository.findOne(id);
const updated = Object.assign(toUpdate, organization);
if (! toUpdate) {
throw new BadRequestException('No item exists with the given id');
}
let updated = Object.assign(toUpdate, organization);
updated = await this.organizationRepository.save(updated);
this.linksService.deleteOrphans();
return await this.organizationRepository.save(updated);
return updated;
}
async delete(id) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment