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 23, 2024
1 parent f306d90 commit dcdbc7c
Show file tree
Hide file tree
Showing 21 changed files with 1,030 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
node-version: "20"

- name: Install dependencies
run: npm install
run: npm install --force

- name: Running test
run: npm run test:coverage
Expand Down
26 changes: 23 additions & 3 deletions package-lock.json

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

5 changes: 2 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 @@ -40,6 +38,7 @@
"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",
Expand All @@ -51,6 +50,7 @@
"react-icons": "^5.2.1",
"react-jwt": "^1.2.1",
"react-loading-skeleton": "^3.4.0",
"react-number-format": "^5.4.0",
"react-redux": "^9.1.2",
"react-router-dom": "^6.23.1",
"react-toastify": "^10.0.5",
Expand All @@ -66,7 +66,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
82 changes: 73 additions & 9 deletions src/__test__/cartSlice.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-nochec
import { configureStore } from "@reduxjs/toolkit";

import cartReducer, {
Expand Down Expand Up @@ -49,6 +48,16 @@ describe("cartManageSlice", () => {
expect(store.getState().cart.isLoading).toBeFalsy();
});

it("should handle cartManage.rejected", async () => {
const errorMessage = "Network Error";
(axios.get as jest.Mock).mockRejectedValue(new Error(errorMessage));

await store.dispatch(cartManage());

expect(store.getState().cart.error).toBeTruthy();
expect(store.getState().cart.isLoading).toBeFalsy();
});

it("should handle addToCart.fulfilled", async () => {
const mockItem = { id: "2", quantity: 1 };
(axios.post as jest.Mock).mockResolvedValue({ data: mockItem });
Expand All @@ -58,31 +67,86 @@ describe("cartManageSlice", () => {
expect(store.getState().cart.data).toContainEqual(mockItem);
});

it("should handle addToCart.rejected", async () => {
const errorMessage = "Failed to add item to cart";
(axios.post as jest.Mock).mockRejectedValue(new Error(errorMessage));

await store.dispatch(addToCart({ productId: 2, quantity: 1 }));

expect(store.getState().cart.add.error).toEqual(errorMessage);
});

it("should handle removeFromCart.fulfilled", async () => {
(axios.put as jest.Mock).mockResolvedValue({ data: {} });
// @ts-ignore
await store.dispatch(removeFromCart("1"));
await store.dispatch(removeFromCart());

expect(store.getState().cart.remove.isLoading).toBeFalsy();
});
it("should handle clear FromCart.fulfilled", async () => {

it("should handle removeFromCart.rejected", async () => {
const errorMessage = "Failed to remove item from cart";
(axios.put as jest.Mock).mockRejectedValue(new Error(errorMessage));

await store.dispatch(removeFromCart());

expect(store.getState().cart.remove.error).toBeTruthy();
});

it("should handle cartDelete.fulfilled", async () => {
(axios.delete as jest.Mock).mockResolvedValue({ data: {} });
// @ts-ignore
await store.dispatch(cartDelete("1"));
await store.dispatch(cartDelete());

expect(store.getState().cart.delete.isLoading).toBeFalsy();
});

it("should handle updateCarts.fulfilled", async () => {
const mockItem = { productId: "1", quantity: 3 };
it("should handle cartDelete.rejected", async () => {
const errorMessage = "Failed to delete cart";
(axios.delete as jest.Mock).mockRejectedValue(new Error(errorMessage));

await store.dispatch(cartDelete());

expect(store.getState().cart.delete.error).toBeTruthy();
});

it("should handle updateCarts return undefined.", async () => {
const mockItem = { id: "1", quantity: 3 };
(axios.patch as jest.Mock).mockResolvedValue({ data: mockItem });

store.dispatch({
type: "carts/cartManage/fulfilled",
payload: [{ productId: "1", quantity: 2 }],
payload: [{ id: "1", quantity: 2 }],
});
await store.dispatch(updateCarts({ productId: "1", quantity: 3 }));

expect(store.getState().cart.data[0]).toEqual(undefined);
});

it("should handle updateCarts.rejected", async () => {
const errorMessage = "Failed to update cart";
(axios.patch as jest.Mock).mockRejectedValue(new Error(errorMessage));

await store.dispatch(updateCarts({ productId: "1", quantity: 3 }));

expect(store.getState().cart.update.error).toBeTruthy();
});

it("should return undefined increaseQuantity", () => {
store.dispatch({
type: "carts/cartManage/fulfilled",
payload: [{ id: "1", quantity: 2 }],
});
store.dispatch(increaseQuantity("1"));

expect(store.getState().cart.data.quantity).toEqual(undefined);
});

it("should return undefined decreaseQuantity", () => {
store.dispatch({
type: "carts/cartManage/fulfilled",
payload: [{ id: "1", quantity: 2 }],
});
store.dispatch(decreaseQuantity("1"));

expect(store.getState().cart.data.quantity).toEqual(undefined);
});
});
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();
});
});
99 changes: 99 additions & 0 deletions src/__test__/orders.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
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,
});
});

it("should handle updateOrderStatus.fulfilled", () => {
const initialStateWithData: any = {
...initialState,
data: [
{
order: { id: 1 },
products: [
{ id: 101, status: "pending" },
{ id: 102, status: "pending" },
],
},
{
order: { id: 2 },
products: [{ id: 201, status: "pending" }],
},
],
};

const action = {
type: updateOrderStatus.fulfilled.type,
payload: { orderId: 1, productId: 102, status: "completed" },
};

const state = ordersReducer(initialStateWithData, action);

expect(state.data[0].products[1].status).toEqual("completed");
expect(state.data[0].products[0].status).toEqual("pending");
expect(state.data[1].products[0].status).toEqual("pending");
});
});
Loading

0 comments on commit dcdbc7c

Please sign in to comment.