Skip to content

Commit

Permalink
fix(api): Preserve control values across syncs
Browse files Browse the repository at this point in the history
Syncing the same workflow multiple times overrides control values set in the Dashboard. This PR fixes it.
  • Loading branch information
SokratisVidros committed Nov 1, 2024
1 parent b0b97f3 commit 961c7ac
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 5 deletions.
5 changes: 2 additions & 3 deletions apps/api/src/app/bridge/usecases/sync/sync.usecase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ export class Sync {
commandWorkflowSteps: DiscoverStepOutput[],
workflow?: NotificationTemplateEntity | undefined
): NotificationStep[] {
const steps: NotificationStep[] = commandWorkflowSteps.map((step) => {
return commandWorkflowSteps.map((step) => {
const foundStep = workflow?.steps?.find((workflowStep) => workflowStep.stepId === step.stepId);

const template = {
Expand All @@ -273,11 +273,10 @@ export class Sync {
name: step.stepId,
stepId: step.stepId,
uuid: step.stepId,
_templateId: foundStep?._templateId,
shouldStopOnFail: this.castToAnyNotSupportedParam(step.options)?.failOnErrorEnabled ?? false,
};
});

return steps;
}

private async getNotificationGroup(
Expand Down
95 changes: 93 additions & 2 deletions apps/api/src/app/events/e2e/bridge-sync.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { UserSession } from '@novu/testing';
import { expect } from 'chai';
import { EnvironmentRepository, NotificationTemplateRepository, MessageTemplateRepository } from '@novu/dal';
import { FeatureFlagsKeysEnum, WorkflowTypeEnum } from '@novu/shared';
import {
EnvironmentRepository,
NotificationTemplateRepository,
MessageTemplateRepository,
ControlValuesRepository,
} from '@novu/dal';
import { WorkflowTypeEnum } from '@novu/shared';
import { workflow } from '@novu/framework';
import { BridgeServer } from '../../../../e2e/bridge.server';

Expand All @@ -10,6 +15,7 @@ describe('Bridge Sync - /bridge/sync (POST)', async () => {
const environmentRepository = new EnvironmentRepository();
const workflowsRepository = new NotificationTemplateRepository();
const messageTemplateRepository = new MessageTemplateRepository();
const controlValuesRepository = new ControlValuesRepository();

const inputPostPayload = {
schema: {
Expand Down Expand Up @@ -553,4 +559,89 @@ describe('Bridge Sync - /bridge/sync (POST)', async () => {
const workflowDataWithName = workflowsWithDescription[0];
expect(workflowDataWithName.description).to.equal('');
});

it('should preserve control values across workflow syncs', async () => {
const workflowId = 'My Workflow';
const spaceSeparatedIdWorkflow = workflow(workflowId, async ({ step }) => {
await step.email('send-email', () => ({
subject: 'Welcome!',
body: 'Hello there',
}));
});
await bridgeServer.start({ workflows: [spaceSeparatedIdWorkflow] });

const firstSyncResponse = await session.testAgent.post(`/v1/bridge/sync`).send({
bridgeUrl: bridgeServer.serverPath,
});
expect(firstSyncResponse.body.data?.length).to.equal(1);

const firstWorkflowCountResponse = await workflowsRepository.count({ _environmentId: session.environment._id });
expect(firstWorkflowCountResponse).to.equal(1);

const firstWorkflowResponse = await workflowsRepository.findById(
firstSyncResponse.body.data[0]._id,
session.environment._id
);

expect(firstWorkflowResponse).to.be.ok;
if (!firstWorkflowResponse) {
throw new Error('Workflow not found');
}

expect(firstWorkflowResponse.name).to.equal(workflowId);
expect(firstWorkflowResponse.type).to.equal(WorkflowTypeEnum.BRIDGE);
expect(firstWorkflowResponse.rawData.workflowId).to.equal(workflowId);
expect(firstWorkflowResponse.triggers[0].identifier).to.equal(workflowId);

expect(firstWorkflowResponse.steps.length).to.equal(1);
expect(firstWorkflowResponse.steps[0].stepId).to.equal('send-email');
expect(firstWorkflowResponse.steps[0]._templateId).to.exist;

await session.testAgent.put(`/v1/bridge/controls/${workflowId}/send-email`).send({
variables: { subject: 'Hello World again' },
});

const firstControlValueResponse = await controlValuesRepository.find({
_environmentId: session.environment._id,
_workflowId: firstWorkflowResponse._id,
});

expect(firstControlValueResponse.length).to.equal(1);
expect(firstControlValueResponse[0].controls.subject).to.equal('Hello World again');

const secondSyncResponse = await session.testAgent.post(`/v1/bridge/sync`).send({
bridgeUrl: bridgeServer.serverPath,
});
expect(secondSyncResponse.body.data?.length).to.equal(1);

const secondWorkflowCountResponse = await workflowsRepository.count({ _environmentId: session.environment._id });
expect(secondWorkflowCountResponse).to.equal(1);

const secondWorkflowResponse = await workflowsRepository.findById(
firstSyncResponse.body.data[0]._id,
session.environment._id
);

expect(secondWorkflowResponse).to.be.ok;
if (!secondWorkflowResponse) {
throw new Error('Workflow not found');
}

expect(secondWorkflowResponse.name).to.equal(workflowId);
expect(secondWorkflowResponse.type).to.equal(WorkflowTypeEnum.BRIDGE);
expect(secondWorkflowResponse.rawData.workflowId).to.equal(workflowId);
expect(secondWorkflowResponse.triggers[0].identifier).to.equal(workflowId);

expect(secondWorkflowResponse.steps.length).to.equal(1);
expect(secondWorkflowResponse.steps[0].stepId).to.equal('send-email');
expect(secondWorkflowResponse.steps[0]._templateId).to.exist;

const secondControlValueResponse = await controlValuesRepository.find({
_environmentId: session.environment._id,
_workflowId: secondWorkflowResponse._id,
});

expect(secondControlValueResponse.length).to.equal(1);
expect(secondControlValueResponse[0].controls.subject).to.equal('Hello World again');
});
});

0 comments on commit 961c7ac

Please sign in to comment.