From 7338bd33d0a6f9f4e000d74dfa3e92a358c35207 Mon Sep 17 00:00:00 2001 From: Rohit Kandimalla Date: Tue, 22 Oct 2024 12:04:34 -0400 Subject: [PATCH] MAT-7731 Added an option to display All TestCases on List Page --- package-lock.json | 72 +++++++++++++++---- package.json | 2 +- .../common/Hooks/UseTestCases.tsx | 13 ++-- .../common/Hooks/useTestCases.test.tsx | 66 ++++++++++++----- .../testCaseLanding/qdm/TestCaseList.tsx | 16 ++--- 5 files changed, 121 insertions(+), 48 deletions(-) diff --git a/package-lock.json b/package-lock.json index f51029823..bc014b1a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -103,7 +103,7 @@ "identity-obj-proxy": "^3.0.0", "jest": "^27.1.0", "jest-cli": "^27.1.0", - "jsonpath-plus": "^7.2.0", + "jsonpath-plus": "^10.1.0", "node-polyfill-webpack-plugin": "^1.1.4", "postcss": "^8.3.6", "postcss-loader": "^6.1.1", @@ -3741,6 +3741,32 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsep-plugin/assignment": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.2.1.tgz", + "integrity": "sha512-gaHqbubTi29aZpVbBlECRpmdia+L5/lh2BwtIJTmtxdbecEyyX/ejAOg7eQDGNvGOUmPY7Z2Yxdy9ioyH/VJeA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsep-plugin/regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", + "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, "node_modules/@juggle/resize-observer": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", @@ -9901,17 +9927,18 @@ } }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -9943,10 +9970,11 @@ } }, "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -14782,6 +14810,16 @@ "node": ">= 6" } }, + "node_modules/jsep": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz", + "integrity": "sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -14836,12 +14874,22 @@ } }, "node_modules/jsonpath-plus": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", - "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.1.0.tgz", + "integrity": "sha512-gHfV1IYqH8uJHYVTs8BJX1XKy2/rR93+f8QQi0xhx95aCiXn1ettYAd5T+7FU6wfqyDoX/wy0pm/fL3jOKJ9Lg==", "dev": true, + "license": "MIT", + "dependencies": { + "@jsep-plugin/assignment": "^1.2.1", + "@jsep-plugin/regex": "^1.0.3", + "jsep": "^1.3.9" + }, + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, "engines": { - "node": ">=12.0.0" + "node": ">=18.0.0" } }, "node_modules/jss": { diff --git a/package.json b/package.json index 33f635eb8..12ee1e140 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "identity-obj-proxy": "^3.0.0", "jest": "^27.1.0", "jest-cli": "^27.1.0", - "jsonpath-plus": "^7.2.0", + "jsonpath-plus": "^10.1.0", "node-polyfill-webpack-plugin": "^1.1.4", "postcss": "^8.3.6", "postcss-loader": "^6.1.1", diff --git a/src/components/testCaseLanding/common/Hooks/UseTestCases.tsx b/src/components/testCaseLanding/common/Hooks/UseTestCases.tsx index 3540ea8c7..b812ecf90 100644 --- a/src/components/testCaseLanding/common/Hooks/UseTestCases.tsx +++ b/src/components/testCaseLanding/common/Hooks/UseTestCases.tsx @@ -81,7 +81,7 @@ function UseFetchTestCases({ measureId, setErrors }) { visibleItems: null, offset: 0, page: 1, - limit: 10, + limit: 10 || "All", count: undefined, currentSlice: [], canGoNext: false, @@ -105,7 +105,10 @@ function UseFetchTestCases({ measureId, setErrors }) { const filter: string = values?.filter ? values.filter.toString() : ""; // pull info from some query url let searchQuery: string = values?.search ? values.search.toString() : ""; - const curLimit = (values.limit && Number(values.limit)) || 10; + const curLimit = + values.limit === "All" && testCases?.length > 0 + ? testCases?.length + : Number(values.limit) || 10; const curPage = (values.page && Number(values.page)) || 1; let navigate = useNavigate(); @@ -132,7 +135,7 @@ function UseFetchTestCases({ measureId, setErrors }) { "testCasesPageOptions", JSON.stringify({ page: curPage, - limit: curLimit, + limit: (values.limit === "All" && values.limit) || curLimit, filter, search: searchQuery, }) @@ -184,7 +187,7 @@ function UseFetchTestCases({ measureId, setErrors }) { visibleItems: currentSlice.length, offset: start, page: curPage, - limit: curLimit, + limit: (values.limit === "All" && values.limit) || curLimit, count: Math.ceil(filteredTestCases.length / curLimit), currentSlice, handlePageChange, @@ -204,7 +207,7 @@ function UseFetchTestCases({ measureId, setErrors }) { visibleItems: currentSlice.length, offset: start, page: curPage, - limit: curLimit, + limit: (values.limit === "All" && values.limit) || curLimit, count, currentSlice, handlePageChange, diff --git a/src/components/testCaseLanding/common/Hooks/useTestCases.test.tsx b/src/components/testCaseLanding/common/Hooks/useTestCases.test.tsx index 4eaf3f74a..93ced773a 100644 --- a/src/components/testCaseLanding/common/Hooks/useTestCases.test.tsx +++ b/src/components/testCaseLanding/common/Hooks/useTestCases.test.tsx @@ -1,13 +1,13 @@ -import React from "react"; +import * as React from "react"; import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { MemoryRouter } from "react-router"; -import UseFetchTestCases, { - customSort, - sortFilteredTestCases, -} from "./UseTestCases"; -import useTestCaseServiceApi from "../../../../api/useTestCaseServiceApi"; +import UseFetchTestCases, { sortFilteredTestCases } from "./UseTestCases"; +import useTestCaseServiceApi, { + TestCaseServiceApi, +} from "../../../../api/useTestCaseServiceApi"; import { renderHook, act } from "@testing-library/react-hooks"; -import { measureStore } from "@madie/madie-util"; +import { TestCase } from "@madie/madie-models"; +import { SortingState } from "@tanstack/react-table"; const mockNavigate = jest.fn(); @@ -55,14 +55,20 @@ const MockComponent = ({ measureId, setErrors }) => { ); }; +jest.mock("../../../../api/useTestCaseServiceApi"); +const useTestCaseServiceMock = + useTestCaseServiceApi as jest.Mock; +const mockGetTestCasesByMeasureId = jest.fn(); +const useTestCaseServiceMockResolved = { + getTestCasesByMeasureId: mockGetTestCasesByMeasureId, +} as unknown as TestCaseServiceApi; + describe("UseFetchTestCases", () => { const mockSetErrors = jest.fn(); - const mockGetTestCasesByMeasureId = jest.fn(); - beforeEach(() => { jest.clearAllMocks(); - useTestCaseServiceApi.mockReturnValue({ - getTestCasesByMeasureId: mockGetTestCasesByMeasureId, + useTestCaseServiceMock.mockImplementation(() => { + return useTestCaseServiceMockResolved; }); }); @@ -126,17 +132,39 @@ describe("UseFetchTestCases", () => { expect(mockNavigate).toHaveBeenCalledWith( expect.stringContaining("limit=20") ); + + act(() => { + result.current.testCasePage.handleLimitChange({ + target: { value: "All" }, + }); + }); + expect(mockNavigate).toHaveBeenCalledWith( + expect.stringContaining("limit=All") + ); }); it("should save pagination options to local storage", () => { const { result } = renderHook(() => UseFetchTestCases({ measureId: "123", setErrors: mockSetErrors }) ); + const testCase1 = { + id: "1234", + title: "Test Case 1", + createdBy: "testuser", + description: "Test IPP", + series: "SeriesA", + json: `{"test":"test" BAD BAD JSON - DEFINITELY INVALID }`, + } as TestCase; + const testCase2 = { + id: "1234", + title: "Test Case 2", + createdBy: "testuser", + description: "Test IPP", + series: "SeriesA", + json: `{"test":"test" BAD BAD JSON - DEFINITELY INVALID }`, + } as TestCase; act(() => { - result.current.setTestCases([ - { title: "Test Case 1" }, - { title: "Test Case 2" }, - ]); + result.current.setTestCases([testCase1, testCase2]); }); expect(window.localStorage.getItem("testCasesPageOptions")).toContain( @@ -248,12 +276,12 @@ describe("UseFetchTestCases", () => { }); // forget it. exporting the lines this doesn't reach. it("should sort test cases based on sorting state", () => { - const testCaseList: TestCase[] = [ + const testCaseList = [ { title: "apple", validResource: true, lastModifiedAt: new Date() }, { title: "banana", validResource: true, lastModifiedAt: new Date() }, { title: "cat", validResource: true, lastModifiedAt: new Date() }, { title: "zebra", validResource: true, lastModifiedAt: new Date() }, - ]; + ] as unknown as TestCase[]; const sorting: SortingState = [{ id: "title", desc: false }]; const sortedCasesAsc = sortFilteredTestCases(sorting, testCaseList); @@ -269,10 +297,10 @@ describe("UseFetchTestCases", () => { }); it("should return original list when no sorting is applied", () => { - const testCaseList: TestCase[] = [ + const testCaseList = [ { title: "apple", validResource: true, lastModifiedAt: new Date() }, { title: "banana", validResource: true, lastModifiedAt: new Date() }, - ]; + ] as unknown as TestCase[]; const sortedCases = sortFilteredTestCases([], testCaseList); expect(sortedCases).toEqual(testCaseList); diff --git a/src/components/testCaseLanding/qdm/TestCaseList.tsx b/src/components/testCaseLanding/qdm/TestCaseList.tsx index 69a0cc0aa..8d3c85f33 100644 --- a/src/components/testCaseLanding/qdm/TestCaseList.tsx +++ b/src/components/testCaseLanding/qdm/TestCaseList.tsx @@ -1,8 +1,7 @@ import React, { useCallback, useEffect, useRef, useState } from "react"; import "twin.macro"; import "styled-components/macro"; -import * as _ from "lodash"; -import { uniqWith } from "lodash"; +import _ from "lodash"; import { Group, GroupedStratificationDto, @@ -16,11 +15,7 @@ import { import { useParams, useNavigate, useLocation } from "react-router-dom"; import queryString from "query-string"; import calculationService from "../../../api/CalculationService"; -import { - checkUserCanEdit, - measureStore, - useFeatureFlags, -} from "@madie/madie-util"; +import { checkUserCanEdit, useFeatureFlags } from "@madie/madie-util"; import CreateCodeCoverageNavTabs from "./CreateCodeCoverageNavTabs"; import CreateNewTestCaseDialog from "../../createTestCase/CreateNewTestCaseDialog"; import { @@ -143,7 +138,6 @@ const TestCaseList = (props: TestCaseListProps) => { onToastClose, } = UseToast(); const excelExportService = useRef(useExcelExportService()); - const { updateMeasure } = measureStore; const calculation = useRef(calculationService()); const qdmCalculation = useRef(qdmCalculationService()); const [canEdit, setCanEdit] = useState(false); @@ -329,12 +323,12 @@ const TestCaseList = (props: TestCaseListProps) => { ) .filter((result) => result.final !== "NA"); // get a list of all unique used clauses - const allUniqueClauses = uniqWith( + const allUniqueClauses = _.uniqWith( allRelevantClauses, (c1, c2) => c1.libraryName === c2.libraryName && c1.localId === c2.localId ).sort((a, b) => a.localId - b.localId); // get a list of all unique covered clauses - const coveredClauses = uniqWith( + const coveredClauses = _.uniqWith( allRelevantClauses.filter((clause) => clause.final === "TRUE"), (c1, c2) => c1.libraryName === c2.libraryName && c1.localId === c2.localId ); @@ -803,7 +797,7 @@ const TestCaseList = (props: TestCaseListProps) => {