PromucFlow_constructor/app/client/src/utils/CustomWidgetBuilderService.test.ts
balajisoundar 55191cb372
fix: [custom widget] remove stale keys from dynamicTriggerPathList (#31586)
## Description
1. Improve string pattern used to determine whether to show onReady
function missing warning
2. Remove stale keys from dynamicTriggerPathList when user changes the
event names
3. Clean up events when a custom widget unselected in editor

Fixes https://github.com/appsmithorg/appsmith/issues/31682
Fixes https://github.com/appsmithorg/appsmith/issues/30276
Fixes https://github.com/appsmithorg/appsmith/issues/30204

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!IMPORTANT]  
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/8337490694>
> Commit: `4fcb4cab6960c9a4a459a2b97261a112363901e2`
> Cypress dashboard url: <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=8337490694&attempt=1"
target="_blank">Click here!</a>
> All cypress tests have passed 🎉🎉🎉

<!-- end of auto-generated comment: Cypress test results  -->







<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit


- **New Features**
- Introduced a new route for `CustomWidgetBuilderLoader` component,
enhancing navigation and accessibility.
- Enhanced the Custom Widget Builder with improved event handling and
dynamic trigger path support.
- Added a new styled `Container` for the Custom Widget component for
better layout management.
- **Refactor**
- Improved configuration settings readability and consistency for New
Relic integration.
- Refactored `CustomWidgetBuilderService` for clearer modularity and
enhanced message handling.
- Optimized property editing and update logic within the Property Pane
of the Editor.
- **Bug Fixes**
- Adjusted connection timeout in the Custom Widget Builder for a more
responsive user experience.
	- Updated button sizes in the ConfirmationModal for consistency.
- **Tests**
- Added comprehensive test cases for `CustomWidgetBuilderService` and
`Builder` classes.
- **Chores**
- Removed deprecated `UPDATE_SRCDOC_ACK` event, streamlining Custom
Widget Builder events.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-03-20 14:31:03 +05:30

208 lines
5.0 KiB
TypeScript

import CustomWidgetBuilderService, {
Builder,
} from "./CustomWidgetBuilderService";
const onMessage = jest.fn();
const postMessage = jest.fn();
const isConnected = jest.fn();
const focus = jest.fn();
const close = jest.fn();
const mockBuilder = jest.fn().mockImplementation(() => {
return {
onMessage,
postMessage,
isConnected,
focus,
close,
};
});
describe("CustomWidgetBuilderService - ", () => {
beforeAll(() => {
CustomWidgetBuilderService.setBuilderFactory(mockBuilder);
});
describe("createBuilder", () => {
it("should test that its creating a builder", () => {
const widgetId = "123";
const builder = CustomWidgetBuilderService.createBuilder(widgetId);
expect(builder).toBeDefined();
expect(mockBuilder).toHaveBeenCalled();
});
});
describe("isConnected", () => {
it("should test that its checking if the builder is connected", () => {
const widgetId = "123";
CustomWidgetBuilderService.createBuilder(widgetId);
isConnected.mockReturnValue(false);
expect(CustomWidgetBuilderService.isConnected(widgetId)).toBeFalsy();
isConnected.mockReturnValue(true);
expect(CustomWidgetBuilderService.isConnected(widgetId)).toBeTruthy();
});
});
describe("focus", () => {
it("should test that its focusing the builder", () => {
const widgetId = "123";
CustomWidgetBuilderService.createBuilder(widgetId);
CustomWidgetBuilderService.focus(widgetId);
expect(focus).toHaveBeenCalled();
});
});
describe("closeBuilder", () => {
it("should test that its closing the builder", () => {
const widgetId = "123";
CustomWidgetBuilderService.createBuilder(widgetId);
expect(CustomWidgetBuilderService.getBuilder(widgetId)).toBeDefined();
CustomWidgetBuilderService.closeBuilder(widgetId, true);
expect(close).toHaveBeenCalled();
expect(CustomWidgetBuilderService.getBuilder(widgetId)).not.toBeDefined();
});
});
});
describe("Builder - ", () => {
let builder: Builder;
let closed = false;
const closeWindow = jest.fn().mockImplementation(() => {
if (builder?.builderWindow) {
(builder.builderWindow as any).closed = true;
}
});
const focus = jest.fn();
const open = jest.fn().mockImplementation(() => {
closed = false;
return { postMessage, close: closeWindow, closed, focus };
});
const addEventListener = jest.fn();
const removeEventListener = jest.fn();
beforeAll(() => {
window.open = open;
window.addEventListener = addEventListener;
window.removeEventListener = removeEventListener;
});
describe("constructor", () => {
it("should test that its creating a builder", () => {
builder = new Builder();
expect(builder).toBeDefined();
expect(open).toHaveBeenCalled();
expect(addEventListener).toHaveBeenCalled();
});
});
describe("onMessage", () => {
it("should test that its adding a message listener", () => {
const type = "READY";
const callback = jest.fn();
const callback2 = jest.fn();
const cancel = builder.onMessage(type, callback);
const listener = builder.onMessageMap.get(type);
expect(listener).toBeDefined();
expect(listener?.length).toBe(1);
expect(listener?.[0]).toEqual(callback);
const cancel2 = builder.onMessage(type, callback2);
expect(listener?.length).toBe(2);
expect(listener?.[1]).toEqual(callback2);
cancel();
expect(listener?.length).toBe(1);
expect(listener?.[0]).toEqual(callback2);
cancel2();
expect(listener?.length).toBe(0);
});
});
describe("postMessage", () => {
it("should test that its posting a message", () => {
const message = "Hello World";
builder.postMessage(message);
expect(postMessage).toHaveBeenCalledWith(message, "*");
});
});
describe("isConnected", () => {
it("should test that its checking if the builder is connected", () => {
expect(builder.isConnected()).toBeTruthy();
builder.close(true);
expect(builder.isConnected()).toBeFalsy();
});
});
describe("focus", () => {
it("should test that its focusing the builder", () => {
builder.focus();
expect(focus).toHaveBeenCalled();
});
});
describe("close", () => {
it("should test that its closing the builder", () => {
let handler;
window.addEventListener = ((type: string, fn: () => void) => {
handler = fn;
}) as typeof window.addEventListener;
const builder = new Builder();
builder.close(true);
expect(closeWindow).toHaveBeenCalled();
expect(removeEventListener).toHaveBeenCalledWith("message", handler);
});
it("should test that its not closing the builder when false is passed to close function", () => {
closeWindow.mockClear();
removeEventListener.mockClear();
const builder = new Builder();
builder.close(false);
expect(closeWindow).not.toHaveBeenCalled();
expect(removeEventListener).toHaveBeenCalled();
});
});
});