Skip to content

Commit

Permalink
ft(order): A buyer and seller should be manage orders
Browse files Browse the repository at this point in the history
    - A buyer should see their orders and status
    - A seller should see their orders made on their products

[Delivers #187900465]
  • Loading branch information
yvanddniyo committed Jul 18, 2024
1 parent 3674d21 commit 33da498
Show file tree
Hide file tree
Showing 16 changed files with 861 additions and 14 deletions.
35 changes: 32 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
"@radix-ui/react-navigation-menu": "^1.1.4",
"@reduxjs/toolkit": "^2.2.5",
"@tanstack/react-query": "^5.45.1",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
"@testing-library/user-event": "^14.5.2",
"axios": "^1.7.2",
"axios-mock-adapter": "^1.22.0",
Expand All @@ -42,10 +40,13 @@
"jest-environment-jsdom": "^29.7.0",
"jest-fetch-mock": "^3.0.3",
"jest-mock-extended": "^3.0.7",
"jwt-decode": "^4.0.0",
"moment": "^2.30.1",
"node-fetch": "^3.3.2",
"npm": "^10.8.1",
"prop-types": "^15.8.1",
"react": "^18.3.1",
"react-currency-format": "^1.1.0",
"react-dom": "^18.3.1",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.51.5",
Expand All @@ -66,7 +67,6 @@
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@testing-library/dom": "^10.2.0",
"@testing-library/jest-dom": "^6.4.6",
"@types/jest": "^29.5.12",
"@types/node": "^20.14.8",
"@types/react": "^18.2.66",
Expand Down
64 changes: 64 additions & 0 deletions src/__test__/deleteNotify.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import "@testing-library/jest-dom/jest-globals";
import "@testing-library/jest-dom";
import { render, screen, fireEvent } from "@testing-library/react";
import { Provider } from "react-redux";
import { BrowserRouter as Router } from "react-router-dom";

import store from "../redux/store";
import DeleteNotify from "../components/common/notify/DeleteNotify";

describe("DeleteNotify component", () => {
const mockOnConfirm = jest.fn();
const mockOnCancel = jest.fn();

beforeEach(() => {
render(
<Provider store={store}>
<Router>
<DeleteNotify onConfirm={mockOnConfirm} onCancel={mockOnCancel} />
</Router>
</Provider>,
);
});

test('renders the "Clear Cart" button', () => {
const clearCartButton = screen.getByText("Clear Cart");
expect(clearCartButton).toBeInTheDocument();
});

test("opens the modal when Clear Cart button is clicked", () => {
const clearCartButton = screen.getByText("Clear Cart");
fireEvent.click(clearCartButton);

const modalHeader = screen.getByText(
"Are you sure you want to delete this product?",
);
expect(modalHeader).toBeInTheDocument();
});

test("calls onConfirm and closes modal when is clicked", () => {
const clearCartButton = screen.getByText("Clear Cart");
fireEvent.click(clearCartButton);

const confirmButton = screen.getByText("Yes, I'm sure");
fireEvent.click(confirmButton);

expect(mockOnConfirm).toHaveBeenCalledTimes(1);
expect(
screen.queryByText("Are you sure you want to delete this product?"),
).not.toBeInTheDocument();
});

test('calls onCancel and closes modal when "No, cancel" is clicked', () => {
const clearCartButton = screen.getByText("Clear Cart");
fireEvent.click(clearCartButton);

const cancelButton = screen.getByText("No, cancel");
fireEvent.click(cancelButton);

expect(mockOnCancel).toHaveBeenCalledTimes(1);
expect(
screen.queryByText("Are you sure you want to delete this product?"),
).not.toBeInTheDocument();
});
});
69 changes: 69 additions & 0 deletions src/__test__/orders.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { orders } from "../../type";
import ordersReducer, {
fetchOrders,
updateOrderStatus,
} from "../redux/reducers/ordersSlice";

describe("orders reducer", () => {
const initialState = {
isLoading: false,
data: [] as unknown as orders,
error: false,
};

it("should handle initial state", () => {
expect(ordersReducer(undefined, { type: "unknown" })).toEqual(initialState);
});

it("should handle fetchOrders.pending", () => {
const action = { type: fetchOrders.pending.type };
const state = ordersReducer(initialState, action);
expect(state).toEqual({
...initialState,
isLoading: true,
});
});

it("should handle fetchOrders.fulfilled", () => {
const mockOrders = [
{ id: 1, status: "pending" },
{ id: 2, status: "completed" },
];
const action = { type: fetchOrders.fulfilled.type, payload: mockOrders };
const state = ordersReducer(initialState, action);
expect(state).toEqual({
...initialState,
isLoading: false,
data: mockOrders,
});
});

it("should handle fetchOrders.rejected", () => {
const action = { type: fetchOrders.rejected.type };
const state = ordersReducer(initialState, action);
expect(state).toEqual({
...initialState,
isLoading: false,
error: true,
});
});

it("should handle updateOrderStatus.pending", () => {
const action = { type: updateOrderStatus.pending.type };
const state = ordersReducer(initialState, action);
expect(state).toEqual({
...initialState,
isLoading: true,
});
});

it("should handle updateOrderStatus.rejected", () => {
const action = { type: updateOrderStatus.rejected.type };
const state = ordersReducer(initialState, action);
expect(state).toEqual({
...initialState,
isLoading: false,
error: true,
});
});
});
2 changes: 1 addition & 1 deletion src/components/common/auth/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const Spinner = () => (
<div className=" w-full h-[80vh] flex justify-center items-center">
<div className=" w-full h-[100vh] flex justify-center items-center">
<div
className="inline-block h-8 w-8 sm:h-16 sm:w-16 animate-spin rounded-full border-4 border-solid border-[#DB4444] border-e-transparent text-danger motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status"
Expand Down
3 changes: 3 additions & 0 deletions src/components/common/header/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ const Navbar: React.FC<InavbarProps> = ({ searchQuery, setSearchQuery }) => {
<NavLink to="/" className="text-nowrap text-white">
New Arrival
</NavLink>
<NavLink to="/orders" className="text-nowrap text-white">
Orders
</NavLink>
</Stack>
</Stack>
</Stack>
Expand Down
9 changes: 5 additions & 4 deletions src/components/dashboard/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { IoBriefcaseOutline, IoSettingsOutline } from "react-icons/io5";
import { AiFillProduct } from "react-icons/ai";
import { MdInsertChartOutlined } from "react-icons/md";
import { FiLogOut } from "react-icons/fi";
import { NavLink, useLocation } from "react-router-dom";
import { Link, NavLink, useLocation } from "react-router-dom";
import { FaCircle } from "react-icons/fa";

interface SidebarProps {
Expand All @@ -14,7 +14,8 @@ interface SidebarProps {
const SideBar: React.FC<SidebarProps> = ({ isOpen }) => {
const location = useLocation();

const getLinkClass = (path: string) => (location.pathname === path ? "text-primary" : "text-dark-gray");
const getLinkClass = (path: string) =>
(location.pathname === path ? "text-primary" : "text-dark-gray");

return (
<div
Expand Down Expand Up @@ -59,9 +60,9 @@ const SideBar: React.FC<SidebarProps> = ({ isOpen }) => {
Add product
</NavLink>
<NavLink
to="/orders"
to="/dashboard/orders"
className={`py-2.5 px-4 flex items-center relative gap-2 text-lg rounded transition duration-200 ${getLinkClass(
"/orders",
"/dashboard/orders",
)}`}
>
<IoBriefcaseOutline className="text-xl" />
Expand Down
Loading

0 comments on commit 33da498

Please sign in to comment.