-
Notifications
You must be signed in to change notification settings - Fork 17
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
test(support-tools-page): add testing for support tools page #70
Conversation
Codecov Report
@@ Coverage Diff @@
## master #70 +/- ##
=========================================
Coverage ? 21.86%
=========================================
Files ? 28
Lines ? 709
Branches ? 152
=========================================
Hits ? 155
Misses ? 539
Partials ? 15
Continue to review full report at Codecov.
|
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`SupportLinksPage matches snapshot 1`] = ` | ||
<main | ||
className="container-fluid m-5" | ||
> | ||
<h3> | ||
Support Tools | ||
</h3> | ||
<ul> | ||
<li> | ||
<a | ||
href="/users" | ||
id="search-users" | ||
onClick={[Function]} | ||
> | ||
Search Users | ||
</a> | ||
</li> | ||
</ul> | ||
</main> | ||
`; |
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.
I am not sure if this file should be committed. Is there a specific reason for this file?
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.
yes, this is the snapshot file which would be required for comparing current (at the time of running builds) and expected snapshot (this one)
it('matches snapshot', () => { | ||
const tree = renderer.create(<SupportLinksPage />).toJSON(); | ||
expect(tree).toMatchSnapshot(); |
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.
What does this achieve?
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.
toMatchSnapshot();
this matches the current snapshot with expected (saved) snapshot.
b8d4759
to
6025560
Compare
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.
For future reference, ideally, the component where the UI changes are more important should be tested via snapshots. For the simple components, the regular unit tests will be enough.
src/PageLoading.test.jsx
Outdated
it('does not render without message', () => { | ||
const wrapper = shallow(<PageLoading srMessage="" />); | ||
|
||
expect(wrapper.find('.sr-only')).toHaveLength(0); | ||
}); | ||
it('does not render without message', () => { |
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.
both have the same description. 2nd should be renders correctly with message
src/PageLoading.test.jsx
Outdated
expect(srElement).toHaveLength(1); | ||
expect(srElement.text()).toEqual(message); | ||
}); | ||
it('renders correctly', () => { |
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.
--> snapshot matches correctly
|
||
expect(searchUsersText).toEqual('Search Users'); | ||
}); | ||
it('have correct heading', () => { |
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.
has
it('correctly renders', () => { | ||
expect(wrapper.find('li')).toHaveLength(1); | ||
}); | ||
it('have search users link', () => { |
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.
has
src/users/UserPage.test.jsx
Outdated
describe('Checking PropTypes', () => { | ||
it('Should not throw a warning', () => { | ||
const expectedProps = { location }; | ||
const propsError = checkProps(UserPage, expectedProps); | ||
|
||
expect(propsError).toBeUndefined(); | ||
}); | ||
}); |
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.
Why is there a separate describe for a single test?
src/users/UserPage.test.jsx
Outdated
}); | ||
}); | ||
// | ||
it('Renders Correctly', () => { |
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.
snapshot match
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.
just to organize tests. I have added a separate test for proptypes tests.
src/users/UserSearch.test.jsx
Outdated
); | ||
}); | ||
|
||
it('using snapshot', () => { |
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.
matches snapshot
2a8f4ce
to
6f244b6
Compare
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.
A few comments/questions to address
src/dates/formatDate.test.js
Outdated
|
||
expect(formatedDate).toEqual('Sep 19, 2015 11:00 AM'); | ||
}); | ||
it('fallback to N/A if no args are passed', () => { |
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.
nit: returns N/A if data is not provided
export const USER_IDENTIFIER_INVALID_ERROR = 'The searched username or email is invalid. Please correct the username or email and try again.'; | ||
export const USERNAME_IDENTIFIER_NOT_FOUND_ERROR = 'We couldn\'t find a user with the username "{identifier}".'; | ||
export const USER_EMAIL_IDENTIFIER_NOT_FOUND_ERROR = 'We couldn\'t find a user with the email "{identifier}".'; | ||
export const UNKNOWN_API_ERROR = "There was an error loading this user's data. Check the JavaScript console for detailed errors."; |
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.
I don't know the current behavior but is there i18n setup for such texts?
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.
I am not aware of that, and these were not being translated currently. I am also not sure if there are plans adding translations for those strings.
// Function to wait until the entire component is fully painted. | ||
const waitForComponentToPaint = async (wrapper) => { | ||
await act(async () => { | ||
await new Promise((resolve) => setTimeout(resolve)); | ||
wrapper.update(); | ||
}); | ||
}; |
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.
What does component paint stands for?
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.
Ah, it just means that component is fully rendered after all promise based function calls.
src/users/UserPage.test.jsx
Outdated
}); | ||
}); | ||
describe('shows expected error alert', () => { | ||
const mockAuthApiToThrowError = (code) => { |
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.
mockAuthResponseError or something similar to this.
src/users/UserPage.test.jsx
Outdated
it('when user identifier is not found', async () => { | ||
const validUsername = 'valid-non-existing-username'; | ||
location.search = `?username=${validUsername}`; | ||
mockAuthApiToThrowError(404); | ||
const expectedAlert = messages.USERNAME_IDENTIFIER_NOT_FOUND_ERROR.replace( | ||
'{identifier}', | ||
validUsername, | ||
); | ||
|
||
const wrapper = mount(<UserPageWrapper location={location} />); | ||
await waitForComponentToPaint(wrapper); | ||
|
||
const alert = wrapper.find('.alert'); | ||
expect(alert).toHaveLength(1); | ||
expect(alert.text()).toEqual(expectedAlert); | ||
}); | ||
it('when user email is not found', async () => { |
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.
I haven't seen async usage inside tests before. Can you share an existing example from edX codebase?
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.
src/users/UserSearch.test.jsx
Outdated
|
||
expect(propsError).toBeUndefined(); | ||
}); | ||
it('does throw error with undefined search handler', () => { |
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.
throws error. not need for does in the beginning.
const EMAIL_REGEX = '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'; | ||
const USERNAME_REGEX = '^[\\w.@_+-]+$'; | ||
|
||
export const isEmail = (value) => !!(value && value.match(EMAIL_REGEX)); |
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.
No need for !!. This operation is not affecting the value.
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.
@DawoudSheraz I have copied the methods as is, we can plan on refactoring in the other ticket. I can add todo here as well.
|
||
/* eslint-disable arrow-body-style */ | ||
export const isValidUsername = (searchValue) => { | ||
return !!(searchValue && searchValue.match(USERNAME_REGEX)); |
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.
same here
33fc72d
to
4fbb9fd
Compare
@DawoudSheraz updated the PR. |
01239de
to
024293e
Compare
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.
looks good.
import formatDate from './formatDate'; | ||
|
||
describe('Format Date', () => { | ||
it('correctly formats date', () => { |
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.
Do we need to test the utilities as well? I think the priority should be the React components for now
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.
Yes, true, I did this to bump to coverage a little bit :) and they were easy enough
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.
Looks good to me
Add Config for testing for the support tools app.
isEmail
,isValidUsername
to a common utils file.Adds the following
npm
commands.npm run debug-test
=> for running tests in debug mode.npm run snapshot
=> updates the snapshotsCoverage from 0% => ~23%
https://openedx.atlassian.net/browse/PROD-2178