From ffc260bba26ab53723cf81e870b31b67a159f988 Mon Sep 17 00:00:00 2001 From: yassinedorbozgithub Date: Fri, 10 Jan 2025 11:30:23 +0100 Subject: [PATCH] fix: implement dynamic create DTO for Block --- api/src/chat/dto/block.dto.ts | 5 +++ api/src/chat/repositories/block.repository.ts | 5 ++- api/src/chat/schemas/block.schema.ts | 40 +++++++++--------- api/src/chat/services/block.service.ts | 8 +++- .../i18n/services/translation.service.spec.ts | 1 + api/src/utils/test/fixtures/block.ts | 41 +++++++++++-------- api/src/utils/test/mocks/block.ts | 2 + 7 files changed, 62 insertions(+), 40 deletions(-) diff --git a/api/src/chat/dto/block.dto.ts b/api/src/chat/dto/block.dto.ts index 7892f424..16a5d9dc 100644 --- a/api/src/chat/dto/block.dto.ts +++ b/api/src/chat/dto/block.dto.ts @@ -21,6 +21,7 @@ import { IsString, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; import { CaptureVar } from '../schemas/types/capture-var'; @@ -146,3 +147,7 @@ export class BlockUpdateDto extends PartialType( @IsOptional() trigger_channels?: string[]; } + +export type BlockDTOMap = DtoConfig<{ + create: BlockCreateDto; +}>; diff --git a/api/src/chat/repositories/block.repository.ts b/api/src/chat/repositories/block.repository.ts index 31b0bacd..27bc42a6 100644 --- a/api/src/chat/repositories/block.repository.ts +++ b/api/src/chat/repositories/block.repository.ts @@ -22,7 +22,7 @@ import { LoggerService } from '@/logger/logger.service'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; -import { BlockCreateDto, BlockUpdateDto } from '../dto/block.dto'; +import { BlockCreateDto, BlockDTOMap, BlockUpdateDto } from '../dto/block.dto'; import { Block, BLOCK_POPULATE, @@ -34,7 +34,8 @@ import { export class BlockRepository extends BaseRepository< Block, BlockPopulate, - BlockFull + BlockFull, + BlockDTOMap > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/chat/schemas/block.schema.ts b/api/src/chat/schemas/block.schema.ts index ab9a0b7a..88d7c0bf 100644 --- a/api/src/chat/schemas/block.schema.ts +++ b/api/src/chat/schemas/block.schema.ts @@ -43,7 +43,7 @@ export class BlockStub extends BaseSchema { validate: isPatternList, default: [], }) - patterns?: Pattern[]; + patterns: Pattern[]; @Prop([ { @@ -52,7 +52,7 @@ export class BlockStub extends BaseSchema { default: [], }, ]) - trigger_labels?: unknown; + trigger_labels: unknown; @Prop([ { @@ -61,19 +61,19 @@ export class BlockStub extends BaseSchema { default: [], }, ]) - assign_labels?: unknown; + assign_labels: unknown; @Prop({ type: Object, default: [], }) - trigger_channels?: string[]; + trigger_channels: string[]; @Prop({ type: Object, default: {}, }) - options?: BlockOptions; + options: BlockOptions; @Prop({ type: Object, @@ -88,13 +88,13 @@ export class BlockStub extends BaseSchema { default: [], }, ]) - nextBlocks?: unknown; + nextBlocks: unknown; @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Block', }) - attachedBlock?: unknown; + attachedBlock: unknown; @Prop({ type: MongooseSchema.Types.ObjectId, @@ -106,14 +106,14 @@ export class BlockStub extends BaseSchema { type: Boolean, default: false, }) - starts_conversation?: boolean; + starts_conversation: boolean; @Prop({ type: Object, validate: isValidVarCapture, default: [], }) - capture_vars?: CaptureVar[]; + capture_vars: CaptureVar[]; @Prop({ type: Object, @@ -125,22 +125,22 @@ export class BlockStub extends BaseSchema { type: Boolean, default: false, }) - builtin?: boolean; + builtin: boolean; } @Schema({ timestamps: true }) export class Block extends BlockStub { - @Transform(({ obj }) => obj.trigger_labels?.map((elem) => elem.toString())) - trigger_labels?: string[]; + @Transform(({ obj }) => obj.trigger_labels.map((elem) => elem.toString())) + trigger_labels: string[]; - @Transform(({ obj }) => obj.assign_labels?.map((elem) => elem.toString())) - assign_labels?: string[]; + @Transform(({ obj }) => obj.assign_labels.map((elem) => elem.toString())) + assign_labels: string[]; - @Transform(({ obj }) => obj.nextBlocks?.map((elem) => elem.toString())) - nextBlocks?: string[]; + @Transform(({ obj }) => obj.nextBlocks.map((elem) => elem.toString())) + nextBlocks: string[]; @Transform(({ obj }) => obj.attachedBlock?.toString() || null) - attachedBlock?: string; + attachedBlock: string; @Transform(({ obj }) => obj.category.toString()) category: string; @@ -161,16 +161,16 @@ export class BlockFull extends BlockStub { assign_labels: Label[]; @Type(() => Block) - nextBlocks?: Block[]; + nextBlocks: Block[]; @Type(() => Block) - attachedBlock?: Block; + attachedBlock: Block; @Type(() => Category) category: Category; @Type(() => Block) - previousBlocks: Block[]; + previousBlocks?: Block[]; @Type(() => Block) attachedToBlock?: Block; diff --git a/api/src/chat/services/block.service.ts b/api/src/chat/services/block.service.ts index 131f45f5..98ef7e66 100644 --- a/api/src/chat/services/block.service.ts +++ b/api/src/chat/services/block.service.ts @@ -22,6 +22,7 @@ import { SettingService } from '@/setting/services/setting.service'; import { BaseService } from '@/utils/generics/base-service'; import { getRandom } from '@/utils/helpers/safeRandom'; +import { BlockDTOMap } from '../dto/block.dto'; import { BlockRepository } from '../repositories/block.repository'; import { Block, BlockFull, BlockPopulate } from '../schemas/block.schema'; import { Context } from '../schemas/types/context'; @@ -35,7 +36,12 @@ import { Payload, StdQuickReply } from '../schemas/types/quick-reply'; import { SubscriberContext } from '../schemas/types/subscriberContext'; @Injectable() -export class BlockService extends BaseService { +export class BlockService extends BaseService< + Block, + BlockPopulate, + BlockFull, + BlockDTOMap +> { constructor( readonly repository: BlockRepository, private readonly contentService: ContentService, diff --git a/api/src/i18n/services/translation.service.spec.ts b/api/src/i18n/services/translation.service.spec.ts index 5f0d6bb4..1667a1e8 100644 --- a/api/src/i18n/services/translation.service.spec.ts +++ b/api/src/i18n/services/translation.service.spec.ts @@ -154,6 +154,7 @@ describe('TranslationService', () => { }, }, options: {}, + attachedBlock: null, }; const mockedPlugin: any = { diff --git a/api/src/utils/test/fixtures/block.ts b/api/src/utils/test/fixtures/block.ts index b66611ce..0ddd537b 100644 --- a/api/src/utils/test/fixtures/block.ts +++ b/api/src/utils/test/fixtures/block.ts @@ -8,17 +8,35 @@ import mongoose from 'mongoose'; -import { BlockCreateDto } from '@/chat/dto/block.dto'; -import { BlockModel, Block } from '@/chat/schemas/block.schema'; +import { Block, BlockModel } from '@/chat/schemas/block.schema'; import { CategoryModel } from '@/chat/schemas/category.schema'; import { FileType } from '@/chat/schemas/types/attachment'; import { ButtonType } from '@/chat/schemas/types/button'; import { QuickReplyType } from '@/chat/schemas/types/quick-reply'; +import { BaseSchema } from '@/utils/generics/base-schema'; import { getFixturesWithDefaultValues } from '../defaultValues'; -import { TFixturesDefaultValues } from '../types'; -export const blocks: BlockCreateDto[] = [ +export const fieldsWithDefaultValues = { + options: {}, + nextBlocks: [], + capture_vars: [], + assign_labels: [], + trigger_labels: [], + builtin: false, + starts_conversation: false, + attachedBlock: null, + attachedToBlock: null, +} satisfies Partial; + +type TFieldWithDefaultValues = + | keyof typeof fieldsWithDefaultValues + | keyof BaseSchema; +type TTransformedField = Omit & + Partial>; +type TBlock = TTransformedField; + +export const blocks: TBlock[] = [ { name: 'hasNextBlocks', patterns: ['Hi'], @@ -163,20 +181,9 @@ export const blocks: BlockCreateDto[] = [ }, ]; -export const blockDefaultValues: TFixturesDefaultValues = { - options: {}, - builtin: false, - nextBlocks: [], - capture_vars: [], - assign_labels: [], - trigger_labels: [], - starts_conversation: false, - attachedToBlock: null, -}; - -export const blockFixtures = getFixturesWithDefaultValues({ +export const blockFixtures = getFixturesWithDefaultValues({ fixtures: blocks, - defaultValues: blockDefaultValues, + defaultValues: fieldsWithDefaultValues, }); export const installBlockFixtures = async () => { diff --git a/api/src/utils/test/mocks/block.ts b/api/src/utils/test/mocks/block.ts index 1c8d3c58..4a9da2cc 100644 --- a/api/src/utils/test/mocks/block.ts +++ b/api/src/utils/test/mocks/block.ts @@ -95,6 +95,7 @@ export const baseBlockInstance = { category: undefined, previousBlocks: [], trigger_channels: [], + nextBlocks: [], ...modelInstance, }; @@ -103,6 +104,7 @@ export const blockEmpty: BlockFull = { name: 'Empty', patterns: [], message: [''], + nextBlocks: [], }; // Translation Data