From 08967a825b4733e9e3bd65e616490a1a101f8cfb Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Tue, 9 Jan 2024 06:49:15 +0100 Subject: [PATCH] feat: add unit test for building block (#30014) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Add unit tests for the building block card component `BuildingBlock` ✓ renders building block details correctly ✓ navigates to the template URL when clicked ✓ triggers onForkTemplateClick when the fork button is clicked ✓ does not trigger onForkTemplateClick when the button is hidden ✓ opens the fork modal when the fork button is clicked #### PR fixes following issue(s) Fixes # (issue number) #### Type of change - New feature (non-breaking change which adds functionality) ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] JUnit - [x] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed ## Summary by CodeRabbit - **New Features** - Introduced a unit test suite for the `BuildingBlock` component to ensure functionality and stability. - **Refactor** - Updated the `ForkTemplate` component to improve testability and consistency in the DOM structure. - **Tests** - Added tests for user interactions within the `BuildingBlock` component, such as navigation and modal interactions. --- .../BuildingBlock/BuildingBlock.test.tsx | 94 +++++++++++++++++++ .../src/pages/Templates/ForkTemplate.tsx | 4 +- app/client/src/pages/Templates/test_config.ts | 26 +++++ 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 app/client/src/pages/Templates/BuildingBlock/BuildingBlock.test.tsx create mode 100644 app/client/src/pages/Templates/test_config.ts diff --git a/app/client/src/pages/Templates/BuildingBlock/BuildingBlock.test.tsx b/app/client/src/pages/Templates/BuildingBlock/BuildingBlock.test.tsx new file mode 100644 index 0000000000..eca37186bc --- /dev/null +++ b/app/client/src/pages/Templates/BuildingBlock/BuildingBlock.test.tsx @@ -0,0 +1,94 @@ +import React from "react"; +import "@testing-library/jest-dom"; +import { render, screen, fireEvent } from "@testing-library/react"; +import { ThemeProvider } from "styled-components"; +import { Router } from "react-router"; +import { templateIdUrl } from "@appsmith/RouteBuilder"; + +import BuildingBlock from "."; +import history from "utils/history"; +import { lightTheme } from "selectors/themeSelectors"; +import { BUILDING_BLOCK_THUMBNAIL_ALT_TEXT } from "../constants"; +import { + mockBuildingBlock, + MOCK_BUILDING_BLOCK_TITLE, + MOCK_BUILDING_BLOCK_DESCRIPTION, + MOCK_BUILDING_BLOCK_ID, +} from "../test_config"; + +jest.mock("react-redux", () => { + const originalModule = jest.requireActual("react-redux"); + return { + ...originalModule, + useDispatch: () => jest.fn(), + useSelector: () => jest.fn(), + }; +}); + +const onForkTemplateClick = jest.fn(); + +const BaseBuildingBlockRender = () => ( + + + +); + +describe("BuildingBlock Component", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("renders building block details correctly", () => { + render(BaseBuildingBlockRender()); + expect(screen.getByText(MOCK_BUILDING_BLOCK_TITLE)).toBeInTheDocument(); + expect( + screen.getByText(MOCK_BUILDING_BLOCK_DESCRIPTION), + ).toBeInTheDocument(); + expect( + screen.getByAltText(BUILDING_BLOCK_THUMBNAIL_ALT_TEXT), + ).toBeInTheDocument(); + }); + + it("navigates to the template URL when clicked", async () => { + render({BaseBuildingBlockRender()}); + const pushMock = jest.spyOn(history, "push"); + fireEvent.click(screen.getByText(MOCK_BUILDING_BLOCK_TITLE)); + expect(pushMock).toHaveBeenCalledWith( + templateIdUrl({ id: MOCK_BUILDING_BLOCK_ID }), + ); + }); + + it("triggers onForkTemplateClick when the fork button is clicked", async () => { + render(BaseBuildingBlockRender()); + fireEvent.click(screen.getByTestId("t--fork-building-block")); + expect(onForkTemplateClick).toHaveBeenCalledWith(mockBuildingBlock); + }); + + it("does not trigger onForkTemplateClick when the button is hidden", () => { + const onForkTemplateClick = jest.fn(); + render( + + + , + ); + const forkButton = screen.queryByTestId("t--fork-building-block"); + expect(forkButton).toBeNull(); + fireEvent.click(screen.getByText(MOCK_BUILDING_BLOCK_TITLE)); + expect(onForkTemplateClick).not.toHaveBeenCalled(); + }); + + it("opens the fork modal when the fork button is clicked", async () => { + render(BaseBuildingBlockRender()); + const forkButton = screen.getByTestId("t--fork-building-block"); + fireEvent.click(forkButton); + expect(screen.getByTestId("t--fork-template-modal")).toBeInTheDocument(); + }); +}); diff --git a/app/client/src/pages/Templates/ForkTemplate.tsx b/app/client/src/pages/Templates/ForkTemplate.tsx index 334542efdc..8daf120303 100644 --- a/app/client/src/pages/Templates/ForkTemplate.tsx +++ b/app/client/src/pages/Templates/ForkTemplate.tsx @@ -52,7 +52,7 @@ function ForkTemplate({ }; return ( - <> +
{children} @@ -96,7 +96,7 @@ function ForkTemplate({ - +
); } diff --git a/app/client/src/pages/Templates/test_config.ts b/app/client/src/pages/Templates/test_config.ts new file mode 100644 index 0000000000..269d8a72ca --- /dev/null +++ b/app/client/src/pages/Templates/test_config.ts @@ -0,0 +1,26 @@ +import type { Template } from "api/TemplatesApi"; + +// Unit Tests +export const MOCK_BUILDING_BLOCK_TITLE = "Test Building Block"; +export const MOCK_BUILDING_BLOCK_DESCRIPTION = + "Description of the test building block"; +export const MOCK_BUILDING_BLOCK_ID = "mockId"; + +export const mockBuildingBlock: Template = { + id: MOCK_BUILDING_BLOCK_ID, + userPermissions: ["read", "write"], + title: MOCK_BUILDING_BLOCK_TITLE, + description: MOCK_BUILDING_BLOCK_DESCRIPTION, + appUrl: "https://mockapp.com", + gifUrl: "https://mockapp.com/mock.gif", + screenshotUrls: [ + "https://mockapp.com/screenshot1.jpg", + "https://mockapp.com/screenshot2.jpg", + ], + widgets: [], + functions: ["Function1", "Function2"], + useCases: ["UseCase1", "UseCase2"], + datasources: ["Datasource1", "Datasource2"], + pages: [], + allowPageImport: true, +};