Skip to content

Commit

Permalink
feat: do not validate cloud flows
Browse files Browse the repository at this point in the history
  • Loading branch information
VojtechVidra committed Feb 23, 2024
1 parent 02bdbda commit ffa15a2
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 17 deletions.
17 changes: 17 additions & 0 deletions workspaces/e2e/tests/cloud/cloud.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/tests/reset.css" />
<link rel="stylesheet" href="/node_modules/@flows/js/css.min/flows.css" />
</head>
<body>
<div
style="background-color: grey; width: 20px; height: 20px; margin: 40px"
class="target"
></div>

<script type="module" src="./cloud.ts"></script>
</body>
</html>
26 changes: 26 additions & 0 deletions workspaces/e2e/tests/cloud/cloud.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect, test } from "@playwright/test";
import { invalidFlow, validFlow } from "./flow-mocks";

test("Should validate local flow", async ({ page }) => {
await page.route("**/sdk/flows?projectId=my-proj", (route) => route.fulfill({ json: [] }));
await page.goto("/cloud/cloud.html?validLocalFlow=true");
await expect(page.locator(".flows-tooltip")).toBeVisible();
await page.goto("/cloud/cloud.html?invalidLocalFlow=true");
await expect(page.locator(".flows-tooltip")).toBeHidden();
});

test("Should run valid cloud flow", async ({ page }) => {
await page.route("**/sdk/flows?projectId=my-proj", (route) =>
route.fulfill({ json: [validFlow] }),
);
await page.goto("/cloud/cloud.html");
await expect(page.locator(".flows-tooltip")).toBeVisible();
});

test("Should run invalid cloud flow", async ({ page }) => {
await page.route("**/sdk/flows?projectId=my-proj", (route) =>
route.fulfill({ json: [invalidFlow] }),
);
await page.goto("/cloud/cloud.html");
await expect(page.locator(".flows-tooltip")).toBeVisible();
});
15 changes: 15 additions & 0 deletions workspaces/e2e/tests/cloud/cloud.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { init } from "@flows/js";
import { invalidFlow, validFlow } from "./flow-mocks";

const validLocalFlow = new URLSearchParams(window.location.search).get("validLocalFlow") === "true";
const invalidLocalFlow =
new URLSearchParams(window.location.search).get("invalidLocalFlow") === "true";

const flows = [];
if (validLocalFlow) flows.push(validFlow);
if (invalidLocalFlow) flows.push(invalidFlow);

init({
projectId: "my-proj",
flows,
});
25 changes: 25 additions & 0 deletions workspaces/e2e/tests/cloud/flow-mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Flow } from "@flows/js";

export const validFlow: Flow = {
id: "valid-local-flow",
location: "/",
steps: [
{
title: "Hello",
targetElement: ".target",
},
],
};

export const invalidFlow: Flow = {
id: "invalid-local-flow",
location: "/",
steps: [
{
title: "Hello",
targetElement: ".target",
// @ts-ignore
invalidOption: "invalid",
},
],
};
5 changes: 3 additions & 2 deletions workspaces/js/src/cloud/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const init = async (options: FlowsCloudOptions): Promise<void> => {

return flowsInit({
...options,
validate: false,
flows: [...(options.flows ?? []), ...(flows || [])],
tracking: (event) => {
options.tracking?.(event);
Expand All @@ -69,7 +70,7 @@ export const init = async (options: FlowsCloudOptions): Promise<void> => {
void api(apiUrl)
.getPreviewFlow({ flowId, projectId })
.then((flow) => {
context.addFlowData({ ...flow, draft: true });
context.addFlowData({ ...flow, draft: true }, { validate: false });
startFlow(flow.id, { startDraft: true });
})
.catch((err) => {
Expand All @@ -80,7 +81,7 @@ export const init = async (options: FlowsCloudOptions): Promise<void> => {
void api(apiUrl)
.getFlowDetail({ flowId, projectId: options.projectId })
.then((flow) => {
context.addFlowData(flow);
context.addFlowData(flow, { validate: false });
})
.catch((err) => {
log.error("Failed to load flow detail", err);
Expand Down
19 changes: 11 additions & 8 deletions workspaces/js/src/core/flows-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,17 @@ export class FlowsContext {
return this;
};

addFlowData(flow: Flow): this {
const validationResult = validateFlow(flow);
if (validationResult.error)
log.error(
`Error validating flow at: flow.${validationResult.error.path.join(".")} with value:`,
validationResult.error.value,
);
if (!validationResult.valid) return this;
addFlowData(flow: Flow, { validate = true }: { validate?: boolean } = {}): this {
if (validate) {
const validationResult = validateFlow(flow);
if (validationResult.error)
log.error(
`Error validating flow at: flow.${validationResult.error.path.join(".")} with value:`,
validationResult.error.value,
);
if (!validationResult.valid) return this;
}

if (!this.flowsById) this.flowsById = {};
this.flowsById[flow.id] = flow;
this.startInstancesFromLocalStorage();
Expand Down
17 changes: 10 additions & 7 deletions workspaces/js/src/core/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ export const init = (options: FlowsInitOptions): Promise<void> =>
});

const _init = (options: FlowsInitOptions): void => {
const validationResult = validateFlowsOptions(options);
if (validationResult.error)
log.error(
`Error validating options at: options.${validationResult.error.path.join(".")} with value:`,
validationResult.error.value,
);
if (!validationResult.valid) return;
const validate = options.validate ?? true;
if (validate) {
const validationResult = validateFlowsOptions(options);
if (validationResult.error)
log.error(
`Error validating options at: options.${validationResult.error.path.join(".")} with value:`,
validationResult.error.value,
);
if (!validationResult.valid) return;
}

const context = FlowsContext.getInstance();
context.updateFromOptions(options);
Expand Down
5 changes: 5 additions & 0 deletions workspaces/js/src/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ export type FlowsInitOptions = FlowsOptions & {
projectId?: string;
onLocationChange?: (pathname: string, context: FlowsContext) => void;
onIncompleteFlowStart?: (flowId: string, context: FlowsContext) => void;
/**
* Validate options and flows before initializing.
* @defaultValue true
*/
validate?: boolean;
};

export interface StartFlowOptions {
Expand Down

0 comments on commit ffa15a2

Please sign in to comment.