From e0c321367af9db9f92feb3c71770feaece633a9e Mon Sep 17 00:00:00 2001 From: Matheus Monteiro Date: Fri, 17 Jan 2025 14:20:46 -0300 Subject: [PATCH 01/10] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3da7b4f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 EPS/MDS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From ff9a03c96ab7094a94947ce90f25f620fa0d97da Mon Sep 17 00:00:00 2001 From: Pabloo8 Date: Wed, 22 Jan 2025 15:15:25 -0300 Subject: [PATCH 02/10] feat: create entity and src "book" --- src/books/books.controller.ts | 26 +++++++++++ src/books/books.module.ts | 13 ++++++ src/books/books.service.ts | 70 ++++++++++++++++++++++++++++ src/books/dtos/borrowBooks.dto.ts | 8 ++++ src/books/dtos/searchBooks.dto.ts | 25 ++++++++++ src/database/entities/book.entity.ts | 50 ++++++++++++++++++++ 6 files changed, 192 insertions(+) create mode 100644 src/books/books.controller.ts create mode 100644 src/books/books.module.ts create mode 100644 src/books/books.service.ts create mode 100644 src/books/dtos/borrowBooks.dto.ts create mode 100644 src/books/dtos/searchBooks.dto.ts create mode 100644 src/database/entities/book.entity.ts diff --git a/src/books/books.controller.ts b/src/books/books.controller.ts new file mode 100644 index 0000000..ec365cb --- /dev/null +++ b/src/books/books.controller.ts @@ -0,0 +1,26 @@ +import { Controller, Get, Param, Query } from '@nestjs/common'; +import { BooksService } from './books.service'; +import { SearchBooksDto } from './dtos/searchBooks.dto'; +import { BorrowBooksDto } from './dtos/borrowBooks.dto'; + +@Controller('books') +export class BooksController { + constructor(private readonly booksService: BooksService) {} + + @Get('search') + async searchBooks(@Query() searchParams: SearchBooksDto) { + return this.booksService.searchBooks(searchParams); + } + + @Get(':id') + async getBookById(@Param('id') id: string): Promise { + try { + // Chama o serviço para buscar os detalhes do livro + return await this.booksService.getBookById(id); + } catch (error) { + // Se necessário, você pode personalizar o tratamento de erros aqui + throw error; + + } +} +} \ No newline at end of file diff --git a/src/books/books.module.ts b/src/books/books.module.ts new file mode 100644 index 0000000..9c1b8c3 --- /dev/null +++ b/src/books/books.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { BooksController } from './books.controller'; +import { BooksService } from './books.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Book } from 'src/database/entities/book.entity'; + + +@Module({ + imports: [TypeOrmModule.forFeature([Book])], + controllers: [BooksController], + providers: [BooksService], +}) +export class BooksModule {} diff --git a/src/books/books.service.ts b/src/books/books.service.ts new file mode 100644 index 0000000..7e2b4a5 --- /dev/null +++ b/src/books/books.service.ts @@ -0,0 +1,70 @@ +import { Injectable, NotFoundException } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { SearchBooksDto } from './dtos/searchBooks.dto'; +import { Book } from 'src/database/entities/book.entity'; + +@Injectable() +export class BooksService { + constructor( + @InjectRepository(Book) + private booksRepository: Repository, + ) { } + + async searchBooks(searchParams: SearchBooksDto) { + let { title, author, theme, page, limit } = searchParams; + + page = parseInt(page as any, 10) || 1; + limit = parseInt(limit as any, 10) || 10; + const offset = (page - 1) * limit; + + const filters: any = {}; + if (title) filters.title = title; + if (author) filters.author = author; + if (theme) filters.theme = theme; + + try { + const [books, totalBooks] = await this.booksRepository.findAndCount({ + where: filters, + skip: offset, + take: limit, + order:{ + averageRating : 'DESC', + title: 'ASC', + } + }); + + const totalPages = Math.ceil(totalBooks / limit); + + if (books.length === 0) { + return { + message: 'Nenhum livro encontrado para a pesquisa realizada. Tente outros termos.', + totalPages: 0, + currentPage: page, + results: [], + }; + } + + return { + message: 'Livros encontrados com sucesso!', + totalPages, + currentPage: page, + results: books, + }; + } catch (error) { + console.error(error); + throw new Error('Erro ao realizar a busca no banco de dados'); + } + } + + async getBookById(id: string): Promise { + const book = await this.booksRepository.findOneBy({ id }) + if (!book) { + throw new NotFoundException(`O livro de ID ${id} não foi encontrado.`); + } + return book; + + + } +} + diff --git a/src/books/dtos/borrowBooks.dto.ts b/src/books/dtos/borrowBooks.dto.ts new file mode 100644 index 0000000..0750457 --- /dev/null +++ b/src/books/dtos/borrowBooks.dto.ts @@ -0,0 +1,8 @@ +import { IsString, IsOptional, IsNumber, IsNotEmpty } from 'class-validator'; + +export class BorrowBooksDto { + @IsString() + @IsNotEmpty() + id: string; + +} diff --git a/src/books/dtos/searchBooks.dto.ts b/src/books/dtos/searchBooks.dto.ts new file mode 100644 index 0000000..cb41129 --- /dev/null +++ b/src/books/dtos/searchBooks.dto.ts @@ -0,0 +1,25 @@ +import { IsOptional, IsString, IsInt, Min } from 'class-validator'; + +export class SearchBooksDto { + @IsOptional() + @IsString() + title?: string; + + @IsOptional() + @IsString() + author?: string; + + @IsOptional() + @IsString() + theme?: string; + + @IsOptional() + @IsInt() + @Min(1) + page: number = 1; + + @IsOptional() + @IsInt() + @Min(1) + limit: number = 20; +} diff --git a/src/database/entities/book.entity.ts b/src/database/entities/book.entity.ts new file mode 100644 index 0000000..9642742 --- /dev/null +++ b/src/database/entities/book.entity.ts @@ -0,0 +1,50 @@ +import { HttpStatus } from '@nestjs/common'; +import { + Column, + CreateDateColumn, + Entity, + PrimaryGeneratedColumn, + UpdateDateColumn, +} from 'typeorm'; + +export enum Status { + AVAILABLE = "available", + NOTAVAILABLE = "notAvailable", +} + +@Entity() +export class Book { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column() + title: string; + + @Column() + coverImage: string; + + @Column() + author: string; + + @Column() + theme: string; + + @Column() + description: string; + + @Column({ type: 'decimal', precision: 2, scale: 1, default: 0 }) + averageRating: number; // Média de avaliação dos usuários (0.0 a 5.0) + + @Column({ nullable: true }) + coverUrl: string; // URL da capa do livro + + @Column({ nullable: true }) + borrowedBy: string; + + @Column({ + type: "enum", + enum: Status, + default: Status.AVAILABLE, + }) + role: Status; +} From 175c6eb16a3c71d80c36eedf492a112acc273425 Mon Sep 17 00:00:00 2001 From: Joaovitor045 Date: Fri, 31 Jan 2025 11:31:57 -0300 Subject: [PATCH 03/10] feat:back-end of us05 --- src/app.module.ts | 2 + src/books/books.controller.ts | 18 +++--- src/books/books.mock.ts | 20 ++++++ src/books/books.service.ts | 86 ++++++++------------------ src/books/dtos/borrowBooks.dto.ts | 12 ++-- src/books/dtos/updateBookStatus.dto.ts | 4 ++ src/main.ts | 2 +- 7 files changed, 72 insertions(+), 72 deletions(-) create mode 100644 src/books/books.mock.ts create mode 100644 src/books/dtos/updateBookStatus.dto.ts diff --git a/src/app.module.ts b/src/app.module.ts index c0f9ca1..10efb6a 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,6 +4,7 @@ import { UsersModule } from './users/users.module'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { AuthModule } from './auth/auth.module'; import typeormConfig from './database/config'; +import { BooksModule } from './books/books.module'; @Module({ imports: [ @@ -18,6 +19,7 @@ import typeormConfig from './database/config'; }), UsersModule, AuthModule, + BooksModule, ], controllers: [], providers: [], diff --git a/src/books/books.controller.ts b/src/books/books.controller.ts index ec365cb..6405798 100644 --- a/src/books/books.controller.ts +++ b/src/books/books.controller.ts @@ -1,7 +1,8 @@ -import { Controller, Get, Param, Query } from '@nestjs/common'; +import { Controller, Get, Param, Query, Put, Body } from '@nestjs/common'; import { BooksService } from './books.service'; import { SearchBooksDto } from './dtos/searchBooks.dto'; import { BorrowBooksDto } from './dtos/borrowBooks.dto'; +import { UpdateBookStatusDto } from './dtos/updateBookStatus.dto'; // Certifique-se de importar esse DTO @Controller('books') export class BooksController { @@ -11,16 +12,19 @@ export class BooksController { async searchBooks(@Query() searchParams: SearchBooksDto) { return this.booksService.searchBooks(searchParams); } - + @Get(':id') async getBookById(@Param('id') id: string): Promise { try { - // Chama o serviço para buscar os detalhes do livro return await this.booksService.getBookById(id); } catch (error) { - // Se necessário, você pode personalizar o tratamento de erros aqui - throw error; - + throw error; + } + } + + + @Put(':id/status') + async updateBookStatus(@Param('id') id: string, @Body() updateBookStatusDto: UpdateBookStatusDto) { + return this.booksService.updateBookStatus(id, updateBookStatusDto); } } -} \ No newline at end of file diff --git a/src/books/books.mock.ts b/src/books/books.mock.ts new file mode 100644 index 0000000..3b1b4f0 --- /dev/null +++ b/src/books/books.mock.ts @@ -0,0 +1,20 @@ +export const booksMock = [ + { + id: 1, + title: "Curupira, O guardião da floresta", + author: "Saci-Pererê", + rating: 4.5, + description: "Descrição do livro", + coverImage: "/logo.png", + status: "Available" + }, + { + id: 2, + title: "O boto cor de rosa", + author: "Mula-sem-cabeça", + rating: 2.5, + description: "Descrição do livro", + coverImage: "/logo.png", + status: "Available" + } +]; diff --git a/src/books/books.service.ts b/src/books/books.service.ts index 7e2b4a5..55c9608 100644 --- a/src/books/books.service.ts +++ b/src/books/books.service.ts @@ -1,70 +1,36 @@ import { Injectable, NotFoundException } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; +import { BorrowBooksDto } from './dtos/borrowBooks.dto'; import { SearchBooksDto } from './dtos/searchBooks.dto'; -import { Book } from 'src/database/entities/book.entity'; +import { UpdateBookStatusDto } from './dtos/updateBookStatus.dto'; +import { booksMock } from './books.mock'; // 🔥 Importando o mock @Injectable() export class BooksService { - constructor( - @InjectRepository(Book) - private booksRepository: Repository, - ) { } - - async searchBooks(searchParams: SearchBooksDto) { - let { title, author, theme, page, limit } = searchParams; - - page = parseInt(page as any, 10) || 1; - limit = parseInt(limit as any, 10) || 10; - const offset = (page - 1) * limit; - - const filters: any = {}; - if (title) filters.title = title; - if (author) filters.author = author; - if (theme) filters.theme = theme; - - try { - const [books, totalBooks] = await this.booksRepository.findAndCount({ - where: filters, - skip: offset, - take: limit, - order:{ - averageRating : 'DESC', - title: 'ASC', - } - }); - - const totalPages = Math.ceil(totalBooks / limit); - - if (books.length === 0) { - return { - message: 'Nenhum livro encontrado para a pesquisa realizada. Tente outros termos.', - totalPages: 0, - currentPage: page, - results: [], - }; - } - - return { - message: 'Livros encontrados com sucesso!', - totalPages, - currentPage: page, - results: books, - }; - } catch (error) { - console.error(error); - throw new Error('Erro ao realizar a busca no banco de dados'); - } + private books = booksMock; // Usando o mock + + async searchBooks(searchParams: SearchBooksDto) { + return this.books.filter(book => + (searchParams.title ? book.title.includes(searchParams.title) : true) && + (searchParams.author ? book.author.includes(searchParams.author) : true) + ); + } + + async getBookById(id: string): Promise { + const book = this.books.find(book => book.id === Number(id)); + if (!book) { + throw new NotFoundException("Livro não encontrado"); } + return book; + } - async getBookById(id: string): Promise { - const book = await this.booksRepository.findOneBy({ id }) - if (!book) { - throw new NotFoundException(`O livro de ID ${id} não foi encontrado.`); - } - return book; + async updateBookStatus(id: string, updateBookStatusDto: UpdateBookStatusDto): Promise { + const bookIndex = this.books.findIndex((book) => book.id === Number(id)); - + if (bookIndex === -1) { + throw new NotFoundException('Livro não encontrado'); } -} + this.books[bookIndex].status = updateBookStatusDto.status; + return this.books[bookIndex]; + } +} diff --git a/src/books/dtos/borrowBooks.dto.ts b/src/books/dtos/borrowBooks.dto.ts index 0750457..f9dde9e 100644 --- a/src/books/dtos/borrowBooks.dto.ts +++ b/src/books/dtos/borrowBooks.dto.ts @@ -1,8 +1,12 @@ import { IsString, IsOptional, IsNumber, IsNotEmpty } from 'class-validator'; export class BorrowBooksDto { - @IsString() - @IsNotEmpty() - id: string; - + id: number; + title: string; + author: string; + rating: number; + description: string; + coverImage: string; + status: string; } + diff --git a/src/books/dtos/updateBookStatus.dto.ts b/src/books/dtos/updateBookStatus.dto.ts new file mode 100644 index 0000000..6b2664c --- /dev/null +++ b/src/books/dtos/updateBookStatus.dto.ts @@ -0,0 +1,4 @@ +export class UpdateBookStatusDto { + status: string; + } + \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 3207518..f07638b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,6 +6,6 @@ async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe()); app.enableCors(); - await app.listen(process.env.PORT || 3000); + await app.listen(process.env.PORT || 3001); } bootstrap(); From 248c03abd085ef20d7d9614733c30d64fd2a43e8 Mon Sep 17 00:00:00 2001 From: Joaovitor045 Date: Sat, 1 Feb 2025 08:51:27 -0300 Subject: [PATCH 04/10] feat:us05 implemented with tests --- src/books/books.controller.ts | 5 +++- src/books/books.mock.ts | 6 ++-- src/books/books.service.spec.ts | 40 ++++++++++++++++++++++++++ src/books/books.service.ts | 4 +-- src/books/dtos/updateBookStatus.dto.ts | 1 + 5 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 src/books/books.service.spec.ts diff --git a/src/books/books.controller.ts b/src/books/books.controller.ts index 6405798..cf45fc6 100644 --- a/src/books/books.controller.ts +++ b/src/books/books.controller.ts @@ -24,7 +24,10 @@ export class BooksController { @Put(':id/status') - async updateBookStatus(@Param('id') id: string, @Body() updateBookStatusDto: UpdateBookStatusDto) { + async updateBookStatus( + @Param('id') id: string, + @Body() updateBookStatusDto: UpdateBookStatusDto + ) { return this.booksService.updateBookStatus(id, updateBookStatusDto); } } diff --git a/src/books/books.mock.ts b/src/books/books.mock.ts index 3b1b4f0..93548b9 100644 --- a/src/books/books.mock.ts +++ b/src/books/books.mock.ts @@ -6,7 +6,8 @@ export const booksMock = [ rating: 4.5, description: "Descrição do livro", coverImage: "/logo.png", - status: "Available" + status: "Available", + userId: null }, { id: 2, @@ -15,6 +16,7 @@ export const booksMock = [ rating: 2.5, description: "Descrição do livro", coverImage: "/logo.png", - status: "Available" + status: "Available", + userId: null } ]; diff --git a/src/books/books.service.spec.ts b/src/books/books.service.spec.ts new file mode 100644 index 0000000..4356efa --- /dev/null +++ b/src/books/books.service.spec.ts @@ -0,0 +1,40 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { BooksService } from './books.service'; +import { NotFoundException } from '@nestjs/common'; + +describe('BooksService', () => { + let booksService: BooksService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [BooksService], + }).compile(); + + booksService = module.get(BooksService); + }); + + it('deve buscar um livro por ID existente', async () => { + const result = await booksService.getBookById('1'); + expect(result).toBeDefined(); + expect(result.id).toBe(1); + }); + + it('deve lançar erro ao buscar um livro por ID inexistente', async () => { + await expect(booksService.getBookById('999')).rejects.toThrow(NotFoundException); + }); + + it('deve atualizar o status de um livro existente', async () => { + const updatedBook = await booksService.updateBookStatus('1', { + status: 'NotAvailable', + userId: '' + }); + expect(updatedBook.status).toBe('NotAvailable'); + }); + + it('deve lançar erro ao tentar atualizar o status de um livro inexistente', async () => { + await expect(booksService.updateBookStatus('999', { + status: 'NotAvailable', + userId: '' + })).rejects.toThrow(NotFoundException); + }); +}); diff --git a/src/books/books.service.ts b/src/books/books.service.ts index 55c9608..24c8a63 100644 --- a/src/books/books.service.ts +++ b/src/books/books.service.ts @@ -2,11 +2,11 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { BorrowBooksDto } from './dtos/borrowBooks.dto'; import { SearchBooksDto } from './dtos/searchBooks.dto'; import { UpdateBookStatusDto } from './dtos/updateBookStatus.dto'; -import { booksMock } from './books.mock'; // 🔥 Importando o mock +import { booksMock } from './books.mock'; @Injectable() export class BooksService { - private books = booksMock; // Usando o mock + private books = booksMock; async searchBooks(searchParams: SearchBooksDto) { return this.books.filter(book => diff --git a/src/books/dtos/updateBookStatus.dto.ts b/src/books/dtos/updateBookStatus.dto.ts index 6b2664c..8510b62 100644 --- a/src/books/dtos/updateBookStatus.dto.ts +++ b/src/books/dtos/updateBookStatus.dto.ts @@ -1,4 +1,5 @@ export class UpdateBookStatusDto { status: string; + userId: string | null; } \ No newline at end of file From c72ec432e89b757ce5a9d46ed342d9cf0ed00d71 Mon Sep 17 00:00:00 2001 From: Joaovitor045 Date: Sat, 1 Feb 2025 08:59:34 -0300 Subject: [PATCH 05/10] feat:us05 implemented with tests --- src/books/books.controller.ts | 5 ++--- src/books/books.mock.ts | 26 +++++++++++++------------- src/books/books.module.ts | 3 +-- src/books/books.service.spec.ts | 16 ++++++++++------ src/books/books.service.ts | 22 ++++++++++++++-------- src/books/dtos/borrowBooks.dto.ts | 5 +---- src/books/dtos/updateBookStatus.dto.ts | 7 +++---- 7 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/books/books.controller.ts b/src/books/books.controller.ts index cf45fc6..f058bb6 100644 --- a/src/books/books.controller.ts +++ b/src/books/books.controller.ts @@ -18,15 +18,14 @@ export class BooksController { try { return await this.booksService.getBookById(id); } catch (error) { - throw error; + throw error; } } - @Put(':id/status') async updateBookStatus( @Param('id') id: string, - @Body() updateBookStatusDto: UpdateBookStatusDto + @Body() updateBookStatusDto: UpdateBookStatusDto, ) { return this.booksService.updateBookStatus(id, updateBookStatusDto); } diff --git a/src/books/books.mock.ts b/src/books/books.mock.ts index 93548b9..5549958 100644 --- a/src/books/books.mock.ts +++ b/src/books/books.mock.ts @@ -1,22 +1,22 @@ export const booksMock = [ { id: 1, - title: "Curupira, O guardião da floresta", - author: "Saci-Pererê", + title: 'Curupira, O guardião da floresta', + author: 'Saci-Pererê', rating: 4.5, - description: "Descrição do livro", - coverImage: "/logo.png", - status: "Available", - userId: null + description: 'Descrição do livro', + coverImage: '/logo.png', + status: 'Available', + userId: null, }, { id: 2, - title: "O boto cor de rosa", - author: "Mula-sem-cabeça", + title: 'O boto cor de rosa', + author: 'Mula-sem-cabeça', rating: 2.5, - description: "Descrição do livro", - coverImage: "/logo.png", - status: "Available", - userId: null - } + description: 'Descrição do livro', + coverImage: '/logo.png', + status: 'Available', + userId: null, + }, ]; diff --git a/src/books/books.module.ts b/src/books/books.module.ts index 9c1b8c3..0a9901c 100644 --- a/src/books/books.module.ts +++ b/src/books/books.module.ts @@ -2,8 +2,7 @@ import { Module } from '@nestjs/common'; import { BooksController } from './books.controller'; import { BooksService } from './books.service'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { Book } from 'src/database/entities/book.entity'; - +import { Book } from '../../src/database/entities/book.entity'; @Module({ imports: [TypeOrmModule.forFeature([Book])], diff --git a/src/books/books.service.spec.ts b/src/books/books.service.spec.ts index 4356efa..fb10fd9 100644 --- a/src/books/books.service.spec.ts +++ b/src/books/books.service.spec.ts @@ -20,21 +20,25 @@ describe('BooksService', () => { }); it('deve lançar erro ao buscar um livro por ID inexistente', async () => { - await expect(booksService.getBookById('999')).rejects.toThrow(NotFoundException); + await expect(booksService.getBookById('999')).rejects.toThrow( + NotFoundException, + ); }); it('deve atualizar o status de um livro existente', async () => { const updatedBook = await booksService.updateBookStatus('1', { - status: 'NotAvailable', - userId: '' + status: 'NotAvailable', + userId: '', }); expect(updatedBook.status).toBe('NotAvailable'); }); it('deve lançar erro ao tentar atualizar o status de um livro inexistente', async () => { - await expect(booksService.updateBookStatus('999', { + await expect( + booksService.updateBookStatus('999', { status: 'NotAvailable', - userId: '' - })).rejects.toThrow(NotFoundException); + userId: '', + }), + ).rejects.toThrow(NotFoundException); }); }); diff --git a/src/books/books.service.ts b/src/books/books.service.ts index 24c8a63..60caf31 100644 --- a/src/books/books.service.ts +++ b/src/books/books.service.ts @@ -2,28 +2,34 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { BorrowBooksDto } from './dtos/borrowBooks.dto'; import { SearchBooksDto } from './dtos/searchBooks.dto'; import { UpdateBookStatusDto } from './dtos/updateBookStatus.dto'; -import { booksMock } from './books.mock'; +import { booksMock } from './books.mock'; @Injectable() export class BooksService { - private books = booksMock; + private books = booksMock; async searchBooks(searchParams: SearchBooksDto) { - return this.books.filter(book => - (searchParams.title ? book.title.includes(searchParams.title) : true) && - (searchParams.author ? book.author.includes(searchParams.author) : true) + return this.books.filter( + (book) => + (searchParams.title ? book.title.includes(searchParams.title) : true) && + (searchParams.author + ? book.author.includes(searchParams.author) + : true), ); } async getBookById(id: string): Promise { - const book = this.books.find(book => book.id === Number(id)); + const book = this.books.find((book) => book.id === Number(id)); if (!book) { - throw new NotFoundException("Livro não encontrado"); + throw new NotFoundException('Livro não encontrado'); } return book; } - async updateBookStatus(id: string, updateBookStatusDto: UpdateBookStatusDto): Promise { + async updateBookStatus( + id: string, + updateBookStatusDto: UpdateBookStatusDto, + ): Promise { const bookIndex = this.books.findIndex((book) => book.id === Number(id)); if (bookIndex === -1) { diff --git a/src/books/dtos/borrowBooks.dto.ts b/src/books/dtos/borrowBooks.dto.ts index f9dde9e..aefdaf7 100644 --- a/src/books/dtos/borrowBooks.dto.ts +++ b/src/books/dtos/borrowBooks.dto.ts @@ -1,7 +1,5 @@ -import { IsString, IsOptional, IsNumber, IsNotEmpty } from 'class-validator'; - export class BorrowBooksDto { - id: number; + id: number; title: string; author: string; rating: number; @@ -9,4 +7,3 @@ export class BorrowBooksDto { coverImage: string; status: string; } - diff --git a/src/books/dtos/updateBookStatus.dto.ts b/src/books/dtos/updateBookStatus.dto.ts index 8510b62..6f9ded3 100644 --- a/src/books/dtos/updateBookStatus.dto.ts +++ b/src/books/dtos/updateBookStatus.dto.ts @@ -1,5 +1,4 @@ export class UpdateBookStatusDto { - status: string; - userId: string | null; - } - \ No newline at end of file + status: string; + userId: string | null; +} From ca6c777a0248adaef03d3b21600f6d4f4944bba6 Mon Sep 17 00:00:00 2001 From: Joaovitor045 Date: Mon, 3 Feb 2025 09:57:17 -0300 Subject: [PATCH 06/10] feat:us05 implemented with tests --- src/books/books.mock.ts | 4 ++-- src/books/books.module.ts | 2 +- src/database/entities/book.entity.ts | 15 ++++----------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/books/books.mock.ts b/src/books/books.mock.ts index 5549958..8052ada 100644 --- a/src/books/books.mock.ts +++ b/src/books/books.mock.ts @@ -5,7 +5,7 @@ export const booksMock = [ author: 'Saci-Pererê', rating: 4.5, description: 'Descrição do livro', - coverImage: '/logo.png', + coverImage: '/curupira.jpeg', status: 'Available', userId: null, }, @@ -15,7 +15,7 @@ export const booksMock = [ author: 'Mula-sem-cabeça', rating: 2.5, description: 'Descrição do livro', - coverImage: '/logo.png', + coverImage: '/boto.jpeg', status: 'Available', userId: null, }, diff --git a/src/books/books.module.ts b/src/books/books.module.ts index 0a9901c..3237b2b 100644 --- a/src/books/books.module.ts +++ b/src/books/books.module.ts @@ -2,7 +2,7 @@ import { Module } from '@nestjs/common'; import { BooksController } from './books.controller'; import { BooksService } from './books.service'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { Book } from '../../src/database/entities/book.entity'; +import { Book } from 'src/database/entities/book.entity'; @Module({ imports: [TypeOrmModule.forFeature([Book])], diff --git a/src/database/entities/book.entity.ts b/src/database/entities/book.entity.ts index 9642742..95b2573 100644 --- a/src/database/entities/book.entity.ts +++ b/src/database/entities/book.entity.ts @@ -1,15 +1,8 @@ -import { HttpStatus } from '@nestjs/common'; -import { - Column, - CreateDateColumn, - Entity, - PrimaryGeneratedColumn, - UpdateDateColumn, -} from 'typeorm'; +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; export enum Status { - AVAILABLE = "available", - NOTAVAILABLE = "notAvailable", + AVAILABLE = 'available', + NOTAVAILABLE = 'notAvailable', } @Entity() @@ -42,7 +35,7 @@ export class Book { borrowedBy: string; @Column({ - type: "enum", + type: 'enum', enum: Status, default: Status.AVAILABLE, }) From f644d122b6a9f697af02fc5a3ee18d8ead260821 Mon Sep 17 00:00:00 2001 From: Joaovitor045 Date: Mon, 3 Feb 2025 19:22:19 -0300 Subject: [PATCH 07/10] fixint --- src/books/books.module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/books/books.module.ts b/src/books/books.module.ts index 3237b2b..09b0114 100644 --- a/src/books/books.module.ts +++ b/src/books/books.module.ts @@ -2,7 +2,7 @@ import { Module } from '@nestjs/common'; import { BooksController } from './books.controller'; import { BooksService } from './books.service'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { Book } from 'src/database/entities/book.entity'; +import { Book } from '../database/entities/book.entity'; @Module({ imports: [TypeOrmModule.forFeature([Book])], From 05e26032b42dff1852246b1608b745f2ad97209c Mon Sep 17 00:00:00 2001 From: Joaovitor045 Date: Mon, 3 Feb 2025 19:34:46 -0300 Subject: [PATCH 08/10] fixint --- listenv.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 listenv.txt diff --git a/listenv.txt b/listenv.txt new file mode 100644 index 0000000..e537c70 --- /dev/null +++ b/listenv.txt @@ -0,0 +1,10 @@ +DB_PORT=5432 +DB_HOST=localhost +DB_USER=afonso +DB_PASSWORD=afonso +DB_NAME=test +ENVIRONMENT=dev +MAIL_HOST= +MAIL_USERNAME= +MAIL_PASSWORD= +APP_URL=http://localhost:3000 From 24f0c6f82cd35329d21551e295feb7a64b81c2d1 Mon Sep 17 00:00:00 2001 From: Joaovitor045 Date: Tue, 4 Feb 2025 12:50:01 -0300 Subject: [PATCH 09/10] fixint:us05 completed --- src/books/books.mock.ts | 6 ++++-- src/books/books.service.spec.ts | 4 ++++ src/books/books.service.ts | 13 ++++++++++--- src/books/dtos/updateBookStatus.dto.ts | 3 ++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/books/books.mock.ts b/src/books/books.mock.ts index 8052ada..9c325a3 100644 --- a/src/books/books.mock.ts +++ b/src/books/books.mock.ts @@ -7,7 +7,8 @@ export const booksMock = [ description: 'Descrição do livro', coverImage: '/curupira.jpeg', status: 'Available', - userId: null, + userId: '', + date: '', }, { id: 2, @@ -17,6 +18,7 @@ export const booksMock = [ description: 'Descrição do livro', coverImage: '/boto.jpeg', status: 'Available', - userId: null, + userId: '', + date: '', }, ]; diff --git a/src/books/books.service.spec.ts b/src/books/books.service.spec.ts index fb10fd9..c421c28 100644 --- a/src/books/books.service.spec.ts +++ b/src/books/books.service.spec.ts @@ -1,6 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { BooksService } from './books.service'; import { NotFoundException } from '@nestjs/common'; +import { isString } from 'class-validator'; describe('BooksService', () => { let booksService: BooksService; @@ -29,6 +30,7 @@ describe('BooksService', () => { const updatedBook = await booksService.updateBookStatus('1', { status: 'NotAvailable', userId: '', + date: '', }); expect(updatedBook.status).toBe('NotAvailable'); }); @@ -38,6 +40,8 @@ describe('BooksService', () => { booksService.updateBookStatus('999', { status: 'NotAvailable', userId: '', + date: '', + }), ).rejects.toThrow(NotFoundException); }); diff --git a/src/books/books.service.ts b/src/books/books.service.ts index 60caf31..cd3b2ee 100644 --- a/src/books/books.service.ts +++ b/src/books/books.service.ts @@ -31,12 +31,19 @@ export class BooksService { updateBookStatusDto: UpdateBookStatusDto, ): Promise { const bookIndex = this.books.findIndex((book) => book.id === Number(id)); - + if (bookIndex === -1) { throw new NotFoundException('Livro não encontrado'); } + - this.books[bookIndex].status = updateBookStatusDto.status; + this.books[bookIndex] = { + ...this.books[bookIndex], + status: updateBookStatusDto.status, + userId: updateBookStatusDto.userId, + date: new Date().toISOString(), + }; + return this.books[bookIndex]; } -} +} \ No newline at end of file diff --git a/src/books/dtos/updateBookStatus.dto.ts b/src/books/dtos/updateBookStatus.dto.ts index 6f9ded3..6c9939c 100644 --- a/src/books/dtos/updateBookStatus.dto.ts +++ b/src/books/dtos/updateBookStatus.dto.ts @@ -1,4 +1,5 @@ export class UpdateBookStatusDto { status: string; - userId: string | null; + userId: string; + date: string; } From b20d229bc22d53ff88d0b09d5385723dd8c4386e Mon Sep 17 00:00:00 2001 From: Joaovitor045 Date: Wed, 5 Feb 2025 06:45:01 -0300 Subject: [PATCH 10/10] fixint:us05 completed --- src/books/books.service.spec.ts | 2 -- src/books/books.service.ts | 9 ++++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/books/books.service.spec.ts b/src/books/books.service.spec.ts index c421c28..adaa724 100644 --- a/src/books/books.service.spec.ts +++ b/src/books/books.service.spec.ts @@ -1,7 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { BooksService } from './books.service'; import { NotFoundException } from '@nestjs/common'; -import { isString } from 'class-validator'; describe('BooksService', () => { let booksService: BooksService; @@ -41,7 +40,6 @@ describe('BooksService', () => { status: 'NotAvailable', userId: '', date: '', - }), ).rejects.toThrow(NotFoundException); }); diff --git a/src/books/books.service.ts b/src/books/books.service.ts index cd3b2ee..00a4cdb 100644 --- a/src/books/books.service.ts +++ b/src/books/books.service.ts @@ -31,19 +31,18 @@ export class BooksService { updateBookStatusDto: UpdateBookStatusDto, ): Promise { const bookIndex = this.books.findIndex((book) => book.id === Number(id)); - + if (bookIndex === -1) { throw new NotFoundException('Livro não encontrado'); } - this.books[bookIndex] = { ...this.books[bookIndex], status: updateBookStatusDto.status, userId: updateBookStatusDto.userId, - date: new Date().toISOString(), + date: new Date().toISOString(), }; - + return this.books[bookIndex]; } -} \ No newline at end of file +}