Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

This PR fixes the Ability to resolve with nothing issue #389

Merged
merged 13 commits into from
Jun 24, 2024
Merged
87 changes: 86 additions & 1 deletion plugins/async-node/core/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { expect, test } from "vitest";
import type { Node, InProgressState } from "@player-ui/player";
import { Player } from "@player-ui/player";
import { Player } from '@player-ui/player';
import { waitFor } from "@testing-library/react";
import { AsyncNodePlugin, AsyncNodePluginPlugin } from "./index";


const basicFRFWithActions = {
id: "test-flow",
views: [
Expand Down Expand Up @@ -37,6 +38,90 @@ const basicFRFWithActions = {
},
};

const asyncNodeTest = async (resolvedValue: any, expectedActionType: string) => {
const plugin = new AsyncNodePlugin({
plugins: [new AsyncNodePluginPlugin()]
});

let deferredResolve: ((value: any) => void) | undefined;

plugin.hooks.onAsyncNode.tap('test', async (node: Node.Node) => {
return new Promise((resolve) => {
deferredResolve = resolve;
});
});

let updateNumber = 0;

const player = new Player({ plugins: [plugin] });

player.hooks.viewController.tap('async-node-test', (vc) => {
vc.hooks.view.tap('async-node-test', (view) => {
view.hooks.onUpdate.tap('async-node-test', () => {
updateNumber++;
});
});
});

player.hooks.viewController.tap('async-node-test', (vc) => {
vc.hooks.view.tap('async-node-test', (view) => {
view.hooks.resolver.tap('async-node-test', () => {
updateNumber++;
brocollie08 marked this conversation as resolved.
Show resolved Hide resolved
});
});
});

player.start(basicFRFWithActions as any);

let view = (player.getState() as InProgressState).controllers.view.currentView
?.lastUpdate;

expect(view).toBeDefined();
expect(view?.actions[0].asset.type).toBe('action');
expect(view?.actions[1]).toBeUndefined();

await waitFor(() => {
expect(deferredResolve).toBeDefined();
});

// Consumer responds with null/undefined
if (deferredResolve) {
deferredResolve(resolvedValue);
}

await waitFor(() => {
expect(updateNumber).toBe(2);
});

view = (player.getState() as InProgressState).controllers.view.currentView
?.lastUpdate;

expect(view?.actions[0].asset.type).toBe('action');
sakuntala-motukuri marked this conversation as resolved.
Show resolved Hide resolved
expect(view?.actions[1]?.asset.type).toBe(expectedActionType);
sakuntala-motukuri marked this conversation as resolved.
Show resolved Hide resolved
expect(view?.actions[2]?.asset.type).toBe(expectedActionType);

await waitFor(() => {
expect(updateNumber).toBe(3);
brocollie08 marked this conversation as resolved.
Show resolved Hide resolved
});

view = (player.getState() as InProgressState).controllers.view.currentView
?.lastUpdate;

expect(view?.actions[0].asset.type).toBe('action');
expect(view?.actions[1]?.asset.type).toBe(expectedActionType);
sakuntala-motukuri marked this conversation as resolved.
Show resolved Hide resolved
expect(view?.actions[2]?.asset.type).toBe(expectedActionType);
expect(view?.actions[3]?.asset.type).toBe(expectedActionType);
expect(updateNumber).toBe(3); // Replace with the actual expected number of updates
};

test('should return current node view when the resolved node is null', async () => {
await asyncNodeTest(null, undefined);
});

test('should return current node view when the resolved node is undefined', async () => {
await asyncNodeTest(undefined, undefined);
});

test("replaces async nodes with provided node", async () => {
const plugin = new AsyncNodePlugin({
plugins: [new AsyncNodePluginPlugin()],
Expand Down
10 changes: 4 additions & 6 deletions plugins/async-node/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class AsyncNodePluginPlugin implements AsyncNodeViewPlugin {

name = "AsyncNode";

private resolvedMapping = new Map<string, Node.Node>();
private resolvedMapping = new Map<string, any>();

private currentView: ViewInstance | undefined;

Expand Down Expand Up @@ -167,10 +167,8 @@ export class AsyncNodePluginPlugin implements AsyncNodeViewPlugin {
? options.parseNode(result)
: undefined;

if (parsedNode) {
this.resolvedMapping.set(node.id, parsedNode);
view.updateAsync();
}
this.resolvedMapping.set(node.id, parsedNode);
view.updateAsync();
});

return node;
Expand All @@ -184,4 +182,4 @@ export class AsyncNodePluginPlugin implements AsyncNodeViewPlugin {
applyPlugin(asyncNodePlugin: AsyncNodePlugin): void {
this.basePlugin = asyncNodePlugin;
}
}
}