Skip to content
Snippets Groups Projects
Commit 5de725cd authored by Lukáš Kratochvíl's avatar Lukáš Kratochvíl
Browse files

Merge branch 'backend-api' into main

parents ba0ddc15 5c12b247
No related branches found
No related tags found
No related merge requests found
Showing
with 407 additions and 33 deletions
......@@ -63,12 +63,12 @@ To login to Adminer in your browser you need to specify:
| requirement |endpoint | method | criteria |
| ------------- | ------------- | ------------- | ------------- |
| Search for a movie | /movies | get | returns array of movies as a result of search
| Show a single movie | /movie/:id | get | return movie
| Show popular movies | /movie/preview | get | returns array of few movies (popular) to preview
| Show a single director | /director/:id | get | returns director
| Show all movies | /movies | get | returns array of movies as a result of search
| Show most recent movies | /movies?mostRecentCnt=$COUNT | get | returns array of $COUNT most recent movies
| Show a single movie | /movies/:id | get | returns movie
| Show a single director | /directors/:id | get | returns director
| Show categories to browse | /categories | get | returns all categories
| Show a single category | /category/:id | get | returns category with movies that belong to it
| Show a single category | /categories/:id | get | returns category with movies that belong to it
## TODO
......
......@@ -27,10 +27,8 @@ module.exports = {
'@typescript-eslint/comma-spacing': ['error', { 'before': false, 'after': true }],
'@typescript-eslint/default-param-last': ['error'],
'@typescript-eslint/dot-notation': ['error'],
'@typescript-eslint/indent': ['error', 2],
'@typescript-eslint/keyword-spacing': ['error', { 'before': true, 'after': true }],
'@typescript-eslint/no-empty-function': ['error'],
'@typescript-eslint/no-extra-parens': ['error'],
'@typescript-eslint/no-extra-semi': ['error'],
'@typescript-eslint/no-shadow': ['error'],
'@typescript-eslint/no-unused-expressions': ['error'],
......@@ -80,6 +78,8 @@ module.exports = {
'comma-spacing': 'off',
'comma-style': ['error', 'last'],
'func-call-spacing': ['error', 'never'],
'function-call-argument-newline': ['error', 'consistent'],
'function-paren-newline': ['error', 'consistent'],
'implicit-arrow-linebreak': ['error', 'beside'],
'indent': 'off',
'jsx-quotes': ['error', 'prefer-single'],
......
......@@ -8,6 +8,9 @@ ENV PATH=/usr/src/node_modules/.bin:$PATH
WORKDIR /usr/src/app
COPY prisma/schema.prisma ./prisma/
RUN npx prisma generate
COPY . .
CMD ["npm", "run", "build"]
backend/diagrams/movie_database.png

17.3 KiB

{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src"
"sourceRoot": "src",
"compilerOptions": {
"plugins": ["@nestjs/swagger"]
}
}
......@@ -12,12 +12,17 @@
"@nestjs/common": "^8.0.0",
"@nestjs/config": "^2.1.0",
"@nestjs/core": "^8.0.0",
"@nestjs/mapped-types": "^1.0.1",
"@nestjs/platform-express": "^8.0.0",
"@prisma/client": "^3.15.1",
"@nestjs/swagger": "^5.2.1",
"@prisma/client": "^3.15.2",
"class-transformer": "^0.4.0",
"class-validator": "^0.13.1",
"jshint": "^2.13.4",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
"rxjs": "^7.2.0",
"swagger-ui-express": "^4.4.0"
},
"devDependencies": {
"@nestjs/cli": "^8.0.0",
......@@ -34,7 +39,7 @@
"eslint-plugin-prettier": "^4.0.0",
"jest": "28.0.3",
"prettier": "^2.3.2",
"prisma": "^3.15.1",
"prisma": "^3.15.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "28.0.1",
......@@ -1598,6 +1603,25 @@
}
}
},
"node_modules/@nestjs/mapped-types": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.0.1.tgz",
"integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==",
"peerDependencies": {
"@nestjs/common": "^7.0.8 || ^8.0.0",
"class-transformer": "^0.2.0 || ^0.3.0 || ^0.4.0 || ^0.5.0",
"class-validator": "^0.11.1 || ^0.12.0 || ^0.13.0",
"reflect-metadata": "^0.1.12"
},
"peerDependenciesMeta": {
"class-transformer": {
"optional": true
},
"class-validator": {
"optional": true
}
}
},
"node_modules/@nestjs/platform-express": {
"version": "8.4.6",
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-8.4.6.tgz",
......@@ -1634,6 +1658,31 @@
"typescript": "^3.4.5 || ^4.3.5"
}
},
"node_modules/@nestjs/swagger": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-5.2.1.tgz",
"integrity": "sha512-7dNa08WCnTsW/oAk3Ujde+z64JMfNm19DhpXasFR8oJp/9pggYAbYU927HpA+GJsSFJX6adjIRZsCKUqaGWznw==",
"dependencies": {
"@nestjs/mapped-types": "1.0.1",
"lodash": "4.17.21",
"path-to-regexp": "3.2.0"
},
"peerDependencies": {
"@nestjs/common": "^8.0.0",
"@nestjs/core": "^8.0.0",
"fastify-swagger": "*",
"reflect-metadata": "^0.1.12",
"swagger-ui-express": "*"
},
"peerDependenciesMeta": {
"fastify-swagger": {
"optional": true
},
"swagger-ui-express": {
"optional": true
}
}
},
"node_modules/@nestjs/testing": {
"version": "8.4.6",
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.4.6.tgz",
......@@ -1729,9 +1778,9 @@
}
},
"node_modules/@prisma/client": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.15.1.tgz",
"integrity": "sha512-Lsk7oupvO9g99mrIs07iE6BIMouHs46Yq/YY8itTsUQNKfecsPuZvVYvcKci0pqRQ0neOpvIvoA/ouZmIMBCrQ==",
"version": "3.15.2",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.15.2.tgz",
"integrity": "sha512-ErqtwhX12ubPhU4d++30uFY/rPcyvjk+mdifaZO5SeM21zS3t4jQrscy8+6IyB0GIYshl5ldTq6JSBo1d63i8w==",
"hasInstallScript": true,
"dependencies": {
"@prisma/engines-version": "3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e"
......@@ -3066,6 +3115,20 @@
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
"dev": true
},
"node_modules/class-transformer": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz",
"integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA=="
},
"node_modules/class-validator": {
"version": "0.13.2",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.2.tgz",
"integrity": "sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw==",
"dependencies": {
"libphonenumber-js": "^1.9.43",
"validator": "^13.7.0"
}
},
"node_modules/cli": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
......@@ -6430,6 +6493,11 @@
"node": ">= 0.8.0"
}
},
"node_modules/libphonenumber-js": {
"version": "1.10.6",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.6.tgz",
"integrity": "sha512-CIjT100/SmntsUjsLVs2t3ufeN4KdNXUxhD07tH153pdbaCWuAjv0jK/gPuywR3IImB/U/MQM+x9RfhMs5XZiA=="
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
......@@ -7187,9 +7255,9 @@
}
},
"node_modules/prisma": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-3.15.1.tgz",
"integrity": "sha512-MLO3JUGJpe5+EVisA/i47+zlyF8Ug0ivvGYG4B9oSXQcPiUHB1ccmnpxqR7o0Up5SQgmxkBiEU//HgR6UuIKOw==",
"version": "3.15.2",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-3.15.2.tgz",
"integrity": "sha512-nMNSMZvtwrvoEQ/mui8L/aiCLZRCj5t6L3yujKpcDhIPk7garp8tL4nMx2+oYsN0FWBacevJhazfXAbV1kfBzA==",
"devOptional": true,
"hasInstallScript": true,
"dependencies": {
......@@ -8012,6 +8080,25 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/swagger-ui-dist": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.12.0.tgz",
"integrity": "sha512-B0Iy2ueXtbByE6OOyHTi3lFQkpPi/L7kFOKFeKTr44za7dJIELa9kzaca6GkndCgpK1QTjArnoXG+aUy0XQp1w=="
},
"node_modules/swagger-ui-express": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.4.0.tgz",
"integrity": "sha512-1CzRkHG386VQMVZK406jcpgnW2a9A5A/NiAjKhsFTQqUBWRF+uGbXTU/mA7WSV3mTzyOQDvjBdWP/c2qd5lqKw==",
"dependencies": {
"swagger-ui-dist": ">=4.11.0"
},
"engines": {
"node": ">= v0.10.32"
},
"peerDependencies": {
"express": ">=4.0.0"
}
},
"node_modules/symbol-observable": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
......@@ -8589,6 +8676,14 @@
"node": ">=10.12.0"
}
},
"node_modules/validator": {
"version": "13.7.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
"integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
......@@ -10088,6 +10183,12 @@
"uuid": "8.3.2"
}
},
"@nestjs/mapped-types": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.0.1.tgz",
"integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==",
"requires": {}
},
"@nestjs/platform-express": {
"version": "8.4.6",
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-8.4.6.tgz",
......@@ -10113,6 +10214,16 @@
"pluralize": "8.0.0"
}
},
"@nestjs/swagger": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-5.2.1.tgz",
"integrity": "sha512-7dNa08WCnTsW/oAk3Ujde+z64JMfNm19DhpXasFR8oJp/9pggYAbYU927HpA+GJsSFJX6adjIRZsCKUqaGWznw==",
"requires": {
"@nestjs/mapped-types": "1.0.1",
"lodash": "4.17.21",
"path-to-regexp": "3.2.0"
}
},
"@nestjs/testing": {
"version": "8.4.6",
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.4.6.tgz",
......@@ -10170,9 +10281,9 @@
}
},
"@prisma/client": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.15.1.tgz",
"integrity": "sha512-Lsk7oupvO9g99mrIs07iE6BIMouHs46Yq/YY8itTsUQNKfecsPuZvVYvcKci0pqRQ0neOpvIvoA/ouZmIMBCrQ==",
"version": "3.15.2",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.15.2.tgz",
"integrity": "sha512-ErqtwhX12ubPhU4d++30uFY/rPcyvjk+mdifaZO5SeM21zS3t4jQrscy8+6IyB0GIYshl5ldTq6JSBo1d63i8w==",
"requires": {
"@prisma/engines-version": "3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e"
}
......@@ -11223,6 +11334,20 @@
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
"dev": true
},
"class-transformer": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz",
"integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA=="
},
"class-validator": {
"version": "0.13.2",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.2.tgz",
"integrity": "sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw==",
"requires": {
"libphonenumber-js": "^1.9.43",
"validator": "^13.7.0"
}
},
"cli": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
......@@ -13786,6 +13911,11 @@
"type-check": "~0.4.0"
}
},
"libphonenumber-js": {
"version": "1.10.6",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.6.tgz",
"integrity": "sha512-CIjT100/SmntsUjsLVs2t3ufeN4KdNXUxhD07tH153pdbaCWuAjv0jK/gPuywR3IImB/U/MQM+x9RfhMs5XZiA=="
},
"lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
......@@ -14338,9 +14468,9 @@
}
},
"prisma": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-3.15.1.tgz",
"integrity": "sha512-MLO3JUGJpe5+EVisA/i47+zlyF8Ug0ivvGYG4B9oSXQcPiUHB1ccmnpxqR7o0Up5SQgmxkBiEU//HgR6UuIKOw==",
"version": "3.15.2",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-3.15.2.tgz",
"integrity": "sha512-nMNSMZvtwrvoEQ/mui8L/aiCLZRCj5t6L3yujKpcDhIPk7garp8tL4nMx2+oYsN0FWBacevJhazfXAbV1kfBzA==",
"devOptional": true,
"requires": {
"@prisma/engines": "3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e"
......@@ -14945,6 +15075,19 @@
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true
},
"swagger-ui-dist": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.12.0.tgz",
"integrity": "sha512-B0Iy2ueXtbByE6OOyHTi3lFQkpPi/L7kFOKFeKTr44za7dJIELa9kzaca6GkndCgpK1QTjArnoXG+aUy0XQp1w=="
},
"swagger-ui-express": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.4.0.tgz",
"integrity": "sha512-1CzRkHG386VQMVZK406jcpgnW2a9A5A/NiAjKhsFTQqUBWRF+uGbXTU/mA7WSV3mTzyOQDvjBdWP/c2qd5lqKw==",
"requires": {
"swagger-ui-dist": ">=4.11.0"
}
},
"symbol-observable": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
......@@ -15348,6 +15491,11 @@
"convert-source-map": "^1.6.0"
}
},
"validator": {
"version": "13.7.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
"integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
......
......@@ -24,12 +24,17 @@
"@nestjs/common": "^8.0.0",
"@nestjs/config": "^2.1.0",
"@nestjs/core": "^8.0.0",
"@nestjs/mapped-types": "^1.0.1",
"@nestjs/platform-express": "^8.0.0",
"@prisma/client": "^3.15.1",
"@nestjs/swagger": "^5.2.1",
"@prisma/client": "^3.15.2",
"class-transformer": "^0.4.0",
"class-validator": "^0.13.1",
"jshint": "^2.13.4",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
"rxjs": "^7.2.0",
"swagger-ui-express": "^4.4.0"
},
"devDependencies": {
"@nestjs/cli": "^8.0.0",
......@@ -46,7 +51,7 @@
"eslint-plugin-prettier": "^4.0.0",
"jest": "28.0.3",
"prettier": "^2.3.2",
"prisma": "^3.15.1",
"prisma": "^3.15.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "28.0.1",
......
backend/prisma/diagrams/movie_database.png

15.8 KiB

......@@ -2,13 +2,12 @@
entity Movie {
* id <<UUID>>
* id_director <<UUID>>
---
* name: String
* originalName: String
* intro: String
* picture: String
* published: Date
picture: String
* publishedAt: Number
* runTimeMinutes: Number
}
......@@ -20,8 +19,6 @@ entity Category {
entity MovieCategory {
* id <<UUID>>
* id_movie <<UUID>>
* id_category <<UUID>>
---
}
......@@ -30,7 +27,7 @@ entity Director {
---
* name: String
* surname: String
* birthDate: Date
birthDate: Date
}
Movie }|...|| Director
......
/*
Warnings:
- Changed the type of `publishedAt` on the `Movie` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
*/
-- AlterTable
ALTER TABLE "Movie" DROP COLUMN "publishedAt",
ADD COLUMN "publishedAt" INTEGER NOT NULL;
-- CreateIndex
CREATE UNIQUE INDEX "Movie_originalName_publishedAt_directorId_key" ON "Movie"("originalName", "publishedAt", "directorId");
......@@ -20,7 +20,7 @@ model Movie {
originalName String
intro String
picture String?
publishedAt DateTime
publishedAt Int
runTimeMinutes Int
director Director @relation(fields: [directorId], references: [id])
......
import { Test, TestingModule } from '@nestjs/testing';
import { CategoriesController } from './categories.controller';
import { CategoriesService } from './categories.service';
describe('CategoriesController', () => {
let controller: CategoriesController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [CategoriesController],
providers: [CategoriesService],
}).compile();
controller = module.get<CategoriesController>(CategoriesController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { CategoriesService } from './categories.service';
import { CreateCategoryDto } from './dto/create-category.dto';
import { UpdateCategoryDto } from './dto/update-category.dto';
import { CategoryEntity } from './entities/category.entity';
@ApiTags('categories')
@Controller('categories')
export class CategoriesController {
constructor(private readonly categoriesService: CategoriesService) {}
@Post()
async create(
@Body() createCategoryDto: CreateCategoryDto,
): Promise<CategoryEntity> {
return await this.categoriesService.create(createCategoryDto);
}
@Get()
async findAll(): Promise<CategoryEntity[]> {
return await this.categoriesService.findAll();
}
@Get(':id')
async findOne(@Param('id') id: string): Promise<CategoryEntity> {
return await this.categoriesService.findOne(id);
}
@Patch(':id')
async update(
@Param('id') id: string,
@Body() updateCategoryDto: UpdateCategoryDto,
): Promise<CategoryEntity> {
return await this.categoriesService.update(id, updateCategoryDto);
}
@Delete(':id')
async remove(@Param('id') id: string): Promise<CategoryEntity> {
return await this.categoriesService.remove(id);
}
}
import { Module } from '@nestjs/common';
import { CategoriesService } from './categories.service';
import { CategoriesController } from './categories.controller';
import { PrismaService } from 'src/prisma/prisma.service';
@Module({
controllers: [CategoriesController],
providers: [CategoriesService, PrismaService],
})
export class CategoriesModule {}
import { Test, TestingModule } from '@nestjs/testing';
import { CategoriesService } from './categories.service';
describe('CategoriesService', () => {
let service: CategoriesService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [CategoriesService],
}).compile();
service = module.get<CategoriesService>(CategoriesService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { CreateCategoryDto } from './dto/create-category.dto';
import { UpdateCategoryDto } from './dto/update-category.dto';
import { plainToClass } from 'class-transformer';
import { CategoryEntity } from './entities/category.entity';
import { Category } from '@prisma/client';
@Injectable()
export class CategoriesService {
constructor(private prisma: PrismaService) {}
async create(createCategoryDto: CreateCategoryDto): Promise<Category> {
const category = plainToClass(CategoryEntity, createCategoryDto);
return await this.prisma.category.create({
data: category,
});
}
async findAll(): Promise<Category[]> {
return await this.prisma.category.findMany();
}
async findOne(id: string): Promise<Category> {
return await this.prisma.category.findUnique({
where: {
id,
},
});
}
async update(
id: string,
updateCategoryDto: UpdateCategoryDto,
): Promise<Category> {
const updatedCategory = {
...(await this.findOne(id)),
...plainToClass(CategoryEntity, updateCategoryDto),
};
return await this.prisma.category.update({
where: {
id,
},
data: {
...updatedCategory,
},
});
}
async remove(id: string): Promise<Category> {
return await this.prisma.category.update({
where: {
id,
},
data: {
deletedAt: new Date(),
},
});
}
}
import { IsNotEmpty, IsString } from 'class-validator';
export class CreateCategoryDto {
@IsNotEmpty()
@IsString()
readonly name: string;
}
import { PartialType } from '@nestjs/swagger';
import { CreateCategoryDto } from './create-category.dto';
export class UpdateCategoryDto extends PartialType(CreateCategoryDto) {}
import { ApiHideProperty } from '@nestjs/swagger';
import { Category } from '@prisma/client';
export class CategoryEntity implements Category {
id: string;
@ApiHideProperty()
createdAt: Date;
@ApiHideProperty()
updatedAt: Date;
@ApiHideProperty()
deletedAt: Date;
name: string;
}
import { Test, TestingModule } from '@nestjs/testing';
import { DirectorsController } from './directors.controller';
import { DirectorsService } from './directors.service';
describe('DirectorsController', () => {
let controller: DirectorsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [DirectorsController],
providers: [DirectorsService],
}).compile();
controller = module.get<DirectorsController>(DirectorsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment