From 7cdb65f8db399c75a83e2c80cf497c072008be63 Mon Sep 17 00:00:00 2001
From: Shimnas E S
Date: Thu, 25 Sep 2025 16:57:24 +0530
Subject: [PATCH 1/4] latest updated navbar
---
src/App.js | 7 ++++++-
src/index.css | 7 ++++++-
src/ui/navbar.jsx | 3 ++-
src/utility/auth.js | 2 +-
4 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/src/App.js b/src/App.js
index b90d8b3..fac6bcb 100644
--- a/src/App.js
+++ b/src/App.js
@@ -42,8 +42,13 @@ const router = createBrowserRouter([
errorElement: ,
},
{
+
path: "/Edit",
- element: ,
+ element:(
+
+
+
+ ),
errorElement: ,
},
]);
diff --git a/src/index.css b/src/index.css
index 201d410..8e6e6be 100644
--- a/src/index.css
+++ b/src/index.css
@@ -32,7 +32,7 @@ body {
.nav-bar {
display: grid;
- grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
+ grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
align-items: center;
height: 7.2rem;
padding: 0 3.2rem;
@@ -40,6 +40,11 @@ body {
border-radius: 0.9rem;
}
+.user-info{
+ font-weight: bolder;
+ font-size: large;
+}
+
.logo {
display: flex;
align-items: center;
diff --git a/src/ui/navbar.jsx b/src/ui/navbar.jsx
index 35940b0..95f2187 100644
--- a/src/ui/navbar.jsx
+++ b/src/ui/navbar.jsx
@@ -68,7 +68,8 @@ export default function Navbar({
)}
-
+
{
const token = localStorage.getItem("user");
return !!token;
From b67423a97a925d8d1803a083597b9ad4b73cfcb9 Mon Sep 17 00:00:00 2001
From: Shimnas E S
Date: Fri, 26 Sep 2025 11:53:31 +0530
Subject: [PATCH 2/4] filter issue resolved
---
src/features/products/productFilter.jsx | 5 +++--
src/ui/home.jsx | 5 +++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/features/products/productFilter.jsx b/src/features/products/productFilter.jsx
index 0b5f536..f5992e1 100644
--- a/src/features/products/productFilter.jsx
+++ b/src/features/products/productFilter.jsx
@@ -1,6 +1,6 @@
import { useOutletContext } from "react-router-dom";
import { useState } from "react";
-export default function ProductFilter({ applyFilters }) {
+export default function ProductFilter({ applyFilters,clearFilters }) {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const toggleDrawer = () => {
@@ -8,10 +8,11 @@ export default function ProductFilter({ applyFilters }) {
};
const clearFilter = () => {
- setSortBy("");
+ setSortBy("none");
setFilter("none");
setPriceRange([0, 1000]);
setIsDrawerOpen(false);
+ clearFilters();
};
const { filter, setFilter, sortBy, setSortBy, priceRange, setPriceRange } =
diff --git a/src/ui/home.jsx b/src/ui/home.jsx
index 9e952fe..6886d44 100644
--- a/src/ui/home.jsx
+++ b/src/ui/home.jsx
@@ -32,6 +32,10 @@ export default function Home() {
setFiltersApplied((prev) => !prev);
}
+ function clearFilters() {
+ setFiltersApplied(false);
+ }
+
return (
<>
From e569f91c6c20bb6066b6626d1bb337cf1233764a Mon Sep 17 00:00:00 2001
From: Shimnas E S
Date: Mon, 29 Sep 2025 22:19:36 +0530
Subject: [PATCH 3/4] Jest unit test and configurations
---
.babelrc | 6 +
package-lock.json | 210 +++++++++++-------
package.json | 19 +-
src/App.test.js | 8 -
src/features/cart/_tests/cartItem.test.jsx | 72 ++++++
src/features/cart/cartItem.jsx | 6 +-
src/features/orders/_tests/orderList.test.jsx | 62 ++++++
src/features/orders/_tests/review.test.js | 105 +++++++++
src/features/orders/review.jsx | 8 +-
.../products/_test/productDetails.test.jsx | 78 +++++++
.../products/_test/productItem.test.jsx | 59 +++++
.../products/_test/productList.test.jsx | 36 +++
.../products/_test/productReview.test.jsx | 54 +++++
src/features/products/productDetails.jsx | 6 +-
src/jest.config.js | 17 ++
src/jest.setup.js | 13 ++
16 files changed, 660 insertions(+), 99 deletions(-)
create mode 100644 .babelrc
delete mode 100644 src/App.test.js
create mode 100644 src/features/cart/_tests/cartItem.test.jsx
create mode 100644 src/features/orders/_tests/orderList.test.jsx
create mode 100644 src/features/orders/_tests/review.test.js
create mode 100644 src/features/products/_test/productDetails.test.jsx
create mode 100644 src/features/products/_test/productItem.test.jsx
create mode 100644 src/features/products/_test/productList.test.jsx
create mode 100644 src/features/products/_test/productReview.test.jsx
create mode 100644 src/jest.config.js
create mode 100644 src/jest.setup.js
diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..a8a04a8
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,6 @@
+{
+ "presets": [
+ "@babel/preset-env",
+ ["@babel/preset-react", { "runtime": "automatic" }]
+ ]
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 029326e..cbe8aa2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,23 +11,30 @@
"@fortawesome/fontawesome-free": "^7.0.1",
"@reduxjs/toolkit": "^2.9.0",
"@testing-library/dom": "^10.4.1",
- "@testing-library/jest-dom": "^6.8.0",
- "@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.12.2",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-redux": "^9.2.0",
- "react-router-dom": "^7.9.1",
+ "react-router-dom": "^7.9.3",
"react-saga": "^0.3.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
+ },
+ "devDependencies": {
+ "@babel/preset-react": "^7.27.1",
+ "@testing-library/jest-dom": "^6.8.0",
+ "@testing-library/react": "^16.3.0",
+ "jest": "^27.5.1",
+ "jest-environment-jsdom": "^27.0.3",
+ "redux-mock-store": "^1.5.5"
}
},
"node_modules/@adobe/css-tools": {
"version": "4.4.4",
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
"integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@alloc/quick-lru": {
@@ -2780,18 +2787,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/@jest/schemas": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz",
- "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==",
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.24.1"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
"node_modules/@jest/source-map": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz",
@@ -3276,12 +3271,6 @@
"integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==",
"license": "MIT"
},
- "node_modules/@sinclair/typebox": {
- "version": "0.24.51",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
- "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
- "license": "MIT"
- },
"node_modules/@sinonjs/commons": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
@@ -3577,6 +3566,7 @@
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.8.0.tgz",
"integrity": "sha512-WgXcWzVM6idy5JaftTVC8Vs83NKRmGJz4Hqs4oyOuO2J4r/y79vvKZsb+CaGyCSEbUPI6OsewfPd0G1A0/TUZQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@adobe/css-tools": "^4.4.0",
@@ -3596,12 +3586,14 @@
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
"integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@testing-library/react": {
"version": "16.3.0",
"resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz",
"integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.12.5"
@@ -6387,6 +6379,7 @@
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
"integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/cssdb": {
@@ -8599,20 +8592,6 @@
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"license": "ISC"
},
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -9415,6 +9394,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -10279,6 +10259,24 @@
}
}
},
+ "node_modules/jest-config/node_modules/jest-environment-jsdom": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz",
+ "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==",
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^27.5.1",
+ "@jest/fake-timers": "^27.5.1",
+ "@jest/types": "^27.5.1",
+ "@types/node": "*",
+ "jest-mock": "^27.5.1",
+ "jest-util": "^27.5.1",
+ "jsdom": "^16.6.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
"node_modules/jest-diff": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz",
@@ -10323,17 +10321,18 @@
}
},
"node_modules/jest-environment-jsdom": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz",
- "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==",
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.3.tgz",
+ "integrity": "sha512-5KLmgv1bhiimpSA8oGTnZYk6g4fsNyZiA/6gI2tAZUgrufd7heRUSVh4gRokzZVEj8zlwAQYT0Zs6tuJSW/ECA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/environment": "^27.5.1",
- "@jest/fake-timers": "^27.5.1",
- "@jest/types": "^27.5.1",
+ "@jest/environment": "^27.0.3",
+ "@jest/fake-timers": "^27.0.3",
+ "@jest/types": "^27.0.2",
"@types/node": "*",
- "jest-mock": "^27.5.1",
- "jest-util": "^27.5.1",
+ "jest-mock": "^27.0.3",
+ "jest-util": "^27.0.2",
"jsdom": "^16.6.0"
},
"engines": {
@@ -10574,6 +10573,24 @@
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
+ "node_modules/jest-runner/node_modules/jest-environment-jsdom": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz",
+ "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==",
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^27.5.1",
+ "@jest/fake-timers": "^27.5.1",
+ "@jest/types": "^27.5.1",
+ "@types/node": "*",
+ "jest-mock": "^27.5.1",
+ "jest-util": "^27.5.1",
+ "jsdom": "^16.6.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
"node_modules/jest-runtime": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz",
@@ -10734,6 +10751,18 @@
"node": ">=8"
}
},
+ "node_modules/jest-watch-typeahead/node_modules/@jest/schemas": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz",
+ "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==",
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.24.1"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
+ },
"node_modules/jest-watch-typeahead/node_modules/@jest/test-result": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz",
@@ -10766,6 +10795,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
+ "node_modules/jest-watch-typeahead/node_modules/@sinclair/typebox": {
+ "version": "0.24.51",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
+ "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
+ "license": "MIT"
+ },
"node_modules/jest-watch-typeahead/node_modules/@types/yargs": {
"version": "17.0.33",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
@@ -11104,6 +11139,27 @@
}
}
},
+ "node_modules/jsdom/node_modules/ws": {
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
@@ -11371,6 +11427,13 @@
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"license": "MIT"
},
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -11604,6 +11667,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -14161,9 +14225,9 @@
}
},
"node_modules/react-router": {
- "version": "7.9.1",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.1.tgz",
- "integrity": "sha512-pfAByjcTpX55mqSDGwGnY9vDCpxqBLASg0BMNAuMmpSGESo/TaOUG6BllhAtAkCGx8Rnohik/XtaqiYUJtgW2g==",
+ "version": "7.9.3",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.3.tgz",
+ "integrity": "sha512-4o2iWCFIwhI/eYAIL43+cjORXYn/aRQPgtFRRZb3VzoyQ5Uej0Bmqj7437L97N9NJW4wnicSwLOLS+yCXfAPgg==",
"license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
@@ -14183,12 +14247,12 @@
}
},
"node_modules/react-router-dom": {
- "version": "7.9.1",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.1.tgz",
- "integrity": "sha512-U9WBQssBE9B1vmRjo9qTM7YRzfZ3lUxESIZnsf4VjR/lXYz9MHjvOxHzr/aUm4efpktbVOrF09rL/y4VHa8RMw==",
+ "version": "7.9.3",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.3.tgz",
+ "integrity": "sha512-1QSbA0TGGFKTAc/aWjpfW/zoEukYfU4dc1dLkT/vvf54JoGMkW+fNA+3oyo2gWVW1GM7BxjJVHz5GnPJv40rvg==",
"license": "MIT",
"dependencies": {
- "react-router": "7.9.1"
+ "react-router": "7.9.3"
},
"engines": {
"node": ">=20.0.0"
@@ -14347,6 +14411,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
"integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"indent-string": "^4.0.0",
@@ -14362,6 +14427,19 @@
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
"license": "MIT"
},
+ "node_modules/redux-mock-store": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/redux-mock-store/-/redux-mock-store-1.5.5.tgz",
+ "integrity": "sha512-YxX+ofKUTQkZE4HbhYG4kKGr7oCTJfB0GLy7bSeqx86GLpGirrbUWstMnqXkqHNaQpcnbMGbof2dYs5KsPE6Zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash.isplainobject": "^4.0.6"
+ },
+ "peerDependencies": {
+ "redux": "*"
+ }
+ },
"node_modules/redux-saga": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/redux-saga/-/redux-saga-1.3.0.tgz",
@@ -15864,6 +15942,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"min-indent": "^1.0.0"
@@ -17186,27 +17265,6 @@
}
}
},
- "node_modules/webpack-dev-server/node_modules/ws": {
- "version": "8.18.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
- "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
- "license": "MIT",
- "engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
"node_modules/webpack-manifest-plugin": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz",
@@ -17833,16 +17891,16 @@
}
},
"node_modules/ws": {
- "version": "7.5.10",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
- "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"engines": {
- "node": ">=8.3.0"
+ "node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
- "utf-8-validate": "^5.0.2"
+ "utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
diff --git a/package.json b/package.json
index 3d18432..46693f5 100644
--- a/package.json
+++ b/package.json
@@ -6,14 +6,12 @@
"@fortawesome/fontawesome-free": "^7.0.1",
"@reduxjs/toolkit": "^2.9.0",
"@testing-library/dom": "^10.4.1",
- "@testing-library/jest-dom": "^6.8.0",
- "@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.12.2",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-redux": "^9.2.0",
- "react-router-dom": "^7.9.1",
+ "react-router-dom": "^7.9.3",
"react-saga": "^0.3.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
@@ -21,7 +19,7 @@
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
- "test": "react-scripts test",
+ "test": "jest",
"eject": "react-scripts eject"
},
"eslintConfig": {
@@ -30,6 +28,11 @@
"react-app/jest"
]
},
+ "jest": {
+ "setupFilesAfterEnv": [
+ "/src/setupTests.js"
+ ]
+ },
"browserslist": {
"production": [
">0.2%",
@@ -41,5 +44,13 @@
"last 1 firefox version",
"last 1 safari version"
]
+ },
+ "devDependencies": {
+ "@babel/preset-react": "^7.27.1",
+ "@testing-library/jest-dom": "^6.8.0",
+ "@testing-library/react": "^16.3.0",
+ "jest": "^27.5.1",
+ "jest-environment-jsdom": "^27.0.3",
+ "redux-mock-store": "^1.5.5"
}
}
diff --git a/src/App.test.js b/src/App.test.js
deleted file mode 100644
index 1f03afe..0000000
--- a/src/App.test.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import App from './App';
-
-test('renders learn react link', () => {
- render();
- const linkElement = screen.getByText(/learn react/i);
- expect(linkElement).toBeInTheDocument();
-});
diff --git a/src/features/cart/_tests/cartItem.test.jsx b/src/features/cart/_tests/cartItem.test.jsx
new file mode 100644
index 0000000..3edda7f
--- /dev/null
+++ b/src/features/cart/_tests/cartItem.test.jsx
@@ -0,0 +1,72 @@
+/**
+ * @jest-environment jsdom
+ */
+
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+import CartItem from '../CartItem';
+
+// Mock redux useDispatch
+const mockDispatch = jest.fn();
+jest.mock('react-redux', () => ({
+ useDispatch: () => mockDispatch,
+}));
+
+// Mock OrderReview component when actions is false
+jest.mock('../../orders/review', () => () => );
+
+describe('CartItem component', () => {
+ const baseCartItem = {
+ id: 1,
+ image: 'test-image.jpg',
+ title: 'Test Product',
+ category: 'electronics',
+ unitPrice: 100,
+ quantity: 1,
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test('renders cart item details correctly', () => {
+ render();
+
+ expect(screen.getByAltText('Test Product')).toBeInTheDocument();
+ expect(screen.getByText('Test Product')).toBeInTheDocument();
+ expect(screen.getByText('electronics')).toBeInTheDocument();
+ expect(screen.getByText(/Price:/)).toBeInTheDocument("$100");
+ expect(screen.getByText('1')).toBeInTheDocument();
+ });
+
+ test('shows delete button when quantity is 1, and clicking calls dispatch with deleteFromCart', () => {
+ render();
+
+ const deleteBtn = screen.getByTestId('delete-icon') ;
+ fireEvent.click(deleteBtn);
+ expect(mockDispatch).toHaveBeenCalled();
+ // Optional: check called action type and payload if you mock cartSlice action creators
+ });
+
+ test('shows decrease button when quantity is > 1, and clicking calls dispatch with decreaseItemQuantity', () => {
+ render();
+
+ const decreaseBtn =screen.getByTestId('minus-icon') ;
+ fireEvent.click(decreaseBtn);
+ expect(mockDispatch).toHaveBeenCalled();
+ });
+
+ test('shows increase button and clicking calls dispatch with increaseItemQuantity', () => {
+ render();
+
+ const increaseBtn = screen.getByTestId('plus-icon') ;
+ fireEvent.click(increaseBtn);
+ expect(mockDispatch).toHaveBeenCalled();
+ });
+
+ test('renders OrderReview component when actions is false', () => {
+ render();
+
+ expect(screen.getByTestId('order-review')).toBeInTheDocument();
+ });
+});
diff --git a/src/features/cart/cartItem.jsx b/src/features/cart/cartItem.jsx
index 1bf483d..9f8eb51 100644
--- a/src/features/cart/cartItem.jsx
+++ b/src/features/cart/cartItem.jsx
@@ -33,7 +33,7 @@ export default function CartItem({ cartItem, actions }) {
className="btn delete-btn"
onClick={() => dispatch(deleteFromCart(cartItem.id))}
>
-
+
)}
@@ -42,7 +42,7 @@ export default function CartItem({ cartItem, actions }) {
className="btn delete-btn"
onClick={() => dispatch(decreaseItemQuantity(cartItem.id))}
>
-
+
)}
@@ -51,7 +51,7 @@ export default function CartItem({ cartItem, actions }) {
className="btn add-btn"
onClick={() => dispatch(increaseItemQuantity(cartItem.id))}
>
-
+
)}
diff --git a/src/features/orders/_tests/orderList.test.jsx b/src/features/orders/_tests/orderList.test.jsx
new file mode 100644
index 0000000..77b72a0
--- /dev/null
+++ b/src/features/orders/_tests/orderList.test.jsx
@@ -0,0 +1,62 @@
+/**
+ * @jest-environment jsdom
+ */
+
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import OrderList from "../orderList";
+import { useSelector } from "react-redux";
+import * as reactRedux from 'react-redux';
+
+// Mock CartItem to isolate OrderList testing
+jest.mock("../../cart/cartItem", () => ({ cartItem, actions }) => (
+
{cartItem.title}
+));
+
+jest.mock('react-redux', () => ({
+ ...jest.requireActual('react-redux'),
+ useSelector: jest.fn(), // Make useSelector a Jest mock function
+}));
+
+describe("OrderList component", () => {
+ beforeEach(() => {
+ reactRedux.useSelector.mockImplementation((selector) =>
+ selector({
+ order: {
+ orders: [
+ { id: 1, title: "Order 1" },
+ { id: 2, title: "Order 2" },
+ ],
+ },
+ })
+ );
+ });
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test("renders order list header and items from Redux state", () => {
+ // Mock useSelector to return orders array
+ useSelector.mockImplementation((selectorFn) =>
+ selectorFn({
+ order: {
+ orders: [
+ { id: 1, title: "Order 1" },
+ { id: 2, title: "Order 2" },
+ ],
+ },
+ })
+ );
+
+ render(
);
+
+ expect(screen.getByText(/your order\(s\)/i)).toBeInTheDocument();
+
+ // Check mocked CartItem components rendered for each order entry
+ const orderItems = screen.getAllByTestId("cart-item");
+ expect(orderItems).toHaveLength(2);
+ expect(orderItems[0]).toHaveTextContent("Order 1");
+ expect(orderItems[1]).toHaveTextContent("Order 2");
+ });
+});
diff --git a/src/features/orders/_tests/review.test.js b/src/features/orders/_tests/review.test.js
new file mode 100644
index 0000000..96391d0
--- /dev/null
+++ b/src/features/orders/_tests/review.test.js
@@ -0,0 +1,105 @@
+/**
+ * @jest-environment jsdom
+ */
+
+import React from "react";
+import { render, screen, fireEvent } from "@testing-library/react";
+import OrderReview from "../review";
+
+// Mock useDispatch hook
+const mockDispatch = jest.fn();
+jest.mock("react-redux", () => ({
+ useDispatch: () => mockDispatch,
+}));
+
+describe("OrderReview component", () => {
+ beforeAll(() => {
+ global.crypto = {
+ randomUUID: jest.fn(() => "test-uuid"),
+ };
+ });
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test("renders no reviews message initially", () => {
+ render(
);
+ expect(screen.getByText(/no reviews yet/i)).toBeInTheDocument();
+ });
+
+ test("allows user to submit a review", () => {
+ render(
);
+
+ // Click on the 5th star to give rating 5
+ const stars = screen.getAllByText("★");
+ fireEvent.click(stars[4]);
+
+ // Input comment
+ const textarea = screen.getByPlaceholderText(/write your review/i);
+ fireEvent.change(textarea, { target: { value: "Great product!" } });
+
+ // Click submit button
+ const submitButton = screen.getByRole("button", { name: /submit review/i });
+ fireEvent.click(submitButton);
+
+ // Verify dispatch was called with an object containing rating, comments, itemId
+ expect(mockDispatch).toHaveBeenCalledWith(
+ expect.objectContaining({
+ type: expect.any(String),
+ payload: expect.objectContaining({
+ itemId: "123",
+ rating: 5,
+ comments: "Great product!",
+ }),
+ })
+ );
+
+ // Review should appear in the review list
+ expect(screen.getByText(/great product!/i)).toBeInTheDocument();
+ });
+
+ test("prevents submitting empty rating or comment", () => {
+ render(
);
+
+ const submitButton = screen.getByRole("button", { name: /submit review/i });
+ fireEvent.click(submitButton);
+
+ // Dispatch should not be called
+ expect(mockDispatch).not.toHaveBeenCalled();
+ });
+
+ test("allows editing and deleting reviews", () => {
+ render(
);
+
+ // Add a review first
+ const stars = screen.getAllByText("★");
+ fireEvent.click(stars[4]);
+ const textarea = screen.getByPlaceholderText(/write your review/i);
+ fireEvent.change(textarea, { target: { value: "Nice product!" } });
+ fireEvent.click(screen.getByRole("button", { name: /submit review/i }));
+
+ // Click edit button (the edit icon button)
+ const editButton = screen.getByTestId("edit-icon");
+ fireEvent.click(editButton);
+
+ // The textarea should be filled with existing comment
+ expect(textarea.value).toBe("Nice product!");
+
+ // Change comment and submit updated review
+ fireEvent.change(textarea, { target: { value: "Updated review" } });
+ fireEvent.click(screen.getByRole("button", { name: /update review/i }));
+
+ expect(mockDispatch).toHaveBeenCalledTimes(2); // 1 for add, 1 for update
+ expect(screen.getByText(/updated review/i)).toBeInTheDocument();
+
+ // Mock window.confirm to always return true for delete
+ window.confirm = jest.fn(() => true);
+
+ // Click delete button
+ const deleteButton = screen.getByTitle("Delete");
+ fireEvent.click(deleteButton);
+
+ expect(mockDispatch).toHaveBeenCalledTimes(3); // 3rd call for delete
+ });
+});
diff --git a/src/features/orders/review.jsx b/src/features/orders/review.jsx
index 71fb221..7ccd86c 100644
--- a/src/features/orders/review.jsx
+++ b/src/features/orders/review.jsx
@@ -10,9 +10,7 @@ export default function OrderReview({ itemId }) {
const [reviewId, setReviewId] = useState(null);
const dispatch = useDispatch();
-// const currentState = useSelector((state) => state.order);
-// console.log(currentState);
- // if(currentState){}
+
const handleSubmit = () => {
if (rating === 0 || comment.trim() === "") return;
@@ -102,7 +100,7 @@ export default function OrderReview({ itemId }) {
alignItems: "center",
}}
>
- {console.log("review", review)}
+
{"★".repeat(review.rating)}
@@ -122,7 +120,7 @@ export default function OrderReview({ itemId }) {
cursor: "pointer",
}}
>
-
+