-
Notifications
You must be signed in to change notification settings - Fork 99
(test) O3-4553: Add unit tests for question component #419
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
base: main
Are you sure you want to change the base?
(test) O3-4553: Add unit tests for question component #419
Conversation
new translation keys:isQuestionInfoProvided,questionInfo,questionInfoPlaceholder
enhanced some code to match conventions
This commit has the test file for the question component. - For now only the tests only include the feature being introduced in this PR. - Future tests will be in a different PR. - Few changes has been made to the `Question` component: * Radio buttons in the same group should have both the attribute `defaultChecked` * Replaced `defaultChecked` with `checked`
…rm/question/question.test.tsx Co-authored-by: Nethmi Rodrigo <[email protected]>
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.
Thanks @MohamedAliMefteh, a couple of suggestions:
jest.mock('../rendering-types/rendering-type.component', () => ({ | ||
__esModule: true, | ||
default: jest.fn(() => <div data-testid="render-type-component" />), | ||
})); | ||
|
||
jest.mock('../question-types/question-type.component', () => ({ | ||
__esModule: true, | ||
default: jest.fn(() => <div data-testid="question-type-component" />), | ||
})); | ||
|
||
jest.mock('../common/required-label/required-label.component', () => ({ | ||
__esModule: true, | ||
default: jest.fn(({ isRequired, text }) => ( | ||
<div data-testid="required-label"> | ||
{text} {isRequired ? '(Required)' : ''} | ||
</div> | ||
)), | ||
})); |
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 are these internal components mocked? We should try to avoid mocking internal components like these as much as possible.
jest.mock('./question.scss', () => ({ | ||
questionIdLabel: 'mock-question-id-label', | ||
})); |
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 a stylesheet mocked?
}); | ||
|
||
it('should render without crashing', () => { | ||
renderWithFormFieldProvider(<Question checkIfQuestionIdExists={jest.fn()} />); |
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.
Define checkIfQuestionIdExists
as a mock function at the top so you can just pass it in instead of defining it as jest.fn
every time.
|
||
it('should render without crashing', () => { | ||
renderWithFormFieldProvider(<Question checkIfQuestionIdExists={jest.fn()} />); | ||
expect(screen.getByRole('textbox', { name: /Question ID/i })).toBeInTheDocument(); |
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.
Not just the question id, the question type field, you should also check if question type and rendering type fields also get rendered.
// it('should validate duplicate question ids', () => { | ||
// const checkIfQuestionIdExists = jest.fn(() => true); | ||
// renderWithFormFieldProvider(<Question checkIfQuestionIdExists={checkIfQuestionIdExists} />, { | ||
// formField: { ...initialFormField, id: 'duplicateId' }, | ||
// }); | ||
|
||
// expect(checkIfQuestionIdExists).toHaveBeenCalledWith('duplicateId'); | ||
// expect(screen.getByText(/This question ID already exists/i)).toBeInTheDocument(); | ||
// }); |
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.
Don't include commented out test cases
// it('should not show label and required inputs when rendering type is markdown', () => { | ||
// renderWithFormFieldProvider(<Question checkIfQuestionIdExists={jest.fn()} />, { | ||
// formField: { ...initialFormField, questionOptions: { rendering: 'markdown' } }, | ||
// }); | ||
|
||
// expect(screen.queryByRole('textbox', { name: /Label/i })).not.toBeInTheDocument(); | ||
// expect(screen.queryByText(/Is this question a required or optional field?/i)).not.toBeInTheDocument(); | ||
// }); |
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.
Ditto
it('should render RenderTypeComponent when rendering type is selected', () => { | ||
renderWithFormFieldProvider(<Question checkIfQuestionIdExists={jest.fn()} />, { | ||
formField: { ...initialFormField, questionOptions: { rendering: 'text' } }, | ||
}); | ||
|
||
expect(screen.getByTestId('render-type-component')).toBeInTheDocument(); | ||
expect(RenderTypeComponent).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should render QuestionTypeComponent when question type is selected', () => { | ||
renderWithFormFieldProvider(<Question checkIfQuestionIdExists={jest.fn()} />, { | ||
formField: { ...initialFormField, type: 'obs' }, | ||
}); | ||
|
||
expect(screen.getByTestId('question-type-component')).toBeInTheDocument(); | ||
expect(QuestionTypeComponent).toHaveBeenCalled(); | ||
}); |
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.
These components should be rendered even if they are not in the field.
const renderingTypeSelect = screen.getByLabelText(/Rendering type/i); | ||
fireEvent.click(renderingTypeSelect); | ||
|
||
// TODO: test the select options. |
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.
Ditto
// TODO: check if it gets the updated prop | ||
|
||
const optionalRadio = screen.getByLabelText(/Optional/i); | ||
fireEvent.click(optionalRadio); |
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.
Prefer to use userEvents over fireEvent - https://testing-library.com/docs/user-event/intro#differences-from-fireevent
const optionalRadio = screen.getByLabelText(/Optional/i); | ||
fireEvent.click(optionalRadio); | ||
|
||
// TODO: check if it gets the updated prop |
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.
Ditto
When writing these tests, I didn't take in consideration other tests written in openMRS form-builder. |
…ith useEvents and fixed other tests
enhanced some code to match conventions
This commit has the test file for the question component. - For now only the tests only include the feature being introduced in this PR. - Future tests will be in a different PR. - Few changes has been made to the `Question` component: * Radio buttons in the same group should have both the attribute `defaultChecked` * Replaced `defaultChecked` with `checked`
…ith useEvents and fixed other tests
…ithub.com/MohamedAliMefteh/openmrs-esm-form-builder into feat/add-unit-test-for-question-component
Requirements
Summary
This PR adds unit tests for the Question Component used within modals to ensure the correct rendering, behavior, and functionality. The tests cover a wide range of scenarios, including interactions with form fields, conditional rendering, and component-specific functionality such as converting labels to camel case, toggling question visibility, and updating question info.
However, some of the tests are currently failing and require adjustments. Additionally, a few test cases are incomplete and need to be finalized later.
Key Changes:
Rendering & Interactions: Tests ensure the Question component renders correctly and interacts with the form fields, such as updating the questionId, toggling visibility of additional question info, and updating question info text.
Question Info Visibility: Tests handle toggling the visibility of the "Additional Question Info" section when radio buttons (Yes/No) are clicked.
Label Conversion: Added tests for converting the question label to camel-case when the corresponding button is clicked.
Component Rendering: Tests ensure that child components like RenderTypeComponent and QuestionTypeComponent are rendered when their corresponding properties are set.
Known Issues:
Test Failures: There are a few tests that are currently not passing. The failing tests are marked with comments in the code, and they need to be reviewed and adjusted to handle specific behaviors or edge cases correctly.
Duplicate Question ID Validation: The test for checking duplicate question IDs is commented out due to an issue in mocking the validation function (checkIfQuestionIdExists). It needs to be reworked to properly test the validation logic.
Rendering Type with Markdown: The test to ensure that label and required inputs are hidden when the rendering type is set to "markdown" is commented out. This needs to be revisited to handle conditional rendering based on the rendering property.
Incomplete Tests: There are two tests marked with TODO comments that need to be completed later:
Question Required Status: The test for toggling between required and optional statuses is incomplete and needs to be updated to verify that the prop value is correctly passed down and updated.
Rendering Type Select Options: The test for checking the select options when rendering type is clicked is a work-in-progress and needs to be finalized to validate the available options for the user.
Screenshots
Related Issue
https://openmrs.atlassian.net/browse/O3-4553