From 0465f06a3408676e6decf6d8f2bf8408f1e58872 Mon Sep 17 00:00:00 2001 From: GalT <39020298+tatarco@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:36:31 +0100 Subject: [PATCH] bug(api): steps working --- .../shared/map-step-type-to-result.mapper.ts | 7 +- ...ailable-variable-schema-usecase.service.ts | 5 + .../usecases/test-data/test-data.usecase.ts | 2 +- .../workflows-v2/workflow.controller.e2e.ts | 118 +++++++++--------- 4 files changed, 72 insertions(+), 60 deletions(-) diff --git a/apps/api/src/app/workflows-v2/shared/map-step-type-to-result.mapper.ts b/apps/api/src/app/workflows-v2/shared/map-step-type-to-result.mapper.ts index 101b457d5bbe..0061e25a42f7 100644 --- a/apps/api/src/app/workflows-v2/shared/map-step-type-to-result.mapper.ts +++ b/apps/api/src/app/workflows-v2/shared/map-step-type-to-result.mapper.ts @@ -3,6 +3,8 @@ import { JSONSchema } from 'json-schema-to-ts'; import { StepTypeEnum } from '@novu/shared'; export function computeResultSchema(stepType: StepTypeEnum, payloadSchema?: JSONSchema) { + console.log('computeResultSchema:stepType', stepType); + console.log('computeResultSchema:payloadSchema', payloadSchema); const mapStepTypeToResult: Record = { [ChannelStepEnum.SMS]: channelStepSchemas[ChannelStepEnum.SMS].result, [ChannelStepEnum.EMAIL]: channelStepSchemas[ChannelStepEnum.EMAIL].result, @@ -13,7 +15,10 @@ export function computeResultSchema(stepType: StepTypeEnum, payloadSchema?: JSON [ActionStepEnum.DIGEST]: buildDigestResult(payloadSchema), }; - return mapStepTypeToResult[stepType]; + const mapStepTypeToResultElement = mapStepTypeToResult[stepType]; + console.log('mapStepTypeToResultElement', JSON.stringify(mapStepTypeToResultElement, null, 2)); + + return mapStepTypeToResultElement; } function buildDigestResult(payloadSchema?: JSONSchema) { diff --git a/apps/api/src/app/workflows-v2/usecases/get-step-schema/build-available-variable-schema-usecase.service.ts b/apps/api/src/app/workflows-v2/usecases/get-step-schema/build-available-variable-schema-usecase.service.ts index d508c30a7b0b..6ef802dfafd2 100644 --- a/apps/api/src/app/workflows-v2/usecases/get-step-schema/build-available-variable-schema-usecase.service.ts +++ b/apps/api/src/app/workflows-v2/usecases/get-step-schema/build-available-variable-schema-usecase.service.ts @@ -13,6 +13,9 @@ class BuildAvailableVariableSchemaCommand { export class BuildAvailableVariableSchemaUsecase { execute(command: BuildAvailableVariableSchemaCommand): JSONSchema { const { previousSteps, payloadSchema } = command; + console.log('Building available variable schema'); + console.log('previousSteps', JSON.stringify(previousSteps)); + console.log('payloadSchema', JSON.stringify(payloadSchema, null, 2)); return { type: 'object', @@ -32,6 +35,8 @@ function buildPreviousStepsSchema(previousSteps: NotificationStepEntity[] | unde previousStepsProperties = (previousSteps || []).reduce( (acc, step) => { if (step.stepId && step.template?.type) { + console.log('Building schema for step:id', step.stepId); + console.log('Building schema for step:type', step.template?.type); acc[step.stepId] = computeResultSchema(step.template.type, payloadSchema); } diff --git a/apps/api/src/app/workflows-v2/usecases/test-data/test-data.usecase.ts b/apps/api/src/app/workflows-v2/usecases/test-data/test-data.usecase.ts index 9262c9182251..ff456aff311e 100644 --- a/apps/api/src/app/workflows-v2/usecases/test-data/test-data.usecase.ts +++ b/apps/api/src/app/workflows-v2/usecases/test-data/test-data.usecase.ts @@ -54,7 +54,7 @@ export class WorkflowTestDataUseCase { payloadExampleForWorkflow = { ...payloadExampleForWorkflow, ...payloadExampleForStep }; } - return jsonToSchema(payloadExampleForWorkflow || {}) as JSONSchemaDto; + return jsonToSchema(payloadExampleForWorkflow || {}) as unknown as JSONSchemaDto; } private async getValues(user: UserSessionData, _stepId: string, _workflowId: string) { diff --git a/apps/api/src/app/workflows-v2/workflow.controller.e2e.ts b/apps/api/src/app/workflows-v2/workflow.controller.e2e.ts index 2acbe6f8dc89..2ace86deb8dc 100644 --- a/apps/api/src/app/workflows-v2/workflow.controller.e2e.ts +++ b/apps/api/src/app/workflows-v2/workflow.controller.e2e.ts @@ -30,7 +30,6 @@ import { WorkflowResponseDto, WorkflowStatusEnum, } from '@novu/shared'; - import { encodeBase62 } from '../shared/helpers'; import { stepTypeToDefaultDashboardControlSchema } from './shared'; import { getTestControlValues } from './generate-preview.e2e'; @@ -441,8 +440,8 @@ describe('Workflow Controller E2E API Testing', () => { }); }); - describe('Get Steps Permutations', () => { - it('should get by worflow slugify ids', async () => { + describe('Get Step Data Permutations', () => { + it('should get step by worflow slugify ids', async () => { const workflowCreated = await createWorkflowAndValidate('XYZ'); const internalWorkflowId = workflowCreated._id; const stepId = workflowCreated.steps[0]._id; @@ -463,7 +462,7 @@ describe('Workflow Controller E2E API Testing', () => { expect(stepRetrievedByWorkflowIdentifier._id).to.equal(stepId); }); - it('should get by step slugify ids', async () => { + it('should get step by step slugify ids', async () => { const workflowCreated = await createWorkflowAndValidate('XYZ'); const internalWorkflowId = workflowCreated._id; const stepId = workflowCreated.steps[0]._id; @@ -483,8 +482,9 @@ describe('Workflow Controller E2E API Testing', () => { const stepRetrievedByStepIdentifier = await getStepData(internalWorkflowId, stepIdentifier); expect(stepRetrievedByStepIdentifier._id).to.equal(stepId); }); - - it('should get step payload variables', async () => { + }); + describe('Variables', () => { + it('should get step available variables', async () => { const steps = [ { ...buildEmailStep(), @@ -521,8 +521,6 @@ describe('Workflow Controller E2E API Testing', () => { }, }); }); - }); - describe('Variables', () => { it('should serve previous step variables with payload schema', async () => { const steps = [ buildDigestStep(), @@ -538,58 +536,13 @@ describe('Workflow Controller E2E API Testing', () => { throw new Error(novuRestResult.error!.responseText); } const { variables } = novuRestResult.value; + const variableList = getJsonSchemaPrimitiveProperties(variables as JSONSchemaDto); + console.log(variableList); + const hasStepVariables = variableList.some((variable) => variable.startsWith('steps.')); + expect(hasStepVariables, JSON.stringify(variableList)).to.be.true; }); }); - function getJsonSchemaPrimitiveProperties( - schema: JSONSchemaDto | JSONSchemaDefinition[] | boolean, - prefix: string = '' - ): string[] { - if (!isJSONSchemaDto(schema)) { - return []; - } - let properties: string[] = []; - // Check if the schema has properties - if (schema.properties) { - // eslint-disable-next-line guard-for-in - for (const key in schema.properties) { - const propertySchema = schema.properties[key]; - if (!isJSONSchemaDto(propertySchema)) { - continue; - } - const propertyPath = prefix ? `${prefix}.${key}` : key; - - // Check if the property type is primitive - if (isPrimitiveType(propertySchema)) { - properties.push(propertyPath); - } else { - // If not primitive, recurse into the object - properties = properties.concat(getJsonSchemaPrimitiveProperties(propertySchema, propertyPath)); - } - } - } - - // Check if the schema has items (for arrays) - if (schema.items && isJSONSchemaDto(schema.items)) { - // Assuming items is an object schema, we can treat it like a property - if (isPrimitiveType(schema.items)) { - properties.push(prefix); // If items are primitive, add the array itself - } else { - properties = properties.concat(getJsonSchemaPrimitiveProperties(schema.items, prefix)); - } - } - - return properties; - } - function isJSONSchemaDto(obj: any): obj is JSONSchemaDto { - // Check if the object has a 'type' property and is of type 'string' - return typeof obj === 'object' && obj !== null && typeof obj.type === 'string'; - } - function isPrimitiveType(schema: JSONSchemaDto): boolean { - const primitiveTypes = ['string', 'number', 'boolean', 'null']; - - return primitiveTypes.includes((schema.type && (schema.type as string)) || ''); - } describe('Get Test Data Permutations', () => { it('should get test data', async () => { const steps = [ @@ -861,6 +814,55 @@ describe('Workflow Controller E2E API Testing', () => { assertWorkflowResponseBodyData(workflowResponseDto); assertStepResponse(workflowResponseDto, createWorkflowDto); } + function getJsonSchemaPrimitiveProperties( + schema: JSONSchemaDto | JSONSchemaDefinition[] | boolean, + prefix: string = '' + ): string[] { + if (!isJSONSchemaDto(schema)) { + return []; + } + let properties: string[] = []; + // Check if the schema has properties + if (schema.properties) { + // eslint-disable-next-line guard-for-in + for (const key in schema.properties) { + const propertySchema = schema.properties[key]; + if (!isJSONSchemaDto(propertySchema)) { + continue; + } + const propertyPath = prefix ? `${prefix}.${key}` : key; + + // Check if the property type is primitive + if (isPrimitiveType(propertySchema)) { + properties.push(propertyPath); + } else { + // If not primitive, recurse into the object + properties = properties.concat(getJsonSchemaPrimitiveProperties(propertySchema, propertyPath)); + } + } + } + + // Check if the schema has items (for arrays) + if (schema.items && isJSONSchemaDto(schema.items)) { + // Assuming items is an object schema, we can treat it like a property + if (isPrimitiveType(schema.items)) { + properties.push(prefix); // If items are primitive, add the array itself + } else { + properties = properties.concat(getJsonSchemaPrimitiveProperties(schema.items, prefix)); + } + } + + return properties; + } + function isJSONSchemaDto(obj: any): obj is JSONSchemaDto { + // Check if the object has a 'type' property and is of type 'string' + return typeof obj === 'object' && obj !== null && typeof obj.type === 'string'; + } + function isPrimitiveType(schema: JSONSchemaDto): boolean { + const primitiveTypes = ['string', 'number', 'boolean', 'null']; + + return primitiveTypes.includes((schema.type && (schema.type as string)) || ''); + } }); function buildEmailStep(): StepCreateDto { @@ -873,7 +875,7 @@ function buildEmailStep(): StepCreateDto { function buildDigestStep(): StepCreateDto { return { name: 'Digest Test Step', - type: StepTypeEnum.EMAIL, + type: StepTypeEnum.DIGEST, controlValues: getTestControlValues()[StepTypeEnum.DIGEST], }; }