From f446de221f59799670e7a702531b0841c17dd36a Mon Sep 17 00:00:00 2001 From: Ricardo Campos Date: Tue, 25 Jun 2024 14:51:15 -0300 Subject: [PATCH] test: silva 447 add unit tests (#329) --- frontend/package-lock.json | 25 ++++++++----- frontend/package.json | 5 ++- .../src/__test__/components/BCHeader.test.tsx | 37 +++++++++++++++++++ .../components/MyRecentActions.test.tsx | 34 +++++++++++++++++ .../OpeningScreenDataTable.test.tsx | 14 +++---- .../__test__/components/StatusTag.test.tsx | 17 +++++++++ frontend/src/components/BCHeader/index.tsx | 4 +- .../src/components/MyRecentActions/index.tsx | 22 +++++++++-- frontend/src/components/StatusTag/index.tsx | 6 ++- frontend/src/services/OpeningService.ts | 20 ++++++++-- frontend/src/types/RecentOpening.ts | 4 +- 11 files changed, 157 insertions(+), 31 deletions(-) create mode 100644 frontend/src/__test__/components/BCHeader.test.tsx create mode 100644 frontend/src/__test__/components/MyRecentActions.test.tsx create mode 100644 frontend/src/__test__/components/StatusTag.test.tsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a909ff74..270160df 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,8 +14,6 @@ "@carbon/react": "^1.27.0", "@redux-devtools/extension": "^3.3.0", "@types/node": "^20.0.0", - "@types/react": "^18.2.0", - "@types/react-dom": "^18.2.1", "@vitejs/plugin-react": "^4.0.4", "@vitejs/plugin-react-swc": "^3.3.2", "amazon-cognito-identity-js": "^6.3.13", @@ -37,10 +35,13 @@ "yaml": "^2.3.2" }, "devDependencies": { + "@testing-library/dom": "^10.2.0", "@testing-library/jest-dom": "^6.4.5", "@testing-library/react": "^15.0.7", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^6.5.0", "@typescript-eslint/parser": "^6.5.0", "@vitest/coverage-v8": "^1.0.0", @@ -4771,9 +4772,9 @@ } }, "node_modules/@testing-library/dom": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", - "integrity": "sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.2.0.tgz", + "integrity": "sha512-CytIvb6tVOADRngTHGWNxH8LPgO/3hi/BdCEHOf7Qd2GvZVClhVP0Wo/QHzWhpki49Bk0b4VT6xpt3fx8HTSIw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", @@ -5047,12 +5048,14 @@ "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "devOptional": true }, "node_modules/@types/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", - "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -5062,6 +5065,7 @@ "version": "18.3.0", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, "dependencies": { "@types/react": "*" } @@ -6606,7 +6610,8 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true }, "node_modules/d3": { "version": "7.9.0", diff --git a/frontend/package.json b/frontend/package.json index 35b9db5b..6400ae6a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,8 +10,6 @@ "@carbon/react": "^1.27.0", "@redux-devtools/extension": "^3.3.0", "@types/node": "^20.0.0", - "@types/react": "^18.2.0", - "@types/react-dom": "^18.2.1", "@vitejs/plugin-react": "^4.0.4", "@vitejs/plugin-react-swc": "^3.3.2", "amazon-cognito-identity-js": "^6.3.13", @@ -54,10 +52,13 @@ ] }, "devDependencies": { + "@testing-library/dom": "^10.2.0", "@testing-library/jest-dom": "^6.4.5", "@testing-library/react": "^15.0.7", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^6.5.0", "@typescript-eslint/parser": "^6.5.0", "@vitest/coverage-v8": "^1.0.0", diff --git a/frontend/src/__test__/components/BCHeader.test.tsx b/frontend/src/__test__/components/BCHeader.test.tsx new file mode 100644 index 00000000..dba203ea --- /dev/null +++ b/frontend/src/__test__/components/BCHeader.test.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; +import BCHeader from '../../components/BCHeader'; +import { ThemePreference } from '../../utils/ThemePreference'; +import { BrowserRouter } from 'react-router-dom'; + +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: vi.fn().mockImplementation(query => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // Deprecated + removeListener: vi.fn(), // Deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn() + })) +}); + +describe('BC Header component tests', () => { + it('should have a Header with proper class name', () => { + const { getByTestId, getByText } = render( + + + + + + ); + + const element: HTMLElement | null = getByTestId('bc-header__header'); + expect(element).toBeDefined(); + expect(element).not.toBeNull(); + expect(element?.classList.contains('spar-header')).toBe(true); + }); +}); diff --git a/frontend/src/__test__/components/MyRecentActions.test.tsx b/frontend/src/__test__/components/MyRecentActions.test.tsx new file mode 100644 index 00000000..c16e0bf7 --- /dev/null +++ b/frontend/src/__test__/components/MyRecentActions.test.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { describe, expect, it } from 'vitest'; +import MyRecentActions from '../../components/MyRecentActions'; + +describe('My Recent Actions component tests', () => { + it('should render the recent action component', () => { + const { getByTestId, getByText } = render( + + ); + const text = 'Recent'; + + const element: HTMLElement | null = getByTestId('my-recent-actions__recent-tab-header'); + expect(element).toBeDefined(); + expect(element).not.toBeNull(); + expect(element?.classList.contains('tab-header-recent')).toBe(true); + const elementText: HTMLElement = getByText(text); + expect(elementText.textContent).toEqual(text); + }); + + it('should render the files and tabs action component', () => { + const { getByTestId, getByText } = render( + + ); + const text = 'Files and Docs'; + + const element: HTMLElement | null = getByTestId('my-recent-actions__files-tab-header'); + expect(element).toBeDefined(); + expect(element).not.toBeNull(); + expect(element?.classList.contains('tab-header-recent')).toBe(true); + const elementText: HTMLElement = getByText(text); + expect(elementText.textContent).toEqual(text); + }); +}); diff --git a/frontend/src/__test__/components/OpeningScreenDataTable.test.tsx b/frontend/src/__test__/components/OpeningScreenDataTable.test.tsx index d617a04a..8df8e766 100644 --- a/frontend/src/__test__/components/OpeningScreenDataTable.test.tsx +++ b/frontend/src/__test__/components/OpeningScreenDataTable.test.tsx @@ -3,20 +3,20 @@ import { render } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; import OpeningScreenDataTable from '../../components/OpeningScreenDataTable'; import PaginationContext from '../../contexts/PaginationContext'; +import { RecentOpening } from '../../types/RecentOpening'; -const rows = [{ - id: '1', +const rows: RecentOpening[] = [{ openingId: '123', fileId: '1', cuttingPermit: '1', timberMark: '1', cutBlock: '1', - grossAreaHa: '1', - status: '1', - category: '1', + grossAreaHa: 1, + statusDesc: 'Approved', + categoryDesc: 'Another', disturbanceStart: '1', - createdAt: '1', - lastViewed: '1', + entryTimestamp: '1', + updateTimestamp: '1', }]; const headers = [{ key: 'openingId', header: 'Opening Id', }, diff --git a/frontend/src/__test__/components/StatusTag.test.tsx b/frontend/src/__test__/components/StatusTag.test.tsx new file mode 100644 index 00000000..1a05c18e --- /dev/null +++ b/frontend/src/__test__/components/StatusTag.test.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; +import StatusTag from '../../components/StatusTag'; + +describe('Status Tag component tests', () => { + it('should have completed color status tag rendered', () => { + const colorKey = 'Completed'; + + const { getByTestId } = render( + + ); + + const element: HTMLElement | null = getByTestId(`tag__status_colored_tag_${colorKey}`); + expect(element).toBeDefined(); + }); +}); diff --git a/frontend/src/components/BCHeader/index.tsx b/frontend/src/components/BCHeader/index.tsx index 9afea40b..d63a596b 100644 --- a/frontend/src/components/BCHeader/index.tsx +++ b/frontend/src/components/BCHeader/index.tsx @@ -30,8 +30,8 @@ const BCHeader: React.FC = () => { (
+ className="spar-header" + data-testid="bc-header__header"> { ]; useEffect(() => { - async function fetchData() { + function fetchData() { try { - const actions: RecentAction[] = await fetchRecentActions(); + const actions: RecentAction[] = fetchRecentActions(); setRecentActions(actions); } catch (error) { console.error('Error fetching recent actions:', error); @@ -43,8 +43,22 @@ const MyRecentActions: React.FC = () => { return ( -
Recent
-
Files and Docs
+ +
+ Recent +
+
+ +
+ Files and Docs +
+
diff --git a/frontend/src/components/StatusTag/index.tsx b/frontend/src/components/StatusTag/index.tsx index f9b4f09d..c11735cc 100644 --- a/frontend/src/components/StatusTag/index.tsx +++ b/frontend/src/components/StatusTag/index.tsx @@ -13,7 +13,11 @@ const StatusTag: React.FC = (props) => { const typeColor: string = StatusColourMap[colorKey as keyof typeof StatusColourMap]; return ( - + { props.code } ); diff --git a/frontend/src/services/OpeningService.ts b/frontend/src/services/OpeningService.ts index 00e2cbc6..d5a4c992 100644 --- a/frontend/src/services/OpeningService.ts +++ b/frontend/src/services/OpeningService.ts @@ -7,6 +7,20 @@ import { RecentOpening } from '../types/RecentOpening'; const backendUrl = env.VITE_BACKEND_URL; +interface IOpeningReq { + openingId: string; + fileId: string; + cuttingPermit: string | null; + timberMark: string | null; + cutBlock: string | null; + grossAreaHa: number | null; + status: { code: string, description: string } | null; + category: { code: string, description: string } | null; + disturbanceStart: string | null; + entryTimestamp: string | null; + updateTimestamp: string | null; +} + /** * Fetch recent openings data from backend. * @@ -26,7 +40,7 @@ export async function fetchRecentOpenings(): Promise { if (data.data) { // Extracting row information from the fetched data - const rows: RecentOpening[] = data.data.map((opening: RecentOpening) => ({ + const rows: RecentOpening[] = data.data.map((opening: IOpeningReq) => ({ id: opening.openingId.toString(), openingId: opening.openingId.toString(), fileId: opening.fileId ? opening.fileId : '-', @@ -34,8 +48,8 @@ export async function fetchRecentOpenings(): Promise { timberMark: opening.timberMark ? opening.timberMark : '-', cutBlock: opening.cutBlock ? opening.cutBlock : '-', grossAreaHa: opening.grossAreaHa ? opening.grossAreaHa.toString() : '-', - status: opening.status ? opening.status.description : '-', - category: opening.category ? opening.category.code : '-', + statusDesc: opening.status ? opening.status.description : '-', + categoryDesc: opening.category ? opening.category.code : '-', disturbanceStart: opening.disturbanceStart ? opening.disturbanceStart : '-', entryTimestamp: opening.entryTimestamp ? opening.entryTimestamp.split('T')[0] : '-', updateTimestamp: opening.updateTimestamp ? opening.updateTimestamp.split('T')[0] : '-' diff --git a/frontend/src/types/RecentOpening.ts b/frontend/src/types/RecentOpening.ts index 886fa548..37952c70 100644 --- a/frontend/src/types/RecentOpening.ts +++ b/frontend/src/types/RecentOpening.ts @@ -5,8 +5,8 @@ export interface RecentOpening { timberMark: string | null; cutBlock: string | null; grossAreaHa: number | null; - status: {code: string, description: string} | null; - category: {code: string, description: string} | null; + statusDesc: string | null; + categoryDesc: string | null; disturbanceStart: string | null; entryTimestamp: string | null; updateTimestamp: string | null;