From 8b7ace53b99c7abc12df7b0b0200f35930193dcd Mon Sep 17 00:00:00 2001
From: mikieyx <103902194+mikieyx@users.noreply.github.com>
Date: Fri, 28 Jun 2024 09:16:18 -0700
Subject: [PATCH] #2014 Use React Testing Library for common-properties tests -
pt1 Actions (#2015)
---
.../__tests__/_utils_/property-utils.js | 4 +-
.../__tests__/_utils_/property-utilsRTL.js | 120 ++++++++++++++++++
.../actions/button-action-test.js | 106 ++++++++++------
.../actions/image-action-test.js | 90 ++++++++-----
4 files changed, 243 insertions(+), 77 deletions(-)
create mode 100644 canvas_modules/common-canvas/__tests__/_utils_/property-utilsRTL.js
diff --git a/canvas_modules/common-canvas/__tests__/_utils_/property-utils.js b/canvas_modules/common-canvas/__tests__/_utils_/property-utils.js
index ddb46ac18d..ead9175bbe 100644
--- a/canvas_modules/common-canvas/__tests__/_utils_/property-utils.js
+++ b/canvas_modules/common-canvas/__tests__/_utils_/property-utils.js
@@ -20,12 +20,11 @@ import * as UiConditionsParser from "../../src/common-properties/ui-conditions/u
import { mountWithIntl, mountWithIntlMessages } from "./intl-utils";
import { expect } from "chai";
import cloneDeep from "lodash/cloneDeep";
-
import CustomTableControl from "./custom-controls/CustomTableControl";
import CustomToggleControl from "./custom-controls/CustomToggleControl";
import CustomOpMax from "./custom-condition-ops/customMax";
-
import sinon from "sinon";
+
var renderedController;
function controllerHandler(propertyController) {
renderedController = propertyController;
@@ -60,7 +59,6 @@ function flyoutEditorForm(paramDef, propertiesConfigOverrides, callbacksOverride
if (propertiesConfigOverrides) {
propertiesConfig = Object.assign(propertiesConfig, propertiesConfigOverrides);
}
-
const wrapper = mountWithIntl(
+
+
+ );
+ return { wrapper: wrapper, controller: renderedController, callbacks: callbacks };
+
+}
+
+function setControls(controller, controls) {
+ const parsedControls = [];
+ for (const control of controls) {
+ UiConditionsParser.parseControl(parsedControls, control);
+ }
+ controller.saveControls(parsedControls);
+}
+
+function genLongString(length) {
+ let str = "";
+ while (length > str.length) {
+ str += Math.random().toString(36)
+ .substr(2, 1);
+ }
+ return str;
+}
+
+function openSummaryPanel(wrapper, panelId) {
+ const { container } = wrapper;
+ const summaryPanel = container.querySelector(`div[data-id='properties-${panelId}']`);
+ expect(summaryPanel).to.exist;
+ fireEvent.click(summaryPanel.querySelector("button.properties-summary-link-button"));
+ return container.querySelector("div.properties-wf-content.show");
+}
+
+function getParameterFromParamDef(parameterId, paramDef) {
+ const parameters = paramDef.parameters;
+ let parameterFound = null;
+ parameters.forEach((parameter) => {
+ if (parameter.id === parameterId) {
+ parameterFound = parameter;
+ }
+ });
+ return parameterFound;
+}
+
+module.exports = {
+ flyoutEditorForm: flyoutEditorForm,
+ setControls: setControls,
+ genLongString: genLongString,
+ openSummaryPanel: openSummaryPanel,
+ getParameterFromParamDef: getParameterFromParamDef
+};
diff --git a/canvas_modules/common-canvas/__tests__/common-properties/actions/button-action-test.js b/canvas_modules/common-canvas/__tests__/common-properties/actions/button-action-test.js
index 98478045ab..40ccb760b1 100644
--- a/canvas_modules/common-canvas/__tests__/common-properties/actions/button-action-test.js
+++ b/canvas_modules/common-canvas/__tests__/common-properties/actions/button-action-test.js
@@ -17,13 +17,15 @@
import React from "react";
import { Provider } from "react-redux";
import ActionButton from "./../../../src/common-properties/actions/button";
-import { mount } from "../../_utils_/mount-utils.js";
+import { render } from "../../_utils_/mount-utils.js";
import { expect } from "chai";
+import { expect as expectJest } from "@jest/globals";
import sinon from "sinon";
import Controller from "./../../../src/common-properties/properties-controller";
-
import ACTION_PARAMDEF from "../../test_resources/paramDefs/action_paramDef.json";
-import propertyUtils from "../../_utils_/property-utils";
+import propertyUtilsRTL from "../../_utils_/property-utilsRTL";
+import { fireEvent, within } from "@testing-library/react";
+
const actionHandler = sinon.spy();
const controller = new Controller();
@@ -51,10 +53,22 @@ const action = {
"class_name": "custom-class-for-action-button"
};
+const mockActionButton = jest.fn();
+jest.mock("./../../../src/common-properties/actions/button",
+ () => (props) => mockActionButton(props)
+);
+
+mockActionButton.mockImplementation((props) => {
+ const ActionButtonComp = jest.requireActual(
+ "./../../../src/common-properties/actions/button",
+ ).default;
+ return ;
+});
+
describe("action-button renders correctly", () => {
it("props should have been defined", () => {
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
-
- const button = wrapper.find("ButtonAction");
+ const button = wrapper.queryAllByRole("button");
expect(button).to.have.length(1);
- expect(button.prop("action")).to.equal(action);
- expect(button.prop("controller")).to.equal(controller);
+
+ expectJest(mockActionButton).toHaveBeenCalledWith({
+ "action": action,
+ "controller": controller
+ });
});
it("should render a `ActionButton`", () => {
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const button = wrapper.find("button");
+ const button = wrapper.getAllByRole("button");
expect(button).to.have.length(1);
});
it("should fire action when button clicked", (done) => {
@@ -89,7 +105,7 @@ describe("action-button renders correctly", () => {
done();
}
controller.setHandlers({ actionHandler: callback });
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const button = wrapper.find("button");
- button.simulate("click");
+ const button = wrapper.getByRole("button");
+ fireEvent.click(button);
});
it("action button renders when disabled", () => {
controller.updateActionState(actionStateId, "disabled");
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const buttonWrapper = wrapper.find("div[data-id='increment']");
- expect(buttonWrapper.find("button").prop("disabled")).to.equal(true);
+ const { container } = wrapper;
+ const buttonWrapper = container.querySelector("div[data-id='increment']");
+ const button = within(buttonWrapper).getByRole("button");
+ expect(button.disabled).to.equal(true);
});
it("action button renders when hidden", () => {
controller.updateActionState(actionStateId, "hidden");
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const buttonWrapper = wrapper.find("div[data-id='increment']");
- expect(buttonWrapper.hasClass("hide")).to.equal(true);
+ const { container } = wrapper;
+ const buttonWrapper = container.querySelector("div[data-id='increment']");
+ expect(buttonWrapper.className.includes("hide")).to.equal(true);
});
it("action button renders tooltip", () => {
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const tooltip = wrapper.find("div.tooltipContainer");
- expect(tooltip).to.have.length(1);
- expect(tooltip.text()).to.equal("Increment number by 1.");
+ const tooltips = wrapper.getAllByText("Increment number by 1.");
+ const parentTooltip = tooltips[0].parentElement;
+ expect(tooltips.length).equal(1);
+ expect(parentTooltip.className).equal("tooltipContainer");
});
it("action button kind and size", () => {
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const button = wrapper.find("button");
+ const { container } = wrapper;
+ const contButton = container.getElementsByClassName("cds--btn")[0];
+ const button = wrapper.getAllByRole("button");
expect(button).to.have.length(1);
// verify button kind is secondary
- expect(button.prop("className").includes("cds--btn--secondary")).to.equal(true);
+ expect(contButton.className.includes("cds--btn--secondary")).to.equal(true);
// verify button size is extra large
- expect(button.prop("className").includes("cds--btn--xl")).to.equal(true);
+ expect(contButton.className.includes("cds--btn--xl")).to.equal(true);
});
it("action button default kind is tertiary and size is small", () => {
const actionWithoutButtonObject = {
@@ -170,7 +192,7 @@ describe("action-button renders correctly", () => {
"parameter_ref": "number"
}
};
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const button = wrapper.find("button");
+ const { container } = wrapper;
+ const contButton = container.getElementsByClassName("cds--btn")[0];
+ const button = wrapper.getAllByRole("button");
expect(button).to.have.length(1);
// verify default button kind is tertiary
- expect(button.prop("className").includes("cds--btn--tertiary")).to.equal(true);
+ expect(contButton.className.includes("cds--btn--tertiary")).to.equal(true);
// verify default button size is small
- expect(button.prop("className").includes("cds--btn--sm")).to.equal(true);
+ expect(contButton.className.includes("cds--btn--sm")).to.equal(true);
});
});
@@ -191,12 +215,12 @@ describe("actions using paramDef", () => {
let wrapper;
let renderedObject;
beforeEach(() => {
- renderedObject = propertyUtils.flyoutEditorForm(ACTION_PARAMDEF);
+ renderedObject = propertyUtilsRTL.flyoutEditorForm(ACTION_PARAMDEF);
wrapper = renderedObject.wrapper;
});
it("should fire action when button clicked", (done) => {
- renderedObject = propertyUtils.flyoutEditorForm(ACTION_PARAMDEF, null, { actionHandler: callback }, { appData: appData });
+ renderedObject = propertyUtilsRTL.flyoutEditorForm(ACTION_PARAMDEF, null, { actionHandler: callback }, { appData: appData });
wrapper = renderedObject.wrapper;
function callback(id, inAppData, data) {
expect(id).to.equal("increment");
@@ -204,17 +228,21 @@ describe("actions using paramDef", () => {
expect(data.parameter_ref).to.equal("number");
done();
}
- const button = wrapper.find("div[data-id='increment'] button");
- button.simulate("click");
+ const { container } = wrapper;
+ const div = container.querySelector("div[data-id='increment']");
+ const button = within(div).getByRole("button");
+ fireEvent.click(button);
});
it("action button should have custom classname defined", () => {
+ const { container } = wrapper;
// class_name defined in uiHints action_info
- const incrementButton = wrapper.find("div[data-id='increment']");
- expect(incrementButton.prop("className")).to.equal("properties-action-button custom-class-for-action-button");
+ // const incrementButton = wrapper.find("div[data-id='increment']");
+ const incrementButton = container.querySelector("div[data-id='increment']");
+ expect(incrementButton.className).to.equal("properties-action-button custom-class-for-action-button");
// class_name not defined in uiHints action_info
- const decrementButton = wrapper.find("div[data-id='decrement']");
- expect(decrementButton.prop("className")).to.equal("properties-action-button");
+ const decrementButton = container.querySelector("div[data-id='decrement']");
+ expect(decrementButton.className).to.equal("properties-action-button");
});
});
diff --git a/canvas_modules/common-canvas/__tests__/common-properties/actions/image-action-test.js b/canvas_modules/common-canvas/__tests__/common-properties/actions/image-action-test.js
index 0a41eeafd6..e60f048b95 100644
--- a/canvas_modules/common-canvas/__tests__/common-properties/actions/image-action-test.js
+++ b/canvas_modules/common-canvas/__tests__/common-properties/actions/image-action-test.js
@@ -17,13 +17,14 @@
import React from "react";
import { Provider } from "react-redux";
import ActionImage from ".../../../src/common-properties/actions/image";
-import { mount } from "../../_utils_/mount-utils.js";
+import { render } from "../../_utils_/mount-utils.js";
import { expect } from "chai";
import sinon from "sinon";
import Controller from "../../../src/common-properties/properties-controller";
-
+import { expect as expectJest } from "@jest/globals";
import ACTION_PARAMDEF from "../../test_resources/paramDefs/action_paramDef.json";
-import propertyUtils from "../../_utils_/property-utils";
+import propertyUtilsRTL from "../../_utils_/property-utilsRTL";
+import { fireEvent, within } from "@testing-library/react";
const actionHandler = sinon.spy();
const controller = new Controller();
@@ -56,10 +57,22 @@ const action = {
"class_name": "custom-class-for-action-image"
};
+const mockActionImage = jest.fn();
+jest.mock(".../../../src/common-properties/actions/image",
+ () => (props) => mockActionImage(props)
+);
+
+mockActionImage.mockImplementation((props) => {
+ const ActionImageComp = jest.requireActual(
+ ".../../../src/common-properties/actions/image",
+ ).default;
+ return ;
+});
+
describe("action-image renders correctly", () => {
it("props should have been defined", () => {
- const wrapper = mount(
+ render(
{
/>
);
-
- const image = wrapper.find("ImageAction");
- expect(image).to.have.length(1);
- expect(image.prop("action")).to.equal(action);
- expect(image.prop("controller")).to.equal(controller);
+ expectJest(mockActionImage).toHaveBeenCalledWith({
+ "action": action,
+ "controller": controller
+ });
});
it("should render a `ActionImage`", () => {
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const image = wrapper.find("img");
- expect(image).to.have.length(1);
- expect(image.prop("height")).to.equal(20);
- expect(image.prop("width")).to.equal(25);
- expect(wrapper.find(".right")).to.have.length(1);
+ const { container } = wrapper;
+ const image = container.querySelectorAll("img");
+ expect(image[0].height).to.equal(20);
+ expect(image[0].width).to.equal(25);
+ expect(container.querySelectorAll(".right")).to.have.length(1);
});
it("should fire action when image clicked", (done) => {
function callback(id, inAppData, data) {
@@ -96,7 +108,7 @@ describe("action-image renders correctly", () => {
done();
}
controller.setHandlers({ actionHandler: callback });
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const image = wrapper.find("img");
- image.simulate("click");
+ const image = wrapper.getByRole("img");
+ fireEvent.click(image);
});
it("action image renders when disabled", () => {
controller.updateActionState(actionStateId, "disabled");
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const imageWrapper = wrapper.find(".properties-action-image");
- expect(imageWrapper.hasClass("disabled")).to.equal(true);
+ const { container } = wrapper;
+ const imageWrapper = container.querySelector(".properties-action-image");
+ expect(imageWrapper.className.includes("disabled")).to.equal(true);
});
it("action image renders when hidden", () => {
controller.updateActionState(actionStateId, "hidden");
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const imageWrapper = wrapper.find(".properties-action-image");
- expect(imageWrapper.hasClass("hide")).to.equal(true);
+ const { container } = wrapper;
+ const imageWrapper = container.querySelector(".properties-action-image");
+ expect(imageWrapper.className.includes("hide")).to.equal(true);
});
it("action image renders tooltip", () => {
- const wrapper = mount(
+ const wrapper = render(
{
/>
);
- const tooltip = wrapper.find("div.tooltipContainer");
+ const tooltip = wrapper.getAllByText("Click to rotate through moon phases.");
+ const tooltipWrapper = tooltip[0].parentElement;
expect(tooltip).to.have.length(1);
- expect(tooltip.text()).to.equal("Click to rotate through moon phases.");
+ expect(tooltipWrapper.className).to.equal("tooltipContainer");
+ expect(tooltip[0].textContent).to.equal("Click to rotate through moon phases.");
});
});
@@ -152,12 +168,12 @@ describe("actions using paramDef", () => {
let wrapper;
let renderedObject;
beforeEach(() => {
- renderedObject = propertyUtils.flyoutEditorForm(ACTION_PARAMDEF);
+ renderedObject = propertyUtilsRTL.flyoutEditorForm(ACTION_PARAMDEF);
wrapper = renderedObject.wrapper;
});
it("should fire action when image clicked", (done) => {
- renderedObject = propertyUtils.flyoutEditorForm(ACTION_PARAMDEF, null, { actionHandler: callback }, { appData: appData });
+ renderedObject = propertyUtilsRTL.flyoutEditorForm(ACTION_PARAMDEF, null, { actionHandler: callback }, { appData: appData });
wrapper = renderedObject.wrapper;
function callback(id, inAppData, data) {
expect(id).to.equal("moon");
@@ -165,17 +181,21 @@ describe("actions using paramDef", () => {
expect(data.parameter_ref).to.equal("moon_phase");
done();
}
- const image = wrapper.find("div[data-id='properties-ctrl-moon_phase']").find("div[data-id='moon'] img");
- image.simulate("click");
+ const { container } = wrapper;
+ const imageWrapper = container.querySelector("div[data-id='properties-ctrl-moon_phase']");
+ const image = within(imageWrapper).getByRole("img");
+ fireEvent.click(image);
});
it("action image should have custom classname defined", () => {
// class_name defined in uiHints action_info
- const fallImage = wrapper.find(".properties-action-image").at(3);
- expect(fallImage.prop("className")).to.equal("properties-action-image right custom-class-for-action-image");
+ const { container } = wrapper;
+ const images = container.querySelectorAll(".properties-action-image");
+ const fallImage = images[3];
+ expect(fallImage.className).to.equal("properties-action-image right custom-class-for-action-image");
// class_name not defined in uiHints action_info
- const winterImage = wrapper.find(".properties-action-image").at(0);
- expect(winterImage.prop("className")).to.equal("properties-action-image");
+ const winterImage = images[0];
+ expect(winterImage.className).to.equal("properties-action-image");
});
});