diff --git a/README.md b/README.md index 53f1bf5..f1472bb 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ $ npm run test:e2e ### Application Rules - [x] It must be possible to register a pet -- [ ] It must be possible to list all pets available for adoption in a city +- [x] It must be possible to list all pets available for adoption in a city - [ ] It must be possible to filter pets by their characteristics - [ ] It must be possible to view details of a pet available for adoption - [x] It must be possible to register as an ORG @@ -52,7 +52,7 @@ $ npm run test:e2e ### Business Rules -- [ ] To list the pets, it is mandatory to provide the city +- [x] To list the pets, it is mandatory to provide the city - [x] An ORG must have an address and a WhatsApp number - [x] A pet must be linked to an ORG - [ ] The user who wants to adopt will contact the ORG via WhatsApp diff --git a/src/controllers/pets/e2e/get-pet-controllet.spec.ts b/src/controllers/pets/e2e/get-pet-controllet.spec.ts new file mode 100644 index 0000000..8fe38c5 --- /dev/null +++ b/src/controllers/pets/e2e/get-pet-controllet.spec.ts @@ -0,0 +1,63 @@ +import { app } from "@/app"; +import { prisma } from "@/lib/prisma"; +import { AddressResponse, getAddressByCep } from "@/services/cep/cep-api-service"; +import { afterAll, beforeAll, describe, expect, it } from "vitest"; +import request from 'supertest' + +describe('Get pet by id', () => { + + beforeAll(async () => { + await app.ready() + }) + + afterAll(async () => { + await app.close() + }) + + it('should get pet by id', async () => { + const address = await getAddressByCep('08560200') as AddressResponse + + const org = await prisma.org.create({ + data: { + cep: '08560200', + email: 'teste@teste.com', + name: 'OEG TEST', + password_hash: '123456', + whatsapp: '119827464', + bairro: address.bairro, + estado: address.estado, + localidade: address.localidade, + logradouro: address.logradouro, + uf: address.uf + } + }) + + const petAddress = await getAddressByCep('13423790') as AddressResponse + + const pet = await prisma.pet.create({ + data: { + age: 'Small', + cep: '13423790', + description: 'A really nice cat', + energy: 'Active', + environment: 'All', + name: 'Harry', + org_id: org.id, + size: 'Big', + localidade: petAddress.localidade, + bairro: petAddress.bairro, + estado: petAddress.estado, + logradouro: petAddress.logradouro, + uf: petAddress.uf, + } + }) + + const response = await request(app.server).get(`/pets/single/${pet.id}`) + + expect(response.body.pet).toEqual(expect.objectContaining({ + localidade: expect.any(String) + })) + expect(response.body.pet.localidade).toEqual(petAddress.localidade) + expect(response.statusCode).toEqual(200) + }) +}) \ No newline at end of file diff --git a/src/controllers/pets/get-pet-controllet.ts b/src/controllers/pets/get-pet-controllet.ts new file mode 100644 index 0000000..e65ba1e --- /dev/null +++ b/src/controllers/pets/get-pet-controllet.ts @@ -0,0 +1,16 @@ +import { GetPetFacotry } from "@/services/pets/factories/get-pet-factory"; +import { FastifyReply, FastifyRequest } from "fastify"; +import { z } from "zod"; + +export async function getPetById(request: FastifyRequest, reply: FastifyReply){ + + const getPetBodySchema = z.object({ + id: z.string(), + }) + + const { id } = getPetBodySchema.parse(request.params) + const getPetService = GetPetFacotry() + + const pet = await getPetService.execute({ id }) + reply.send(pet).status(200) +} \ No newline at end of file diff --git a/src/controllers/pets/routes.ts b/src/controllers/pets/routes.ts index d4d73ca..be40f76 100644 --- a/src/controllers/pets/routes.ts +++ b/src/controllers/pets/routes.ts @@ -1,8 +1,10 @@ import { FastifyInstance } from "fastify"; import { registerPet } from "./register-pet-controller"; import { listPet } from "./list-pet-controller"; +import { getPetById } from "./get-pet-controllet"; export async function petRoutes(app: FastifyInstance) { app.post('/pets', registerPet) app.get('/pets/:city', listPet) + app.get('/pets/single/:id', getPetById) } \ No newline at end of file diff --git a/src/services/pets/factories/get-pet-factory.ts b/src/services/pets/factories/get-pet-factory.ts new file mode 100644 index 0000000..da6ff66 --- /dev/null +++ b/src/services/pets/factories/get-pet-factory.ts @@ -0,0 +1,9 @@ +import { PrismaPetsRepository } from "@/repositories/pets/pets-repository" +import { GetPetService } from "../get-pet-service" + +export function GetPetFacotry(){ + const petsRepository = new PrismaPetsRepository() + const getPetService = new GetPetService(petsRepository) + + return getPetService +} \ No newline at end of file diff --git a/src/services/pets/get-pet-service.ts b/src/services/pets/get-pet-service.ts new file mode 100644 index 0000000..8a5ffdb --- /dev/null +++ b/src/services/pets/get-pet-service.ts @@ -0,0 +1,20 @@ +import { Pet } from "@prisma/client"; +import { PetsRepository } from '../../repositories/pets/prisma-pets-repository'; + +interface GetPetRequest { + id: string; +} + +interface GetPetResponse { + pet: Pet | null +} + +export class GetPetService { + + constructor(private petsRepository: PetsRepository) { } + + async execute({ id }: GetPetRequest): Promise { + const pet = await this.petsRepository.findById(id) + return { pet } + } +} \ No newline at end of file diff --git a/src/services/pets/tests/get-pet-service.spec.ts b/src/services/pets/tests/get-pet-service.spec.ts new file mode 100644 index 0000000..bf62f65 --- /dev/null +++ b/src/services/pets/tests/get-pet-service.spec.ts @@ -0,0 +1,62 @@ +import { beforeEach, describe, expect, it } from "vitest"; +import { GetPetService } from "../get-pet-service"; +import { PetsRepository } from "@/repositories/pets/prisma-pets-repository"; +import { InMemoryPetsRepository } from "@/repositories/pets/in-memory-pets-repository"; +import { AddressResponse, getAddressByCep } from "@/services/cep/cep-api-service"; + +let sut: GetPetService +let petsRepository: PetsRepository + +describe('Get pet by id', () => { + + beforeEach(() => { + petsRepository = new InMemoryPetsRepository() + sut = new GetPetService(petsRepository) + }) + + it('should get pet by id', async () => { + const address = await getAddressByCep('08560200') as AddressResponse + + const createdPet = await petsRepository.create({ + age: 'Small', + cep: '08560250', + description: 'A really nice cat', + energy: 'Active', + environment: 'All', + name: 'Harry', + org_id: '1', + size: 'Big', + bairro: address.bairro, + estado: address.estado, + localidade: address.localidade, + logradouro: address.logradouro, + uf: address.uf, + }) + + const { pet } = await sut.execute({ id: createdPet.id }) + expect(pet?.age).toEqual(createdPet.age) + }) + + it('should not get pet by id', async () => { + const address = await getAddressByCep('08560200') as AddressResponse + + await petsRepository.create({ + age: 'Small', + cep: '08560250', + description: 'A really nice cat', + energy: 'Active', + environment: 'All', + name: 'Harry', + org_id: '1', + size: 'Big', + bairro: address.bairro, + estado: address.estado, + localidade: address.localidade, + logradouro: address.logradouro, + uf: address.uf, + }) + + const { pet } = await sut.execute({ id: 'NON_EXISTING ID' }) + expect(pet?.age).toBeUndefined() + }) +}) \ No newline at end of file