-
-
Notifications
You must be signed in to change notification settings - Fork 864
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Achieved 100% Code Coverage for OrganizationCard Component #3464
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -266,6 +266,7 @@ describe('OrganizationCard Component', () => { | |
}); | ||
}); | ||
|
||
|
||
// Mutation Tests | ||
describe('Mutations', () => { | ||
it('should handle joining a private organization successfully', async () => { | ||
|
@@ -347,24 +348,157 @@ describe('OrganizationCard Component', () => { | |
}); | ||
}); | ||
|
||
it('should handle membership withdrawal error when request not found', async () => { | ||
it('should log development error and show generic error toast', async () => { | ||
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); | ||
|
||
// Mock process.env.NODE_ENV to 'development' | ||
const originalNodeEnv = process.env.NODE_ENV; | ||
process.env.NODE_ENV = 'development'; | ||
|
||
const props = { | ||
...defaultProps, | ||
userId: 'mockUserId', | ||
membershipRequestStatus: 'pending', | ||
membershipRequests: [], // Empty requests to trigger error | ||
membershipRequests: [{ _id: 'requestId', user: { _id: 'mockUserId' } }], | ||
}; | ||
|
||
|
||
const errorMocks: MockedResponse[] = [ | ||
{ | ||
request: { | ||
query: CANCEL_MEMBERSHIP_REQUEST, | ||
variables: { membershipRequestId: 'requestId' }, | ||
}, | ||
error: new Error('Withdrawal failed'), | ||
}, | ||
]; | ||
|
||
render( | ||
<TestWrapper mocks={errorMocks}> | ||
<OrganizationCard {...props} isJoined={false} /> | ||
</TestWrapper>, | ||
</TestWrapper> | ||
); | ||
|
||
const withdrawButton = screen.getByTestId('withdrawBtn'); | ||
await fireEvent.click(withdrawButton); | ||
|
||
await waitFor(() => { | ||
expect(consoleErrorSpy).toHaveBeenCalledWith( | ||
'Failed to withdraw membership request:', | ||
expect.any(Error) | ||
); | ||
expect(toast.error).toHaveBeenCalledWith('errorOccured'); | ||
}); | ||
|
||
// Restore original environment | ||
process.env.NODE_ENV = originalNodeEnv; | ||
consoleErrorSpy.mockRestore(); | ||
}); | ||
|
||
it('should handle already joined error when joining organization', async () => { | ||
const errorMocksWithAlreadyJoined: MockedResponse[] = [ | ||
{ | ||
request: { | ||
query: JOIN_PUBLIC_ORGANIZATION, | ||
variables: { organizationId: '123' }, | ||
}, | ||
result: { | ||
errors: [ | ||
{ | ||
message: 'Already a member', | ||
extensions: { code: 'ALREADY_MEMBER' }, | ||
}, | ||
], | ||
}, | ||
}, | ||
]; | ||
|
||
render( | ||
<TestWrapper mocks={errorMocksWithAlreadyJoined}> | ||
<OrganizationCard | ||
{...defaultProps} | ||
userRegistrationRequired={false} | ||
isJoined={false} | ||
/> | ||
</TestWrapper> | ||
); | ||
|
||
const joinButton = screen.getByText('joinNow'); | ||
await fireEvent.click(joinButton); | ||
|
||
await waitFor(() => { | ||
expect(toast.error).toHaveBeenCalledWith('AlreadyJoined'); | ||
}); | ||
}); | ||
it('should handle membership request not found', async () => { | ||
// Mock getItem to return a userId that exists | ||
mockGetItem.mockReturnValue('testUserId'); | ||
|
||
const props = { | ||
...defaultProps, | ||
membershipRequestStatus: 'pending', | ||
// Create a membership requests array with a different user ID | ||
membershipRequests: [ | ||
{ | ||
_id: 'requestId', | ||
user: { | ||
_id: 'differentUserId' // Different from the mocked userId | ||
} | ||
} | ||
], | ||
}; | ||
|
||
render( | ||
<TestWrapper mocks={successMocks}> | ||
<OrganizationCard {...props} isJoined={false} /> | ||
</TestWrapper> | ||
); | ||
|
||
// Find and click the withdraw button | ||
const withdrawButton = screen.getByTestId('withdrawBtn'); | ||
await fireEvent.click(withdrawButton); | ||
|
||
// Verify that the error toast is shown | ||
await waitFor(() => { | ||
expect(toast.error).toHaveBeenCalledWith('MembershipRequestNotFound'); | ||
}); | ||
|
||
// Verify the mutation was not called | ||
const cancelMutation = successMocks.find( | ||
mock => mock.request.query === CANCEL_MEMBERSHIP_REQUEST | ||
); | ||
expect(cancelMutation?.result).not.toHaveBeenCalled; | ||
}); | ||
|
||
|
||
|
||
it('should handle withdrawal attempt with no userId', async () => { | ||
// Mock getItem to return null to simulate no userId | ||
mockGetItem.mockReturnValue(null); | ||
|
||
const props = { | ||
...defaultProps, | ||
membershipRequestStatus: 'pending', | ||
membershipRequests: [{ _id: 'requestId', user: { _id: 'mockUserId' } }], | ||
}; | ||
|
||
render( | ||
<TestWrapper mocks={successMocks}> | ||
<OrganizationCard {...props} isJoined={false} /> | ||
</TestWrapper> | ||
); | ||
|
||
const withdrawButton = screen.getByTestId('withdrawBtn'); | ||
await fireEvent.click(withdrawButton); | ||
|
||
await waitFor(() => { | ||
expect(toast.error).toHaveBeenCalledWith('MembershipRequestNotFound'); | ||
expect(toast.error).toHaveBeenCalledWith('UserIdNotFound'); | ||
}); | ||
|
||
// Verify that the cancelMembershipRequest mutation was not called | ||
expect( | ||
successMocks.find( | ||
mock => mock.request.query === CANCEL_MEMBERSHIP_REQUEST | ||
)?.result | ||
).not.toHaveBeenCalled; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Fix assertion syntax and use proper translation key for error message The test has two issues that need to be addressed:
expect(
successMocks.find(
(mock) => mock.request.query === CANCEL_MEMBERSHIP_REQUEST
)?.result
- ).not.toHaveBeenCalled;
+ ).not.toHaveBeenCalled();
await waitFor(() => {
- expect(toast.error).toHaveBeenCalledWith('UserIdNotFound');
+ expect(toast.error).toHaveBeenCalledWith('notFound');
}); Consider using an existing translation key like 'notFound' or add a new specific translation key for this error case in the translation files. 🔗 Analysis chainFix assertion syntax and verify error message translation. The test has multiple issues that need to be addressed:
expect(
successMocks.find(
- mock => mock.request.query === CANCEL_MEMBERSHIP_REQUEST
+ (mock) => mock.request.query === CANCEL_MEMBERSHIP_REQUEST,
)?.result
- ).not.toHaveBeenCalled;
+ ).not.toHaveBeenCalled(); Let's verify if the error message is defined in the translations: 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Search for 'UserIdNotFound' in translation files
rg -l "UserIdNotFound" --type json
Length of output: 34 Script: #!/bin/bash
# First, let's find all potential translation/locale files
echo "=== Searching for translation files ==="
fd -e json -e yaml -e yml . | grep -iE 'translation|locale|i18n|lang'
echo -e "\n=== Searching for similar message patterns ==="
# Search for various forms of the message
rg -i "userid.*not.*found|user.*id.*not.*found|user_id_not_found" --type json --type ts --type tsx
echo -e "\n=== Looking for message constants ==="
# Search for message definitions in TypeScript/JavaScript files
ast-grep --pattern 'const $_ = $$$"UserIdNotFound"$$$'
Length of output: 1021 Script: #!/bin/bash
# Check content of error translation files
echo "=== Content of English error translations ==="
cat public/locales/en/errors.json
echo -e "\n=== Searching for any user-related error messages ==="
rg -i "user" public/locales/en/errors.json
Length of output: 1245 🧰 Tools🪛 ESLint[error] 477-477: Delete (prettier/prettier) [error] 483-483: Delete (prettier/prettier) [error] 487-487: Insert (prettier/prettier) [error] 489-489: Delete (prettier/prettier) [error] 492-492: Delete (prettier/prettier) [error] 496-496: Delete (prettier/prettier) [error] 498-502: Expected an assignment or function call and instead saw an expression. (@typescript-eslint/no-unused-expressions) [error] 500-500: Replace (prettier/prettier) [error] 501-501: Insert (prettier/prettier) [error] 502-502: Matchers must be called to assert (jest/valid-expect) 🪛 GitHub Actions: PR Workflow[warning] Code style issues found. File needs to be formatted using Prettier. |
||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect assertion syntax and formatting issues.
The test has an incorrect assertion syntax and multiple formatting issues that need to be addressed.
Also, fix the formatting issues in the membership requests array:
📝 Committable suggestion
🧰 Tools
🪛 ESLint
[error] 432-432: Delete
··
(prettier/prettier)
[error] 433-433: Delete
··
(prettier/prettier)
[error] 434-434: Delete
··
(prettier/prettier)
[error] 435-435: Delete
······
(prettier/prettier)
[error] 436-436: Delete
··
(prettier/prettier)
[error] 437-437: Delete
··
(prettier/prettier)
[error] 438-438: Delete
··
(prettier/prettier)
[error] 439-439: Delete
··
(prettier/prettier)
[error] 440-440: Delete
··
(prettier/prettier)
[error] 441-441: Replace
··{·
with{
(prettier/prettier)
[error] 442-442: Replace
············_id:·'requestId',·
with··········_id:·'requestId',
(prettier/prettier)
[error] 443-443: Replace
··user:·{·
withuser:·{
(prettier/prettier)
[error] 444-444: Replace
··············_id:·'differentUserId'·
with············_id:·'differentUserId',
(prettier/prettier)
[error] 445-445: Replace
··}·
with},
(prettier/prettier)
[error] 446-446: Replace
··········}
with········},
(prettier/prettier)
[error] 447-447: Delete
··
(prettier/prettier)
[error] 448-448: Replace
······
with····
(prettier/prettier)
[error] 449-449: Delete
······
(prettier/prettier)
[error] 450-450: Delete
··
(prettier/prettier)
[error] 451-451: Delete
··
(prettier/prettier)
[error] 452-452: Replace
··········
with········
(prettier/prettier)
[error] 453-453: Replace
··</TestWrapper>
with</TestWrapper>,
(prettier/prettier)
[error] 454-454: Delete
··
(prettier/prettier)
[error] 455-455: Delete
······
(prettier/prettier)
[error] 456-456: Delete
··
(prettier/prettier)
[error] 457-457: Delete
··
(prettier/prettier)
[error] 458-458: Delete
··
(prettier/prettier)
[error] 459-459: Delete
······
(prettier/prettier)
[error] 460-460: Delete
··
(prettier/prettier)
[error] 461-461: Delete
··
(prettier/prettier)
[error] 462-462: Delete
··
(prettier/prettier)
[error] 463-463: Delete
··
(prettier/prettier)
[error] 464-464: Delete
······
(prettier/prettier)
[error] 465-465: Delete
··
(prettier/prettier)
[error] 466-466: Replace
······
with····
(prettier/prettier)
[error] 467-467: Replace
········mock·=>·mock.request.query·===·CANCEL_MEMBERSHIP_REQUEST
with······(mock)·=>·mock.request.query·===·CANCEL_MEMBERSHIP_REQUEST,
(prettier/prettier)
[error] 468-468: Delete
··
(prettier/prettier)
[error] 469-469: Delete
··
(prettier/prettier)
[error] 469-469: Expected an assignment or function call and instead saw an expression.
(@typescript-eslint/no-unused-expressions)
[error] 469-469: Matchers must be called to assert
(jest/valid-expect)
🪛 GitHub Actions: PR Workflow
[warning] Code style issues found. File needs to be formatted using Prettier.