Skip to content

Commit

Permalink
Added test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
gkbishnoi07 committed Jan 15, 2025
1 parent fb0328a commit 8320e05
Show file tree
Hide file tree
Showing 3 changed files with 339 additions and 89 deletions.
376 changes: 294 additions & 82 deletions src/components/OrganizationCard/OrganizationCard.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,49 @@
import '@testing-library/jest-dom';
import { vi } from 'vitest';
import React from 'react';
import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import { MockedProvider } from '@apollo/client/testing';
import { I18nextProvider } from 'react-i18next';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import type { MockedResponse } from '@apollo/client/testing';
import { toast } from 'react-toastify';
import i18n from 'i18next';
import OrganizationCard from './OrganizationCard';
import { TestWrapper } from '../../components/test-utils/TestWrapper';
import {
SEND_MEMBERSHIP_REQUEST,
JOIN_PUBLIC_ORGANIZATION,
CANCEL_MEMBERSHIP_REQUEST,
} from 'GraphQl/Mutations/OrganizationMutations';
import { USER_JOINED_ORGANIZATIONS } from 'GraphQl/Queries/OrganizationQueries';

// Mock hooks
const mockGetItem = vi.fn();
vi.mock('utils/useLocalstorage', () => ({
__esModule: true,
default: () => ({
getItem: () => mockGetItem(),
setItem: vi.fn(),
}),
}));

vi.mock('react-toastify', () => ({
toast: {
success: vi.fn(),
error: vi.fn(),
},
}));

const mockNavigate = vi.fn();
vi.mock('react-router-dom', () => {
const actual = vi.importActual('react-router-dom');
return {
...actual,
useNavigate: () => mockNavigate,
BrowserRouter: ({
children,
}: {
children: React.ReactNode;
}): JSX.Element => <div>{children}</div>,
};
});

// Initialize i18n for testing
i18n.init({
Expand All @@ -16,7 +55,7 @@ i18n.init({
MembershipRequestSent: 'Request sent',
orgJoined: 'Joined',
AlreadyJoined: 'Already joined',
errorOccured: 'Error occurred',
errorOccured: 'error occurred',
MembershipRequestNotFound: 'Request not found',
MembershipRequestWithdrawn: 'Request withdrawn',
visit: 'Visit',
Expand All @@ -32,85 +71,258 @@ i18n.init({
},
});

// Wrapper component to provide all required contexts
const TestWrapper = ({
children,
}: {
children: React.ReactNode;
}): React.ReactElement => {
return (
<MockedProvider>
<I18nextProvider i18n={i18n}>
<BrowserRouter>{children}</BrowserRouter>
</I18nextProvider>
</MockedProvider>
);
};

describe('Testing the Organization Card', () => {
it('should render props and text elements test for the page component', () => {
const props = {
id: '123',
image: 'https://via.placeholder.com/80',
firstName: 'John',
lastName: 'Doe',
name: 'Sample',
description: '',
admins: [],
members: [],
address: {
city: '',
countryCode: '',
line1: '',
postalCode: '',
state: '',
// Success mocks
const successMocks: MockedResponse[] = [
{
request: {
query: SEND_MEMBERSHIP_REQUEST,
variables: { organizationId: '123' },
},
result: {
data: { sendMembershipRequest: { success: true } },
},
},
{
request: {
query: JOIN_PUBLIC_ORGANIZATION,
variables: { organizationId: '123' },
},
result: {
data: { joinPublicOrganization: { success: true } },
},
},
{
request: {
query: CANCEL_MEMBERSHIP_REQUEST,
variables: { membershipRequestId: 'requestId' },
},
result: {
data: { cancelMembershipRequest: { success: true } },
},
},
{
request: {
query: USER_JOINED_ORGANIZATIONS,
variables: { userId: 'mockUserId' },
},
result: {
data: {
organizations: [
{
_id: '123',
name: 'Test Org',
},
],
},
membershipRequestStatus: '',
userRegistrationRequired: false,
membershipRequests: [],
};

render(
<TestWrapper>
<OrganizationCard isJoined={false} {...props} />
</TestWrapper>,
);

expect(screen.getByText(props.name)).toBeInTheDocument();
expect(screen.getByText(/Admins/i)).toBeInTheDocument();
expect(screen.getByText(/Members/i)).toBeInTheDocument();
},
},
];

// Error mocks
const errorMocks: MockedResponse[] = [
{
request: {
query: SEND_MEMBERSHIP_REQUEST,
variables: { organizationId: '123' },
},
error: new Error('Failed to send request'),
},
{
request: {
query: JOIN_PUBLIC_ORGANIZATION,
variables: { organizationId: '123' },
},
error: new Error('Failed to join organization'),
},
{
request: {
query: CANCEL_MEMBERSHIP_REQUEST,
variables: { membershipRequestId: 'requestId' },
},
error: new Error('Failed to cancel request'),
},
];

describe('OrganizationCard Component', () => {
const defaultProps = {
id: '123',
image: 'https://via.placeholder.com/80',
firstName: 'John',
lastName: 'Doe',
name: 'Sample',
description: '',
admins: [],
members: [],
address: {
city: '',
countryCode: '',
line1: '',
postalCode: '',
state: '',
},
membershipRequestStatus: '',
userRegistrationRequired: false,
membershipRequests: [],
};

beforeEach(() => {
vi.clearAllMocks();
mockGetItem.mockReturnValue('mockUserId');
});

it('Should render text elements when props value is not passed', () => {
const props = {
id: '123',
image: '',
firstName: 'John',
lastName: 'Doe',
name: 'Sample',
description: '',
admins: [],
members: [],
address: {
city: '',
countryCode: '',
line1: '',
postalCode: '',
state: '',
},
membershipRequestStatus: '',
userRegistrationRequired: false,
membershipRequests: [],
};

render(
<TestWrapper>
<OrganizationCard isJoined={false} {...props} />
</TestWrapper>,
);

expect(screen.getByText(props.name)).toBeInTheDocument();
expect(screen.getByText(/Admins/i)).toBeInTheDocument();
expect(screen.getByText(/Members/i)).toBeInTheDocument();
// Basic Rendering Tests
describe('Rendering', () => {
it('should render props and text elements', () => {
render(
<TestWrapper mocks={successMocks}>
<OrganizationCard isJoined={false} {...defaultProps} />
</TestWrapper>,
);

expect(screen.getByText(defaultProps.name)).toBeInTheDocument();
expect(screen.getByText(/Admins/i)).toBeInTheDocument();
expect(screen.getByText(/Members/i)).toBeInTheDocument();
});

it('should render without image', () => {
const props = { ...defaultProps, image: '' };
render(
<TestWrapper mocks={successMocks}>
<OrganizationCard isJoined={false} {...props} />
</TestWrapper>,
);

expect(screen.getByText(props.name)).toBeInTheDocument();
});

it('should render full address when provided', () => {
const props = {
...defaultProps,
address: {
city: 'Test City',
countryCode: 'TC',
line1: 'Test Line 1',
postalCode: '12345',
state: 'TS',
},
};

render(
<TestWrapper mocks={successMocks}>
<OrganizationCard isJoined={false} {...props} />
</TestWrapper>,
);

expect(screen.getByText(/Test Line 1/)).toBeInTheDocument();
expect(screen.getByText(/Test City/)).toBeInTheDocument();
expect(screen.getByText(/TC/)).toBeInTheDocument();
});
});

// Hook Tests
describe('Hooks Behavior', () => {
it('should handle localStorage error gracefully', () => {
mockGetItem.mockImplementation(() => {
throw new Error('localStorage error');
});

render(
<TestWrapper mocks={successMocks}>
<OrganizationCard isJoined={false} {...defaultProps} />
</TestWrapper>,
);

const joinButton = screen.getByTestId('joinBtn');
expect(joinButton).toBeInTheDocument();
expect(joinButton).toHaveTextContent('joinNow');
});

it('should navigate to organization page on visit', () => {
render(
<TestWrapper mocks={successMocks}>
<OrganizationCard isJoined={true} {...defaultProps} />
</TestWrapper>,
);

const visitButton = screen.getByTestId('manageBtn');
fireEvent.click(visitButton);
expect(mockNavigate).toHaveBeenCalledWith(
`/user/organization/${defaultProps.id}`,
);
});

it('should correctly translate all text elements', () => {
render(
<TestWrapper mocks={successMocks}>
<OrganizationCard isJoined={false} {...defaultProps} />
</TestWrapper>,
);

const adminText = screen.getByText(/Admins:/);
const memberText = screen.getByText(/Members:/);

expect(adminText).toBeInTheDocument();
expect(memberText).toBeInTheDocument();
});
});

// Mutation Tests
describe('Mutations', () => {
it('should handle joining a private organization successfully', async () => {
render(
<TestWrapper mocks={successMocks}>
<OrganizationCard
{...defaultProps}
userRegistrationRequired={true}
isJoined={false}
/>
</TestWrapper>,
);

const joinButton = screen.getByText('joinNow');
await fireEvent.click(joinButton);

await waitFor(() => {
expect(toast.success).toHaveBeenCalledWith('MembershipRequestSent');
});
});

it('should handle joining a public organization successfully', async () => {
render(
<TestWrapper mocks={successMocks}>
<OrganizationCard
{...defaultProps}
userRegistrationRequired={false}
isJoined={false}
/>
</TestWrapper>,
);

const joinButton = screen.getByText('joinNow');
await fireEvent.click(joinButton);

await waitFor(() => {
expect(toast.success).toHaveBeenCalledWith('orgJoined');
});
});

it('should handle private organization join error', async () => {
render(
<TestWrapper mocks={errorMocks}>
<OrganizationCard
{...defaultProps}
userRegistrationRequired={true}
isJoined={false}
/>
</TestWrapper>,
);

const joinButton = screen.getByTestId('joinBtn');
await fireEvent.click(joinButton);

await waitFor(() => {
expect(toast.error).toHaveBeenCalledWith('errorOccured');
});
});
});
});
Loading

0 comments on commit 8320e05

Please sign in to comment.