diff --git a/sonar-project.properties b/sonar-project.properties index 7599bf4..2cd3f96 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -13,11 +13,11 @@ sonar.sources=. # Encoding of the source code. Default is default system encoding sonar.sourceEncoding=UTF-8 sonar.inclusions=**/*.ts,**/*.tsx,**/*.js,**/*.jsx,**/*.tf -sonar.exclusions=**/testHelpers/**/*,**/__tests__/**/*,**/mock*.ts,**/__mocks__/**/* +sonar.exclusions=**/testHelpers/**/*,**/__tests__/**/*,**/mock*.ts,**/__mocks__/**/*,**/*.spec.tsx,**/*.spec.ts, sonar.typescript.file.suffixes=.ts,.tsx # Coverage exclusions for specific files or folders # Excluding artisan-api from coverage temporarily sonar.coverage.exclusions=components/artisan-api/src/__service_tests__/**/*,components/artisan-api/src/testHelpers/**/*,components/artisan-api/scripts/**/*,components/artisan-api/**/handler.ts,components/artisan-api/src/resources/Profiles/dev-assets/index.ts sonar.tests=. -sonar.test.inclusions=**/*.test.tsx,**/*.test.ts,**/testHelpers/**/*,**/__tests__/**/*,**/mock*.ts \ No newline at end of file +sonar.test.inclusions=**/*.test.tsx,**/*.test.ts,**/testHelpers/**/*,**/__tests__/**/*,**/mock*.ts,**/*.test.tsx,**/*.spec.tsx,**/*.spec.ts, diff --git a/src/auth/dto/create-user-dto.spec.ts b/src/auth/dto/create-user-dto.spec.ts new file mode 100644 index 0000000..6ab449b --- /dev/null +++ b/src/auth/dto/create-user-dto.spec.ts @@ -0,0 +1,34 @@ +import { validate } from "class-validator"; +import { CreateUserDto } from "./create-user-dto"; +import { error } from "console"; + +describe('CreateUserDto', () => { + + it('should have the correct properties', async () => { + const createUserDto = new CreateUserDto(); + + createUserDto.email = 'test@test.com'; + createUserDto.password = 'Password123'; + createUserDto.fullName = 'User test'; + + const errors = await validate(createUserDto); + + expect(errors.length).toBe(0); + }); + + it('shold throw errors if password in not valid', async () => { + const createUserDto = new CreateUserDto(); + + createUserDto.email = 'test@test.com'; + createUserDto.password = 'password'; + createUserDto.fullName = 'User test'; + + const errors = await validate(createUserDto); + const passwordError = errors.find(error => error.property === 'password'); + + expect(passwordError).toBeDefined(); + expect(passwordError.constraints).toBeDefined(); + expect(passwordError.constraints.matches).toBe('The password must have a Uppercase, lowercase letter and a number'); + }); + +}); \ No newline at end of file diff --git a/src/auth/dto/login-user-dto.spec.ts b/src/auth/dto/login-user-dto.spec.ts new file mode 100644 index 0000000..bc964c1 --- /dev/null +++ b/src/auth/dto/login-user-dto.spec.ts @@ -0,0 +1,33 @@ +import { plainToClass } from "class-transformer" +import { LoginUserDto } from "./login-user-dto" +import { validate } from "class-validator"; + +describe('LoginUserDto', () => { + + it('should have the correct properties', async () => { + const loginUserDto = plainToClass(LoginUserDto, { + email: 'test@test.com', + password: 'Password123', + }); + + const errors = await validate(loginUserDto); + + expect(errors.length).toBe(0); + }); + + + it('shold throw error if password is not valid', async () => { + const loginUserDto = plainToClass(LoginUserDto, { + email: 'test@test.com', + password: 'invalidpassword', + }); + + const errors = validate(loginUserDto); + const passwordError = (await errors).find(error => error.property === 'password'); + + expect(passwordError).toBeDefined(); + expect(passwordError.constraints).toBeDefined(); + expect(passwordError.constraints.matches).toBe('The password must have a Uppercase, lowercase letter and a number'); + }) + +}) \ No newline at end of file diff --git a/src/auth/entities/user.entity.ts b/src/auth/entities/user.entity.ts index f35e0d8..e91a9cd 100644 --- a/src/auth/entities/user.entity.ts +++ b/src/auth/entities/user.entity.ts @@ -1,4 +1,4 @@ -import { Product } from "src/products/entities"; +import { Product } from "../../products/entities/product.entity"; import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; @Entity('users') diff --git a/src/common/dtos/pagination.dto.spec.ts b/src/common/dtos/pagination.dto.spec.ts new file mode 100644 index 0000000..e173ef3 --- /dev/null +++ b/src/common/dtos/pagination.dto.spec.ts @@ -0,0 +1,26 @@ +import { plainToClass } from "class-transformer" +import { PaginationDto } from "./pagination.dto" +import { validate } from "class-validator"; + +describe('PaginationDto', () => { + it('shold work with default parameters', async () => { + const paginationDto = plainToClass(PaginationDto, {}); + + const errors = await validate(paginationDto); + + expect(paginationDto).toBeDefined(); + expect(errors.length).toBe(0); + }); + + it('should validate limit as a positive number', async () => { + const paginationDto = plainToClass(PaginationDto, { limit: -1 }); + + const errors = await validate(paginationDto); + + const limitError = errors.find(error => error.property === 'limit'); + + expect(limitError).toBeDefined(); + expect(limitError.constraints.isPositive).toBeDefined(); + }); + +}); \ No newline at end of file diff --git a/src/common/dtos/pagination.dto.ts b/src/common/dtos/pagination.dto.ts index 40a1613..f9bbfee 100644 --- a/src/common/dtos/pagination.dto.ts +++ b/src/common/dtos/pagination.dto.ts @@ -1,17 +1,34 @@ +import { ApiProperty } from "@nestjs/swagger" import { Type } from "class-transformer" -import { IsOptional, IsPositive, Min, min } from "class-validator" +import { IsIn, IsOptional, IsPositive, Min } from "class-validator" export class PaginationDto { + @ApiProperty({ + default: 10, + description: 'How many rows do you need', + + }) @IsOptional() @IsPositive() @Type(() => Number) limit?: number + @ApiProperty({ + default: 0, + description: 'How many rows do you want to skip', + }) @IsOptional() - @IsPositive() @Min(0) @Type(() => Number) - offset?: number + offset?: number; + + @ApiProperty({ + default: '', + description: 'Filter results by gender', + }) + @IsOptional() + @IsIn(['men', 'women', 'kid']) + gender: 'men' | 'women' | 'kid'; } \ No newline at end of file diff --git a/src/products/dto/create-product.dto.ts b/src/products/dto/create-product.dto.ts index 28a97ad..a60e478 100644 --- a/src/products/dto/create-product.dto.ts +++ b/src/products/dto/create-product.dto.ts @@ -1,8 +1,15 @@ -import { IsArray, IsIn, IsInt, IsNumber, IsOptional, isPositive, IsPositive, IsString, MinLength } from "class-validator" +import { ApiProperty } from "@nestjs/swagger" +import { IsArray, IsIn, IsInt, IsNumber, IsOptional, IsPositive, IsString, MinLength } from "class-validator" export class CreateProductDto { + @ApiProperty({ + example: 'T-Shirt', + description: 'Product title (unique)', + nullable: false, + minLength: 1 + }) @IsString() @MinLength(1) title: string diff --git a/src/products/dto/update-product.dto.ts b/src/products/dto/update-product.dto.ts index e2d43fc..87b9d7f 100644 --- a/src/products/dto/update-product.dto.ts +++ b/src/products/dto/update-product.dto.ts @@ -1,4 +1,4 @@ -import { PartialType } from '@nestjs/mapped-types'; +import { PartialType } from '@nestjs/swagger'; import { CreateProductDto } from './create-product.dto'; export class UpdateProductDto extends PartialType(CreateProductDto) {} diff --git a/src/products/entities/product.entity.ts b/src/products/entities/product.entity.ts index c5b94b3..c22c335 100644 --- a/src/products/entities/product.entity.ts +++ b/src/products/entities/product.entity.ts @@ -1,6 +1,6 @@ import { BeforeInsert, Column, Entity, PrimaryGeneratedColumn, BeforeUpdate, OneToMany, ManyToOne } from "typeorm"; import { ProductImage } from "./product-image.entity"; -import { User } from "src/auth/entities/user.entity"; +import { User } from "../../auth/entities/user.entity"; import { ApiProperty } from "@nestjs/swagger"; @Entity({ name: 'products' })