Skip to content

Commit

Permalink
Adding vitest to TagNode.tsx (#3089)
Browse files Browse the repository at this point in the history
* adding vitest

Signed-off-by: NishantSinghhhhh <[email protected]>

* tests for mocks

Signed-off-by: NishantSinghhhhh <[email protected]>

* passing the test for not changin sensitive files

Signed-off-by: NishantSinghhhhh <[email protected]>

* passing the test for not changin sensitive files

Signed-off-by: NishantSinghhhhh <[email protected]>

* adding tests for 100% covergae of mocks

Signed-off-by: NishantSinghhhhh <[email protected]>

---------

Signed-off-by: NishantSinghhhhh <[email protected]>
  • Loading branch information
NishantSinghhhhh authored Dec 31, 2024
1 parent 59bccdf commit 6349f3f
Show file tree
Hide file tree
Showing 3 changed files with 342 additions and 0 deletions.
266 changes: 266 additions & 0 deletions src/components/TagActions/TagNode.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { describe, it, expect, vi } from 'vitest';
import TagNode from './TagNode';
import type { InterfaceTagData } from '../../utils/interfaces';
import type { TFunction } from 'i18next';
import { MOCKS, MOCKS_ERROR_SUBTAGS_QUERY } from './TagActionsMocks';
import { MOCKS_ERROR_SUBTAGS_QUERY1, MOCKS1 } from './TagNodeMocks';

const mockTag: InterfaceTagData = {
_id: '1',
name: 'Parent Tag',
childTags: { totalCount: 2 },
parentTag: { _id: '0' },
usersAssignedTo: { totalCount: 0 },
ancestorTags: [
{
_id: '2',
name: 'Ancestor Tag 1',
},
],
};

const mockCheckedTags: Set<string> = new Set<string>();
const mockToggleTagSelection = vi.fn();
const mockT: TFunction<'translation', 'manageTag'> = ((key: string) =>
key) as TFunction<'translation', 'manageTag'>;

describe('TagNode', () => {
// Existing tests
it('renders the tag name', () => {
render(
<MockedProvider mocks={[]} addTypename={false}>
<TagNode
tag={mockTag}
checkedTags={mockCheckedTags}
toggleTagSelection={mockToggleTagSelection}
t={mockT}
/>
</MockedProvider>,
);

expect(screen.getByText('Parent Tag')).toBeInTheDocument();
});

it('calls toggleTagSelection when the checkbox is clicked', () => {
render(
<MockedProvider mocks={MOCKS} addTypename={false}>
<TagNode
tag={mockTag}
checkedTags={mockCheckedTags}
toggleTagSelection={mockToggleTagSelection}
t={mockT}
/>
</MockedProvider>,
);

const checkbox = screen.getByTestId(`checkTag${mockTag._id}`);
fireEvent.click(checkbox);
expect(mockToggleTagSelection).toHaveBeenCalledWith(mockTag, true);
});

// Existing subtag tests
it('expands and fetches subtags when expand icon is clicked', async () => {
render(
<MockedProvider mocks={MOCKS} addTypename={false}>
<TagNode
tag={mockTag}
checkedTags={mockCheckedTags}
toggleTagSelection={mockToggleTagSelection}
t={mockT}
/>
</MockedProvider>,
);

const expandIcon = screen.getByTestId(`expandSubTags${mockTag._id}`);
fireEvent.click(expandIcon);

await waitFor(() => {
expect(screen.getByText('subTag 1')).toBeInTheDocument();
expect(screen.getByText('subTag 2')).toBeInTheDocument();
});
});

it('displays an error message if fetching subtags fails', async () => {
render(
<MockedProvider mocks={MOCKS_ERROR_SUBTAGS_QUERY} addTypename={false}>
<TagNode
tag={mockTag}
checkedTags={mockCheckedTags}
toggleTagSelection={mockToggleTagSelection}
t={mockT}
/>
</MockedProvider>,
);

const expandIcon = screen.getByTestId(`expandSubTags${mockTag._id}`);
fireEvent.click(expandIcon);

await waitFor(() => {
expect(
screen.getByText('errorOccurredWhileLoadingSubTags'),
).toBeInTheDocument();
});
});

it('loads more subtags on scroll', async () => {
render(
<MockedProvider mocks={MOCKS} addTypename={false}>
<TagNode
tag={mockTag}
checkedTags={mockCheckedTags}
toggleTagSelection={mockToggleTagSelection}
t={mockT}
/>
</MockedProvider>,
);

const expandIcon = screen.getByTestId(`expandSubTags${mockTag._id}`);
fireEvent.click(expandIcon);

await waitFor(() => {
expect(screen.getByText('subTag 1')).toBeInTheDocument();
});

const scrollableDiv = screen.getByTestId(
`subTagsScrollableDiv${mockTag._id}`,
);
fireEvent.scroll(scrollableDiv, { target: { scrollY: 100 } });

await waitFor(() => {
expect(screen.getByText('subTag 11')).toBeInTheDocument();
});
});
});
describe('TagNode with Mocks', () => {
it('renders parent tag name', () => {
render(
<MockedProvider mocks={[]} addTypename={false}>
<TagNode
tag={mockTag}
checkedTags={mockCheckedTags}
toggleTagSelection={mockToggleTagSelection}
t={mockT}
/>
</MockedProvider>,
);

expect(screen.getByText('Parent Tag')).toBeInTheDocument();
});

it('fetches and displays child tags from MOCKS', async () => {
render(
<MockedProvider mocks={MOCKS} addTypename={false}>
<TagNode
tag={mockTag}
checkedTags={mockCheckedTags}
toggleTagSelection={mockToggleTagSelection}
t={mockT}
/>
</MockedProvider>,
);

const expandIcon = screen.getByTestId(`expandSubTags${mockTag._id}`);
fireEvent.click(expandIcon);

await waitFor(() => {
expect(screen.getByText('subTag 1')).toBeInTheDocument();
expect(screen.getByText('subTag 2')).toBeInTheDocument();
});
});

it('handles pagination correctly with second MOCKS item', async () => {
render(
<MockedProvider mocks={MOCKS} addTypename={false}>
<TagNode
tag={mockTag}
checkedTags={mockCheckedTags}
toggleTagSelection={mockToggleTagSelection}
t={mockT}
/>
</MockedProvider>,
);

const expandIcon = screen.getByTestId(`expandSubTags${mockTag._id}`);
fireEvent.click(expandIcon);

// Verify first set of subtags
await waitFor(() => {
expect(screen.getByText('subTag 1')).toBeInTheDocument();
expect(screen.getByText('subTag 2')).toBeInTheDocument();
});

// Trigger load more
const scrollableDiv = screen.getByTestId(
`subTagsScrollableDiv${mockTag._id}`,
);
fireEvent.scroll(scrollableDiv, { target: { scrollY: 100 } });

// Verify paginated subtags
await waitFor(() => {
expect(screen.getByText('subTag 11')).toBeInTheDocument();
});
});

it('displays error message with MOCKS_ERROR_SUBTAGS_QUERY', async () => {
render(
<MockedProvider mocks={MOCKS_ERROR_SUBTAGS_QUERY} addTypename={false}>
<TagNode
tag={mockTag}
checkedTags={mockCheckedTags}
toggleTagSelection={mockToggleTagSelection}
t={mockT}
/>
</MockedProvider>,
);

const expandIcon = screen.getByTestId(`expandSubTags${mockTag._id}`);
fireEvent.click(expandIcon);

// Verify error message
await waitFor(() => {
expect(
screen.getByText('errorOccurredWhileLoadingSubTags'),
).toBeInTheDocument();
});
});
});

describe('MOCKS Structure Validation', () => {
it('validates the structure of MOCKS[0]', () => {
const firstMock = MOCKS1[0];

expect(firstMock.request.query).toBeDefined();
expect(firstMock.request.variables).toEqual({ id: '1', first: 10 });
expect(firstMock.result.data?.getChildTags?.childTags?.edges?.length).toBe(
2,
);
});

it('validates the structure of MOCKS[1] (pagination)', () => {
const secondMock = MOCKS1[1];

expect(secondMock.request.query).toBeDefined();
expect(secondMock.request.variables).toEqual({
id: '1',
first: 10,
after: 'subTag2',
});
expect(secondMock.result.data?.getChildTags?.childTags?.edges?.length).toBe(
1,
);
});

it('validates MOCKS_ERROR_SUBTAGS_QUERY structure', () => {
const errorMock = MOCKS_ERROR_SUBTAGS_QUERY1[0];

expect(errorMock.request.query).toBeDefined();
expect(errorMock.request.variables).toEqual({ id: '1', first: 10 });
expect(errorMock.error).toBeInstanceOf(Error);
expect(errorMock.error?.message).toBe(
'Mock GraphQL Error for fetching subtags',
);
});
});
1 change: 1 addition & 0 deletions src/components/TagActions/TagNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ const TagNode: React.FC<InterfaceTagNodeProps> = ({
className="me-2"
onChange={handleCheckboxChange}
data-testid={`checkTag${tag._id}`}
id={`checkbox-${tag._id}`}
aria-label={t('selectTag')}
/>
<i className="fa fa-folder mx-2" />{' '}
Expand Down
75 changes: 75 additions & 0 deletions src/components/TagActions/TagNodeMocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { USER_TAG_SUB_TAGS } from 'GraphQl/Queries/userTagQueries';

export const MOCKS1 = [
{
request: {
query: USER_TAG_SUB_TAGS,
variables: {
id: '1',
first: 10,
},
},
result: {
data: {
getChildTags: {
__typename: 'GetChildTagsPayload',
childTags: {
__typename: 'ChildTagsConnection',
edges: [
{ node: { _id: 'subTag1', name: 'subTag 1', __typename: 'Tag' } },
{ node: { _id: 'subTag2', name: 'subTag 2', __typename: 'Tag' } },
],
pageInfo: {
__typename: 'PageInfo',
hasNextPage: true,
endCursor: 'subTag2',
},
},
},
},
},
},
{
request: {
query: USER_TAG_SUB_TAGS,
variables: {
id: '1',
first: 10,
after: 'subTag2',
},
},
result: {
data: {
getChildTags: {
__typename: 'GetChildTagsPayload',
childTags: {
__typename: 'ChildTagsConnection',
edges: [
{
node: { _id: 'subTag11', name: 'subTag 11', __typename: 'Tag' },
},
],
pageInfo: {
__typename: 'PageInfo',
hasNextPage: false,
endCursor: 'subTag11',
},
},
},
},
},
},
];

export const MOCKS_ERROR_SUBTAGS_QUERY1 = [
{
request: {
query: USER_TAG_SUB_TAGS,
variables: {
id: '1',
first: 10,
},
},
error: new Error('Mock GraphQL Error for fetching subtags'),
},
];

0 comments on commit 6349f3f

Please sign in to comment.