Skip to content

Commit

Permalink
merge develop
Browse files Browse the repository at this point in the history
  • Loading branch information
EddyShimwa committed Jul 26, 2024
2 parents c8d62a3 + c75ab18 commit 5b99673
Show file tree
Hide file tree
Showing 41 changed files with 5,626 additions and 840 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ module.exports = {
'react/self-closing-comp': 0,
'react/jsx-props-no-spreading': 0,
'@typescript-eslint/no-explicit-any': 0,
'jsx-a11y/label-has-associated-control': 0,
'jsx-a11y/control-has-associated-label': 0,
'react/no-array-index-key': 0,
'no-nested-ternary': 0,
'no-param-reassign': [
'error',
{ props: true, ignorePropertyModificationsFor: ['state'] },
Expand Down
6 changes: 6 additions & 0 deletions .hintrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
{
"button-name": "off"
}
],
"axe/parsing": [
"default",
{
"duplicate-id-active": "off"
}
]
}
}
2,850 changes: 2,283 additions & 567 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@mui/material": "^5.16.4",
"@react-jvectormap/core": "^1.0.4",
"@react-jvectormap/world": "^1.1.2",
"@reduxjs/toolkit": "^2.2.5",
"@reduxjs/toolkit": "^2.2.6",
"@testing-library/user-event": "^14.5.2",
"@types/react-redux": "^7.1.33",
"@types/react-router-dom": "^5.3.3",
Expand Down Expand Up @@ -59,7 +59,7 @@
"yup": "^1.4.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.4.5",
"@testing-library/jest-dom": "^6.4.8",
"@testing-library/react": "^16.0.0",
"@types/dotenv": "^8.2.0",
"@types/jest": "^29.5.12",
Expand All @@ -68,7 +68,7 @@
"@types/node": "^20.14.7",
"@types/react": "^18.3.3",
"@types/react-color": "^3.0.12",
"@types/react-dom": "^18.2.22",
"@types/react-dom": "^18.3.0",
"@types/react-simple-maps": "^3.0.4",
"@types/react-slider": "^1.3.6",
"@types/redux-mock-store": "^1.0.6",
Expand Down
8 changes: 4 additions & 4 deletions src/__test__/Checkout/checkout.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ describe('checkoutSlice', () => {
it('should handle initial state', () => {
expect(store.getState().checkout).toEqual({
checkout: {
id: 31,
totalAmount: 160,
id: -1,
totalAmount: 0,
status: 'Pending',
couponCode: '',
deliveryInfo: {
Expand Down Expand Up @@ -91,7 +91,7 @@ describe('checkoutSlice', () => {
city: 'Anytown',
zip: '12345',
},
id: 31,
id: -1,
orderDetails: [
{
id: 41,
Expand All @@ -102,7 +102,7 @@ describe('checkoutSlice', () => {
paid: true,
paymentInfo: null,
status: 'Pending',
totalAmount: 160,
totalAmount: 0,
trackingNumber: 'Tr280585',
updatedAt: '2024-07-22T11:01:20.291Z',
},
Expand Down
185 changes: 185 additions & 0 deletions src/__test__/Coupons/CouponsFeature.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import { configureStore } from '@reduxjs/toolkit';

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import axios from 'axios';
import couponsReducer, {
fetchCoupons,
fetchMyCoupons,
createCoupon,
updateCoupon,
deleteCoupon,
} from '@/features/Coupons/CouponsFeature';

vi.mock('axios');

const createTestStore = () =>
configureStore({ reducer: { coupons: couponsReducer } });
let store: any;

describe('couponsSlice', () => {
beforeEach(() => {
store = createTestStore();
});

afterEach(() => {
vi.clearAllMocks();
});

it('should handle initial state', () => {
const { coupons } = store.getState();
expect(coupons).toEqual({
coupons: [],
loading: false,
error: null,
});
});

describe('fetchCoupons', () => {
it('should handle fetchCoupons.pending', () => {
store.dispatch(fetchCoupons.pending('requestId'));
const { coupons } = store.getState();
expect(coupons.loading).toBe(true);
});

it('should handle fetchCoupons.fulfilled', async () => {
const mockCoupons = [{ id: 1, code: 'TEST' }];
(axios.get as any).mockResolvedValueOnce({ data: mockCoupons });

await store.dispatch(fetchCoupons());
const { coupons } = store.getState();
expect(coupons.loading).toBe(false);
expect(coupons.coupons).toEqual(mockCoupons);
});

it('should handle fetchCoupons.rejected', async () => {
const error = 'Failed to fetch coupons';
(axios.get as any).mockRejectedValueOnce(new Error(error));

await store.dispatch(fetchCoupons());
const { coupons } = store.getState();
expect(coupons.loading).toBe(false);
expect(coupons.error).toBe(error);
});
});

describe('fetchMyCoupons', () => {
it('should handle fetchMyCoupons.pending', () => {
store.dispatch(fetchMyCoupons.pending('requestId'));
const { coupons } = store.getState();
expect(coupons.loading).toBe(true);
});

it('should handle fetchMyCoupons.fulfilled', async () => {
const mockCoupons = [{ id: 1, code: 'MYCOUPON' }];
(axios.get as any).mockResolvedValueOnce({ data: mockCoupons });

await store.dispatch(fetchMyCoupons());
const { coupons } = store.getState();
expect(coupons.loading).toBe(false);
expect(coupons.coupons).toEqual(mockCoupons);
});

it('should handle fetchMyCoupons.rejected', async () => {
const error = 'Failed to fetch coupons';
(axios.get as any).mockRejectedValueOnce(new Error(error));

await store.dispatch(fetchMyCoupons());
const { coupons } = store.getState();
expect(coupons.loading).toBe(false);
expect(coupons.error).toBe(error);
});
});
describe('createCoupon', () => {
it('should handle createCoupon.pending', () => {
const dummyRequestId = 'dummyRequestId';
const dummyArgs = {
newCoupon: {
description: '',
percentage: 0,
expirationDate: '',
applicableProducts: [],
},
token: 'dummyToken',
};

store.dispatch(createCoupon.pending(dummyRequestId, dummyArgs));
const { coupons } = store.getState();
expect(coupons.loading).toBe(true);
});

it('should handle createCoupon.fulfilled', async () => {
const newCoupon = {
id: 1,
description: 'NEWCOUPON',
percentage: 1,
expirationDate: '2024-02-01',
applicableProducts: [1, 2],
};
(axios.post as any).mockResolvedValueOnce({ data: newCoupon });

await store.dispatch(createCoupon({ newCoupon, token: 'testToken' }));
const { coupons } = store.getState();
expect(coupons.loading).toBe(false);
expect(coupons.coupons).toContainEqual(newCoupon);
});

it('should handle createCoupon.rejected', async () => {
const error = 'Failed to create coupon';
(axios.post as any).mockRejectedValueOnce(new Error(error));
const invalidCoupon = {
description: '',
percentage: 0,
expirationDate: '',
applicableProducts: [],
};

await store.dispatch(
createCoupon({ newCoupon: invalidCoupon, token: 'testToken' })
);
const { coupons } = store.getState();
expect(coupons.loading).toBe(false);
expect(coupons.error).toBe(error);
});
});

describe('updateCoupon', () => {
it('should handle updateCoupon.rejected', async () => {
const error = 'Failed to update coupon';
(axios.put as any).mockRejectedValueOnce(new Error(error));

const updatedCoupon = {
id: 1,
description: 'UPDATED DESCRIPTION',
percentage: 10,
expirationDate: '2024-12-31',
applicableProducts: [1, 2, 3],
code: 'UPDATEDCOUPON',
};

await store.dispatch(updateCoupon(updatedCoupon));
const { coupons } = store.getState();
expect(coupons.error).toBe(error);
});
});

describe('deleteCoupon', () => {
it('should handle deleteCoupon.fulfilled', async () => {
const couponId = 1;
(axios.delete as any).mockResolvedValueOnce({ data: { id: couponId } });

await store.dispatch(deleteCoupon({ couponId, token: 'testToken' }));
const { coupons } = store.getState();
const coupon = coupons.coupons.find((c: any) => c.id === couponId);
expect(coupon).toBeUndefined();
});

it('should handle deleteCoupon.rejected', async () => {
const error = 'Failed to delete coupon';
(axios.delete as any).mockRejectedValueOnce(new Error(error));

await store.dispatch(deleteCoupon({ couponId: 1, token: 'testToken' }));
const { coupons } = store.getState();
expect(coupons.error).toBe(error);
});
});
});
94 changes: 94 additions & 0 deletions src/__test__/TableUserRole.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import { vi } from 'vitest';
import axios from 'axios';
import TableUserRole from '@/components/dashBoard/UserRole';
import { showErrorToast } from '@/utils/ToastConfig';
import userRoleSlice from '@/features/userRole/userRoleSlice';

vi.mock('@/utils/ToastConfig', () => ({
showErrorToast: vi.fn(),
showSuccessToast: vi.fn(),
}));

vi.mock('axios');

const renderWithProviders = (ui: React.ReactElement) => {
const store = configureStore({
reducer: {
userRoles: userRoleSlice,
},
});
return render(<Provider store={store}>{ui}</Provider>);
};

describe('TableUserRole', () => {
beforeEach(() => {
vi.clearAllMocks();
(axios.get as jest.Mock).mockResolvedValue({
data: { data: [{ id: 1, name: 'Admin', permissions: [] }] },
});
});

it('renders TableUserRole component', () => {
renderWithProviders(<TableUserRole />);
expect(screen.getByText('Register Role')).toBeInTheDocument();
});

it('fetches all roles on mount', async () => {
renderWithProviders(<TableUserRole />);
await waitFor(() => {
expect(screen.getByText('Register Role')).toBeInTheDocument();
});
});

it('shows error when role name is empty', async () => {
renderWithProviders(<TableUserRole />);

fireEvent.click(screen.getByText('Add Role'));

await waitFor(() => {
expect(showErrorToast).toHaveBeenCalledWith('Role name cannot be empty');
});
});

it('adds and removes permissions', async () => {
renderWithProviders(<TableUserRole />);

const permissionInput = screen.getByPlaceholderText('Enter permissions');
fireEvent.change(permissionInput, { target: { value: 'Permission 1' } });
fireEvent.click(screen.getByText('+ Add Permissions'));

expect(screen.getByText('Permission 1')).toBeInTheDocument();

const removePermissionButton = screen.getByText('X', {
selector: 'button',
});
fireEvent.click(removePermissionButton);

await waitFor(() => {
expect(screen.queryByText('Permission 1')).not.toBeInTheDocument();
});
});

it('adds a new role successfully', async () => {
renderWithProviders(<TableUserRole />);

const roleNameInput = screen.getByPlaceholderText('Role Name');
const permissionInput = screen.getByPlaceholderText('Enter permissions');
const addPermissionsButton = screen.getByText('+ Add Permissions');
const addRoleButton = screen.getByText('Add Role');

fireEvent.change(roleNameInput, { target: { value: 'New Role' } });
fireEvent.change(permissionInput, { target: { value: 'Permission 1' } });
fireEvent.click(addPermissionsButton);

fireEvent.click(addRoleButton);

await waitFor(() => {
expect(screen.queryByText('Permission 1')).not.toBeInTheDocument();
});
});
});
Loading

0 comments on commit 5b99673

Please sign in to comment.