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;