From 8de74f320a59df40bd768558ec377c3557e294b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Geraldo=20D=2E=20F?= Date: Wed, 15 May 2024 17:53:01 -0300 Subject: [PATCH] Release/0.0.3 (#117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jhonatan David <82552187+jotahdavid@users.noreply.github.com> Co-authored-by: MatheusDubin Co-authored-by: Lipe Co-authored-by: Gustavo Clemente Co-authored-by: kelvinsb Co-authored-by: Tatiane Co-authored-by: Sombrio Co-authored-by: AlbuquerqueRafael Co-authored-by: Arthur <40851238+4rthuurr@users.noreply.github.com> Co-authored-by: Giovanni Bassi <334958+giggio@users.noreply.github.com> Co-authored-by: LeoFC97 Co-authored-by: Rogério Piatek <74259272+RogerioPiatek@users.noreply.github.com> Co-authored-by: Anderson Rocha <59173445+AndersonCRocha@users.noreply.github.com> Co-authored-by: Pedro Perrone Co-authored-by: Kevin Eduard Piske Co-authored-by: Kevin Eduard Piske Co-authored-by: Wesley Araujo <52975177+w-araujo@users.noreply.github.com> --- .eslintrc.js | 19 ++-- .github/workflows/ci.yml | 17 +++- jest.config.ts | 20 +++++ package-lock.json | 26 ++++++ package.json | 20 +---- .../migrations/20240514211840_/migration.sql | 14 +++ .../migrations/20240515003750_/migration.sql | 8 ++ prisma/schema.prisma | 10 +++ src/app.module.ts | 2 + src/main.ts | 1 + src/partners/partners.controller.spec.ts | 29 +++++++ src/partners/partners.controller.ts | 21 +++++ src/partners/partners.module.ts | 12 +++ src/partners/partners.service.spec.ts | 28 ++++++ src/partners/partners.service.ts | 14 +++ src/sessions/sessions.controller.spec.ts | 12 ++- src/sessions/sessions.service.spec.ts | 12 ++- .../shelter-managers.controller.spec.ts | 11 ++- .../shelter-managers.service.spec.ts | 9 +- .../shelter-supply.controller.spec.ts | 11 ++- .../shelter-supply.service.spec.ts | 9 +- src/shelter-supply/types.ts | 2 +- src/shelter/ShelterSearch.ts | 1 + src/shelter/shelter.controller.spec.ts | 13 ++- src/shelter/shelter.service.spec.ts | 13 ++- src/shelter/shelter.service.ts | 17 ++-- .../supply-categories.controller.spec.ts | 11 ++- .../supply-categories.service.spec.ts | 9 +- src/supply/supply.controller.spec.ts | 11 ++- src/supply/supply.service.spec.ts | 9 +- src/users/users.controller.spec.ts | 11 ++- src/users/users.controller.ts | 87 ++++++++++++++++++- src/users/users.service.spec.ts | 9 +- test/app.e2e-spec.ts | 7 +- test/jest-e2e.json | 9 -- test/jest.e2e.config.ts | 15 ++++ 36 files changed, 465 insertions(+), 64 deletions(-) create mode 100644 jest.config.ts create mode 100644 prisma/migrations/20240514211840_/migration.sql create mode 100644 prisma/migrations/20240515003750_/migration.sql create mode 100644 src/partners/partners.controller.spec.ts create mode 100644 src/partners/partners.controller.ts create mode 100644 src/partners/partners.module.ts create mode 100644 src/partners/partners.service.spec.ts create mode 100644 src/partners/partners.service.ts delete mode 100644 test/jest-e2e.json create mode 100644 test/jest.e2e.config.ts diff --git a/.eslintrc.js b/.eslintrc.js index d8bc3457..3627deb5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,10 +5,11 @@ module.exports = { tsconfigRootDir: __dirname, sourceType: 'module', }, - plugins: ['@typescript-eslint/eslint-plugin'], + plugins: ['@typescript-eslint/eslint-plugin', 'jest'], extends: [ 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended', + 'plugin:jest/recommended', ], root: true, env: { @@ -21,11 +22,17 @@ module.exports = { '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-explicit-any': 'off', - "prettier/prettier": [ - "error", + 'jest/expect-expect': [ + 'warn', { - "endOfLine": "auto" - } - ] + assertFunctionNames: ['expect', 'request.**.expect'], + }, + ], + 'prettier/prettier': [ + 'error', + { + endOfLine: 'auto', + }, + ], }, }; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f03015e0..150e2e9f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,15 @@ name: CI on: + workflow_dispatch: + push: + branches: + - main + tags: + - '*' pull_request: branches: - - master + - main - develop jobs: @@ -15,10 +21,10 @@ jobs: - name: Checkout Source uses: actions/checkout@v4 # Setup node.js and cache - - name: "Setup node.js" + - name: 'Setup node.js' uses: actions/setup-node@v4 with: - node-version: "18.x" + node-version: '18.x' cache: 'npm' cache-dependency-path: ./package-lock.json # Install dependencies @@ -29,4 +35,7 @@ jobs: run: npm run lint:ci # Build App - name: Build App - run: npm run build \ No newline at end of file + run: npm run build + + - name: Test + run: npm test diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 00000000..6bc3f4c4 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,20 @@ +import type { Config } from 'jest'; + +const config: Config = { + moduleFileExtensions: ['js', 'json', 'ts'], + rootDir: 'src', + testRegex: '.*\\.spec\\.ts$', + transform: { + '^.+\\.(t|j)s$': 'ts-jest', + }, + collectCoverageFrom: ['**/*.(t|j)s'], + coverageDirectory: '../coverage', + moduleNameMapper: { + '^src/(.*)$': '/$1', + '^@/(.*)$': '/$1', + '^test/(.*)$': '/../$1', + }, + testEnvironment: 'node', +}; + +export default config; diff --git a/package-lock.json b/package-lock.json index 6c3ae692..455fac11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,7 @@ "@typescript-eslint/parser": "^6.0.0", "eslint": "^8.42.0", "eslint-config-prettier": "^9.0.0", + "eslint-plugin-jest": "^28.5.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "prettier": "^3.0.0", @@ -4517,6 +4518,31 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-plugin-jest": { + "version": "28.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.5.0.tgz", + "integrity": "sha512-6np6DGdmNq/eBbA7HOUNV8fkfL86PYwBfwyb8n23FXgJNTR8+ot3smRHjza9LGsBBZRypK3qyF79vMjohIL8eQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" + }, + "engines": { + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, "node_modules/eslint-plugin-prettier": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", diff --git a/package.json b/package.json index 3212f2fd..b20634cd 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./test/jest-e2e.json", + "test:e2e": "jest --config ./test/jest.e2e.config.ts", "migrations:run": "npx prisma migrate deploy", "migrations:dev": "npx prisma migrate dev", "docker:compose": "docker-compose -f docker-compose.dev.yml up" @@ -53,6 +53,7 @@ "@typescript-eslint/parser": "^6.0.0", "eslint": "^8.42.0", "eslint-config-prettier": "^9.0.0", + "eslint-plugin-jest": "^28.5.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "prettier": "^3.0.0", @@ -64,22 +65,5 @@ "ts-node": "^10.9.1", "tsconfig-paths": "^4.2.0", "typescript": "^5.1.3" - }, - "jest": { - "moduleFileExtensions": [ - "js", - "json", - "ts" - ], - "rootDir": "src", - "testRegex": ".*\\.spec\\.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - }, - "collectCoverageFrom": [ - "**/*.(t|j)s" - ], - "coverageDirectory": "../coverage", - "testEnvironment": "node" } } diff --git a/prisma/migrations/20240514211840_/migration.sql b/prisma/migrations/20240514211840_/migration.sql new file mode 100644 index 00000000..d0e1f1e2 --- /dev/null +++ b/prisma/migrations/20240514211840_/migration.sql @@ -0,0 +1,14 @@ +-- CreateTable +CREATE TABLE "partners" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "link" TEXT NOT NULL, + "iconName" TEXT NOT NULL DEFAULT 'Handshake', + "created_at" VARCHAR(32) NOT NULL, + "updated_at" VARCHAR(32), + + CONSTRAINT "partners_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "partners_name_key" ON "partners"("name"); diff --git a/prisma/migrations/20240515003750_/migration.sql b/prisma/migrations/20240515003750_/migration.sql new file mode 100644 index 00000000..5e1e2a63 --- /dev/null +++ b/prisma/migrations/20240515003750_/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - You are about to drop the column `iconName` on the `partners` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "partners" DROP COLUMN "iconName"; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b853d2b4..a43b535a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -123,3 +123,13 @@ model ShelterManagers { @@id([shelterId, userId]) @@map("shelter_managers") } + +model Partners { + id String @id @default(uuid()) + name String @unique + link String + createdAt String @map("created_at") @db.VarChar(32) + updatedAt String? @map("updated_at") @db.VarChar(32) + + @@map("partners") +} diff --git a/src/app.module.ts b/src/app.module.ts index 8b528767..c08ea99f 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -11,6 +11,7 @@ import { SessionsModule } from './sessions/sessions.module'; import { SupplyCategoriesModule } from './supply-categories/supply-categories.module'; import { ShelterManagersModule } from './shelter-managers/shelter-managers.module'; import { ShelterSupplyModule } from './shelter-supply/shelter-supply.module'; +import { PartnersModule } from './partners/partners.module'; @Module({ imports: [ @@ -22,6 +23,7 @@ import { ShelterSupplyModule } from './shelter-supply/shelter-supply.module'; SupplyCategoriesModule, ShelterManagersModule, ShelterSupplyModule, + PartnersModule, ], controllers: [], providers: [ diff --git a/src/main.ts b/src/main.ts index eaf3c678..649e75d4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,6 +18,7 @@ async function bootstrap() { .setTitle('SOS - Rio Grande do Sul') .setDescription('...') .setVersion('1.0') + .addBearerAuth() .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('api', app, document); diff --git a/src/partners/partners.controller.spec.ts b/src/partners/partners.controller.spec.ts new file mode 100644 index 00000000..3d7226e8 --- /dev/null +++ b/src/partners/partners.controller.spec.ts @@ -0,0 +1,29 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PartnersController } from './partners.controller'; +import { PartnersService } from './partners.service'; +import { PrismaService } from '../prisma/prisma.service'; + +describe('PartnersController', () => { + let controller: PartnersController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [PartnersController], + providers: [PartnersService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return { + supplyCategory: { findMany: jest.fn().mockResolvedValue(0) }, + }; + } + }) + .compile(); + + controller = module.get(PartnersController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/partners/partners.controller.ts b/src/partners/partners.controller.ts new file mode 100644 index 00000000..f1829171 --- /dev/null +++ b/src/partners/partners.controller.ts @@ -0,0 +1,21 @@ +import { Controller, Get, HttpException, Logger } from '@nestjs/common'; +import { PartnersService } from './partners.service'; +import { ServerResponse } from '../utils'; + +@Controller('partners') +export class PartnersController { + private logger = new Logger(PartnersController.name); + + constructor(private readonly partnersService: PartnersService) {} + + @Get('') + async index() { + try { + const data = await this.partnersService.index(); + return new ServerResponse(200, 'Successfully get partners', data); + } catch (err: any) { + this.logger.error(`Failed to get partners: ${err}`); + throw new HttpException(err?.code ?? err?.name ?? `${err}`, 400); + } + } +} diff --git a/src/partners/partners.module.ts b/src/partners/partners.module.ts new file mode 100644 index 00000000..04ea8c41 --- /dev/null +++ b/src/partners/partners.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; + +import { PartnersService } from './partners.service'; +import { PartnersController } from './partners.controller'; +import { PrismaModule } from '../prisma/prisma.module'; + +@Module({ + imports: [PrismaModule], + providers: [PartnersService], + controllers: [PartnersController], +}) +export class PartnersModule {} diff --git a/src/partners/partners.service.spec.ts b/src/partners/partners.service.spec.ts new file mode 100644 index 00000000..f34d51e9 --- /dev/null +++ b/src/partners/partners.service.spec.ts @@ -0,0 +1,28 @@ +import { Test, TestingModule } from '@nestjs/testing'; + +import { PartnersService } from './partners.service'; +import { PrismaService } from '../prisma/prisma.service'; + +describe('PartnersService', () => { + let service: PartnersService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PartnersService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return { + supplyCategory: { findMany: jest.fn().mockResolvedValue(0) }, + }; + } + }) + .compile(); + + service = module.get(PartnersService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/partners/partners.service.ts b/src/partners/partners.service.ts new file mode 100644 index 00000000..6b3f6c8a --- /dev/null +++ b/src/partners/partners.service.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; + +import { PrismaService } from '../prisma/prisma.service'; + +@ApiTags('Parceiros') +@Injectable() +export class PartnersService { + constructor(private readonly prismaService: PrismaService) {} + + async index() { + return await this.prismaService.partners.findMany({}); + } +} diff --git a/src/sessions/sessions.controller.spec.ts b/src/sessions/sessions.controller.spec.ts index 118ad549..a2d145e2 100644 --- a/src/sessions/sessions.controller.spec.ts +++ b/src/sessions/sessions.controller.spec.ts @@ -1,5 +1,8 @@ import { Test, TestingModule } from '@nestjs/testing'; import { SessionsController } from './sessions.controller'; +import { SessionsService } from './sessions.service'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { JwtService } from '@nestjs/jwt'; describe('SessionsController', () => { let controller: SessionsController; @@ -7,7 +10,14 @@ describe('SessionsController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [SessionsController], - }).compile(); + providers: [SessionsService, JwtService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); controller = module.get(SessionsController); }); diff --git a/src/sessions/sessions.service.spec.ts b/src/sessions/sessions.service.spec.ts index 923df18b..4115d43b 100644 --- a/src/sessions/sessions.service.spec.ts +++ b/src/sessions/sessions.service.spec.ts @@ -1,13 +1,21 @@ import { Test, TestingModule } from '@nestjs/testing'; import { SessionsService } from './sessions.service'; +import { JwtService } from '@nestjs/jwt'; +import { PrismaService } from 'src/prisma/prisma.service'; describe('SessionsService', () => { let service: SessionsService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [SessionsService], - }).compile(); + providers: [SessionsService, JwtService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); service = module.get(SessionsService); }); diff --git a/src/shelter-managers/shelter-managers.controller.spec.ts b/src/shelter-managers/shelter-managers.controller.spec.ts index 5bc76a94..01b41779 100644 --- a/src/shelter-managers/shelter-managers.controller.spec.ts +++ b/src/shelter-managers/shelter-managers.controller.spec.ts @@ -1,5 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { ShelterManagersController } from './shelter-managers.controller'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { ShelterManagersService } from './shelter-managers.service'; describe('ShelterManagersController', () => { let controller: ShelterManagersController; @@ -7,7 +9,14 @@ describe('ShelterManagersController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [ShelterManagersController], - }).compile(); + providers: [ShelterManagersService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); controller = module.get( ShelterManagersController, diff --git a/src/shelter-managers/shelter-managers.service.spec.ts b/src/shelter-managers/shelter-managers.service.spec.ts index 9d1878c6..51834fc4 100644 --- a/src/shelter-managers/shelter-managers.service.spec.ts +++ b/src/shelter-managers/shelter-managers.service.spec.ts @@ -1,5 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { ShelterManagersService } from './shelter-managers.service'; +import { PrismaService } from 'src/prisma/prisma.service'; describe('ShelterManagersService', () => { let service: ShelterManagersService; @@ -7,7 +8,13 @@ describe('ShelterManagersService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ShelterManagersService], - }).compile(); + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); service = module.get(ShelterManagersService); }); diff --git a/src/shelter-supply/shelter-supply.controller.spec.ts b/src/shelter-supply/shelter-supply.controller.spec.ts index 73f1a18d..04c0f885 100644 --- a/src/shelter-supply/shelter-supply.controller.spec.ts +++ b/src/shelter-supply/shelter-supply.controller.spec.ts @@ -1,5 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { ShelterSupplyController } from './shelter-supply.controller'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { ShelterSupplyService } from './shelter-supply.service'; describe('ShelterSupplyController', () => { let controller: ShelterSupplyController; @@ -7,7 +9,14 @@ describe('ShelterSupplyController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [ShelterSupplyController], - }).compile(); + providers: [ShelterSupplyService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); controller = module.get(ShelterSupplyController); }); diff --git a/src/shelter-supply/shelter-supply.service.spec.ts b/src/shelter-supply/shelter-supply.service.spec.ts index 2a4678ba..b3e3cae9 100644 --- a/src/shelter-supply/shelter-supply.service.spec.ts +++ b/src/shelter-supply/shelter-supply.service.spec.ts @@ -1,5 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { ShelterSupplyService } from './shelter-supply.service'; +import { PrismaService } from 'src/prisma/prisma.service'; describe('ShelterSupplyService', () => { let service: ShelterSupplyService; @@ -7,7 +8,13 @@ describe('ShelterSupplyService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ShelterSupplyService], - }).compile(); + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); service = module.get(ShelterSupplyService); }); diff --git a/src/shelter-supply/types.ts b/src/shelter-supply/types.ts index 1ff25f90..f683bf68 100644 --- a/src/shelter-supply/types.ts +++ b/src/shelter-supply/types.ts @@ -12,7 +12,7 @@ const ShelterSupplySchema = z.object({ z.literal(SupplyPriority.Needing), z.literal(SupplyPriority.Urgent), ]), - quantity: z.number().gt(0).nullable().optional(), + quantity: z.number().min(0).nullable().optional(), createdAt: z.string(), updatedAt: z.string().nullable().optional(), }); diff --git a/src/shelter/ShelterSearch.ts b/src/shelter/ShelterSearch.ts index 5215d37c..3d1367e5 100644 --- a/src/shelter/ShelterSearch.ts +++ b/src/shelter/ShelterSearch.ts @@ -60,6 +60,7 @@ class ShelterSearch { }, unavailable: { lte: this.prismaService.shelter.fields.shelteredPeople, + not: 0, }, }; diff --git a/src/shelter/shelter.controller.spec.ts b/src/shelter/shelter.controller.spec.ts index 6774fccb..eab66b66 100644 --- a/src/shelter/shelter.controller.spec.ts +++ b/src/shelter/shelter.controller.spec.ts @@ -1,5 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; +import { PrismaService } from 'src/prisma/prisma.service'; import { ShelterController } from './shelter.controller'; +import { ShelterService } from './shelter.service'; describe('ShelterController', () => { let controller: ShelterController; @@ -7,7 +9,16 @@ describe('ShelterController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [ShelterController], - }).compile(); + providers: [ShelterService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return { + supplyCategory: { findMany: jest.fn().mockResolvedValue(0) }, + }; + } + }) + .compile(); controller = module.get(ShelterController); }); diff --git a/src/shelter/shelter.service.spec.ts b/src/shelter/shelter.service.spec.ts index ac7cf4e0..1ce3198b 100644 --- a/src/shelter/shelter.service.spec.ts +++ b/src/shelter/shelter.service.spec.ts @@ -1,5 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { ShelterService } from './shelter.service'; +import { PrismaService } from 'src/prisma/prisma.service'; describe('ShelterService', () => { let service: ShelterService; @@ -7,7 +8,17 @@ describe('ShelterService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ShelterService], - }).compile(); + }) + .useMocker((token) => { + if (token === PrismaService) { + return { + supplyCategory: { + findMany: jest.fn().mockResolvedValue([]), + }, + }; + } + }) + .compile(); service = module.get(ShelterService); }); diff --git a/src/shelter/shelter.service.ts b/src/shelter/shelter.service.ts index 74d03860..f9c853d8 100644 --- a/src/shelter/shelter.service.ts +++ b/src/shelter/shelter.service.ts @@ -1,6 +1,7 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, OnModuleInit } from '@nestjs/common'; import { Prisma } from '@prisma/client'; import { DefaultArgs } from '@prisma/client/runtime/library'; +import { subDays } from 'date-fns'; import * as qs from 'qs'; import { z } from 'zod'; @@ -14,13 +15,14 @@ import { FullUpdateShelterSchema, UpdateShelterSchema, } from './types/types'; -import { subDays } from 'date-fns'; @Injectable() -export class ShelterService { +export class ShelterService implements OnModuleInit { private voluntaryIds: string[] = []; - constructor(private readonly prismaService: PrismaService) { + constructor(private readonly prismaService: PrismaService) {} + + onModuleInit() { this.loadVoluntaryIds(); } @@ -185,6 +187,11 @@ export class ShelterService { async getCities() { const cities = await this.prismaService.shelter.groupBy({ + where: { + city: { + not: null, + }, + }, by: ['city'], _count: { id: true, @@ -197,7 +204,7 @@ export class ShelterService { }); return cities.map(({ city, _count: { id: sheltersCount } }) => ({ - city: city || 'Cidade não informada', + city, sheltersCount, })); } diff --git a/src/supply-categories/supply-categories.controller.spec.ts b/src/supply-categories/supply-categories.controller.spec.ts index e9e287a5..4e92c769 100644 --- a/src/supply-categories/supply-categories.controller.spec.ts +++ b/src/supply-categories/supply-categories.controller.spec.ts @@ -1,5 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { SupplyCategoriesController } from './supply-categories.controller'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { SupplyCategoriesService } from './supply-categories.service'; describe('SupplyCategoriesController', () => { let controller: SupplyCategoriesController; @@ -7,7 +9,14 @@ describe('SupplyCategoriesController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [SupplyCategoriesController], - }).compile(); + providers: [SupplyCategoriesService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); controller = module.get( SupplyCategoriesController, diff --git a/src/supply-categories/supply-categories.service.spec.ts b/src/supply-categories/supply-categories.service.spec.ts index 52a3e572..80f980c8 100644 --- a/src/supply-categories/supply-categories.service.spec.ts +++ b/src/supply-categories/supply-categories.service.spec.ts @@ -1,4 +1,5 @@ import { Test, TestingModule } from '@nestjs/testing'; +import { PrismaService } from 'src/prisma/prisma.service'; import { SupplyCategoriesService } from './supply-categories.service'; describe('SupplyCategoriesService', () => { @@ -7,7 +8,13 @@ describe('SupplyCategoriesService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [SupplyCategoriesService], - }).compile(); + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); service = module.get(SupplyCategoriesService); }); diff --git a/src/supply/supply.controller.spec.ts b/src/supply/supply.controller.spec.ts index 60c2f5a4..0fb33288 100644 --- a/src/supply/supply.controller.spec.ts +++ b/src/supply/supply.controller.spec.ts @@ -1,5 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { SupplyController } from './supply.controller'; +import { SupplyService } from './supply.service'; +import { PrismaService } from 'src/prisma/prisma.service'; describe('SupplyController', () => { let controller: SupplyController; @@ -7,7 +9,14 @@ describe('SupplyController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [SupplyController], - }).compile(); + providers: [SupplyService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); controller = module.get(SupplyController); }); diff --git a/src/supply/supply.service.spec.ts b/src/supply/supply.service.spec.ts index f9034a62..7868d160 100644 --- a/src/supply/supply.service.spec.ts +++ b/src/supply/supply.service.spec.ts @@ -1,5 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { SupplyService } from './supply.service'; +import { PrismaService } from 'src/prisma/prisma.service'; describe('SupplyService', () => { let service: SupplyService; @@ -7,7 +8,13 @@ describe('SupplyService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [SupplyService], - }).compile(); + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); service = module.get(SupplyService); }); diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts index 3e27c395..e2bcecdc 100644 --- a/src/users/users.controller.spec.ts +++ b/src/users/users.controller.spec.ts @@ -1,5 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { UsersController } from './users.controller'; +import { UsersService } from './users.service'; +import { PrismaService } from 'src/prisma/prisma.service'; describe('UsersController', () => { let controller: UsersController; @@ -7,7 +9,14 @@ describe('UsersController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [UsersController], - }).compile(); + providers: [UsersService], + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); controller = module.get(UsersController); }); diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 5d4a0dc2..18baf4b6 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -9,7 +9,7 @@ import { Req, UseGuards, } from '@nestjs/common'; -import { ApiTags } from '@nestjs/swagger'; +import { ApiTags, ApiBody, ApiOperation, ApiBearerAuth } from '@nestjs/swagger'; import { UserGuard } from '@/guards/user.guard'; import { ServerResponse } from '../utils'; @@ -25,6 +25,31 @@ export class UsersController { @Post('') @UseGuards(AdminGuard) + @ApiBearerAuth() + @ApiOperation({ + summary: 'Cria um novo usuário', + description: 'Esta rota é usada para criar um novo usuário no sistema.', + }) + @ApiBody({ + schema: { + type: 'object', + properties: { + name: { type: 'string' }, + lastName: { type: 'string' }, + phone: { type: 'string' }, + }, + required: ['name', 'lastName', 'phone'], + }, + examples: { + 'Exemplo 1': { + value: { + name: 'Dinho', + lastName: 'Duarte', + phone: '(31) 996675945', + }, + }, + }, + }) async store(@Body() body) { try { await this.userServices.store(body); @@ -37,6 +62,36 @@ export class UsersController { @Put(':id') @UseGuards(AdminGuard) + @ApiBearerAuth() + @ApiOperation({ + summary: 'Atualiza um usuário pelo ID', + description: + 'Esta rota é usada para atualizar um usuário específico no sistema, podendo ser informado um ou mais campos.', + }) + @ApiBody({ + schema: { + type: 'object', + properties: { + name: { type: 'string' }, + lastName: { type: 'string' }, + phone: { type: 'string' }, + login: { type: 'string' }, + password: { type: 'string' }, + }, + required: [], + }, + examples: { + 'Exemplo 1': { + value: { + name: 'Dinho', + lastName: 'Duarte', + phone: '(31) 996675945', + login: 'dinho duarte', + password: '123456', + }, + }, + }, + }) async update(@Body() body, @Param('id') id: string) { try { await this.userServices.update(id, body); @@ -49,6 +104,36 @@ export class UsersController { @Put('') @UseGuards(UserGuard) + @ApiBearerAuth() + @ApiOperation({ + summary: 'Atualiza o seu próprio usuário', + description: + 'Esta rota é usada para atualizar o próprio usuário no sistema, podendo ser informado um ou mais campos.', + }) + @ApiBody({ + schema: { + type: 'object', + properties: { + name: { type: 'string' }, + lastName: { type: 'string' }, + phone: { type: 'string' }, + login: { type: 'string' }, + password: { type: 'string' }, + }, + required: [], + }, + examples: { + 'Exemplo 1': { + value: { + name: 'Dinho', + lastName: 'Duarte', + phone: '(31) 996675945', + login: 'dinho duarte', + password: '123456', + }, + }, + }, + }) async selfUpdate(@Body() body, @Req() req) { try { const { userId } = req.user; diff --git a/src/users/users.service.spec.ts b/src/users/users.service.spec.ts index 62815ba6..05a1f82b 100644 --- a/src/users/users.service.spec.ts +++ b/src/users/users.service.spec.ts @@ -1,5 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { UsersService } from './users.service'; +import { PrismaService } from 'src/prisma/prisma.service'; describe('UsersService', () => { let service: UsersService; @@ -7,7 +8,13 @@ describe('UsersService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [UsersService], - }).compile(); + }) + .useMocker((token) => { + if (token === PrismaService) { + return {}; + } + }) + .compile(); service = module.get(UsersService); }); diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts index 50cda623..4bcbd9bb 100644 --- a/test/app.e2e-spec.ts +++ b/test/app.e2e-spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import * as request from 'supertest'; -import { AppModule } from './../src/app.module'; +import { AppModule } from 'src/app.module'; describe('AppController (e2e)', () => { let app: INestApplication; @@ -16,9 +16,6 @@ describe('AppController (e2e)', () => { }); it('/ (GET)', () => { - return request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!'); + return request(app.getHttpServer()).get('/').expect(404); }); }); diff --git a/test/jest-e2e.json b/test/jest-e2e.json deleted file mode 100644 index e9d912f3..00000000 --- a/test/jest-e2e.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "moduleFileExtensions": ["js", "json", "ts"], - "rootDir": ".", - "testEnvironment": "node", - "testRegex": ".e2e-spec.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - } -} diff --git a/test/jest.e2e.config.ts b/test/jest.e2e.config.ts new file mode 100644 index 00000000..d680f170 --- /dev/null +++ b/test/jest.e2e.config.ts @@ -0,0 +1,15 @@ +import type { Config } from 'jest'; +import { default as projectConfig } from '../jest.config'; + +const config: Config = { + ...projectConfig, + rootDir: '.', + moduleNameMapper: { + '^src/(.*)$': '/../src/$1', + '^@/(.*)$': '/../src/$1', + '^test/(.*)$': '/$1', + }, + testRegex: '.e2e-spec.ts$', +}; + +export default config;