Skip to content

Commit

Permalink
fix(framework): Stop validating controls for non previewed step (#6876)
Browse files Browse the repository at this point in the history
  • Loading branch information
rifont authored Nov 7, 2024
1 parent 0238e2b commit f6ed024
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 12 deletions.
69 changes: 68 additions & 1 deletion packages/framework/src/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,15 @@ describe('Novu Client', () => {
workflowId: 'test-workflow',
stepId: 'active-step-id',
subscriber: {},
state: [],
state: [
{
stepId: 'skipped-step-id',
outputs: {},
state: {
status: 'success',
},
},
],
payload: {},
controls: {},
};
Expand Down Expand Up @@ -1434,6 +1442,65 @@ describe('Novu Client', () => {
expect(metadata.duration).toEqual(expect.any(Number));
});

it('should preview a non-first step in a workflow successfully when action is preview', async () => {
const newWorkflow = workflow('test-workflow', async ({ step }) => {
await step.delay(
'delay-step',
async (controls) => ({
amount: controls.amount,
unit: controls.unit,
}),
{
controlSchema: {
type: 'object',
properties: {
amount: { type: 'number' },
unit: {
type: 'string',
enum: ['seconds', 'minutes', 'hours', 'days', 'weeks', 'months'],
},
},
required: ['amount', 'unit'],
additionalProperties: false,
} as const,
}
);

await step.inApp('send-in-app', async () => ({ body: 'Test Body', subject: 'Subject' }));
});

client.addWorkflows([newWorkflow]);

const event: Event = {
action: PostActionEnum.PREVIEW,
workflowId: 'test-workflow',
stepId: 'send-in-app',
subscriber: {},
state: [],
payload: {},
controls: {},
};

const executionResult = await client.executeWorkflow(event);

expect(executionResult).toBeDefined();
expect(executionResult.outputs).toBeDefined();
if (!executionResult.outputs) throw new Error('executionResult.outputs is undefined');

const { body } = executionResult.outputs;
expect(body).toBe('Test Body');

const { subject } = executionResult.outputs;
expect(subject).toBe('Subject');

expect(executionResult.providers).toEqual({});

const { metadata } = executionResult;
expect(metadata.status).toBe('success');
expect(metadata.error).toBe(false);
expect(metadata.duration).toEqual(expect.any(Number));
});

it('should preview workflow successfully when action is preview and skipped', async () => {
const newWorkflow = workflow('test-workflow', async ({ step }) => {
await step.email('send-email', async () => ({ body: 'Test Body', subject: 'Subject' }), {
Expand Down
24 changes: 13 additions & 11 deletions packages/framework/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,25 +278,27 @@ export class Client {
}

const step = this.getStep(event.workflowId, stepId);
const controls = await this.createStepControls(step, event);
const isPreview = event.action === PostActionEnum.PREVIEW;

if (!isPreview && (await this.shouldSkip(options?.skip as typeof step.options.skip, controls))) {
if (stepId === event.stepId) {
// Only set the result when the step is the current step.
// Only evaluate a skip condition when the step is the current step and not in preview mode.
if (!isPreview && stepId === event.stepId) {
const controls = await this.createStepControls(step, event);
const shouldSkip = await this.shouldSkip(options?.skip as typeof step.options.skip, controls);

if (shouldSkip) {
setResult({
options: { skip: true },
outputs: {},
providers: {},
});
}

/*
* Return an empty object for results when a step is skipped.
* TODO: fix typings when `skip` is specified to return `Partial<T_Result>`
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return {} as any;
/*
* Return an empty object for results when a step is skipped.
* TODO: fix typings when `skip` is specified to return `Partial<T_Result>`
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return {} as any;
}
}

const previewStepHandler = this.previewStep.bind(this);
Expand Down

0 comments on commit f6ed024

Please sign in to comment.