-
Notifications
You must be signed in to change notification settings - Fork 1
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
1222 vitest widgets #1605
1222 vitest widgets #1605
Conversation
"react/react-in-jsx-scope": "off", | ||
"react/jsx-uses-react": "off", |
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.
This was added to remove a warning from the nx merge airbnb rules. Basically it gives an error if you use jsx in a file without importing React at the top of each 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.
Okay I actually removed this since I rebased on Josh's PR which fixed these eslint rules!
@@ -10,6 +10,7 @@ const ReadOnlyComboBoxWidget: React.FC<WidgetProps> = ({ | |||
]; | |||
const selectedValue = | |||
fieldSchema && | |||
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.
Found this bug while testing the empty state of the read only widget. Without this added it would show a selected value even if there was no 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.
😱 nice find!
bciers/apps/registration/tests/components/form/widgets/MultiSelectWidget.test.tsx
Show resolved
Hide resolved
"reg:coverage": "nx run registration:test --coverage", | ||
"reg:test": "nx run registration:test" |
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.
hot reloading is currently not working. To enable it I believe we will have to update nx
, so I decided to make it's own issue:
expect(screen.queryByText(urlErrorMessage)).toBeNull(); | ||
}); | ||
|
||
// Todo: Fix bug preventing required field validation |
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.
The fix I did ages ago for the URL widget empty string error prevents it from being set to a required field. There is more context in this bug ticket though it's something we should handle properly in the future.
}, | ||
}; | ||
|
||
describe("RJSF FileWidget", () => { |
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.
Feels like this could be more thoroughly tested. What are we missing here?
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.
- should allow user to select a file for upload, then remove it?
- should display an error when trying to upload files greater than ? (iirc, when Brianna implemented file upload, she added a file size limit)
- (if we have restrictions on file type in place?) should display an error message when an "undesired" file (e.g.,
.exe
) is uploaded - if we want to be really on the ball, should allow file types of .kml and .kmz to be uploaded
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.
Okay I've done what I can here but some things to note as our FileWidget is super basic at the moment:
- There is no feature to remove the file. I added a test to verify that we can replace the current file though.
- The
accept
functionality for file types just blocks them from being selected in the document browser and we don't currently have any built in validation messages. I added a test that verifies that the input won't accept a non-pdf. - I added a test to confirm that the
accept
option would accept .kml/.kmz. I wasn't sure if you meant you actually wanted that enabled for the file upload field on the operations form. It would be easy to do but I only added a test. - Added a couple tests for the 20mb maximum, one to verify it won't accept that input and one that uses
spyOn
for the window alert and makes sure it gets called.
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.
the test cases for FileWidget are very comprehensive now - great work @BCerki and @marcellmueller !
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.
Fantastic work Marcel!
@@ -10,6 +10,7 @@ const ReadOnlyComboBoxWidget: React.FC<WidgetProps> = ({ | |||
]; | |||
const selectedValue = | |||
fieldSchema && | |||
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.
😱 nice find!
|
||
export const comboBoxFieldSchema = { | ||
type: "object", | ||
required: ["comboBoxTestField"], |
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.
likely just me being an idiot, but why is the value of required
an array of strings? I would have expected a bool
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.
Take a look at any of our actual form schemas. In JSONSchema format this is an array of all required fields in an object. If it is a nested object then it requires it's own array for those fields.
expect(comboBoxInput.value).toBe("Option 3"); | ||
}); | ||
|
||
it("should allow clearing a combo box value", 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.
feels like we should have an additional test here to assert that multiple values can be selected simultaneously in the comboBox?
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.
re-review: not seeing a test case for multiple simultaneous values...?
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 think we can select more than one option in the comboBox. We can in the MultiSelectWidget
"data:application/pdf;name=dummy.pdf;base64,ZHVtbXk="; | ||
const mockFile = new File(["test"], "test.pdf", { type: "application/pdf" }); | ||
|
||
vi.resetAllMocks(); |
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: is this needed here when it's also called in beforeEach()
?
}, | ||
}; | ||
|
||
describe("RJSF FileWidget", () => { |
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.
- should allow user to select a file for upload, then remove it?
- should display an error when trying to upload files greater than ? (iirc, when Brianna implemented file upload, she added a file size limit)
- (if we have restrictions on file type in place?) should display an error message when an "undesired" file (e.g.,
.exe
) is uploaded - if we want to be really on the ball, should allow file types of .kml and .kmz to be uploaded
bciers/apps/registration/tests/components/form/widgets/MultiSelectWidget.test.tsx
Show resolved
Hide resolved
bciers/apps/registration/tests/components/form/widgets/MultiSelectWidget.test.tsx
Show resolved
Hide resolved
expect(input).toHaveValue("test"); | ||
}); | ||
|
||
it("should only allow entering numbers in a number field", 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 think the other use case we might need in the future is decimal values (e.g., 23.5)
and in the case of reporting in particular, I'd expect there will be users typing in large values like "1,320,000" so maybe a test with commas in the input 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.
Sounds good add a should not allow entering commas in a number field
test.
it("should trigger validation error for invalid URL", async () => { | ||
render(<FormBase schema={urlFieldSchema} uiSchema={urlFieldUiSchema} />); | ||
const input = screen.getByLabelText(urlLabelRequired); | ||
await userEvent.type(input, "example.com"); |
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.
how hard/easy is it to change this behaviour? IMO, "example.com" should be considered a valid URL. As a naive user, I wouldn't expect to have to specify "https://www.example.com" - I don't consider that to be the norm anymore.
I would call "example" or ".com" invalid URLs.
{end rant}
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.
Haha I pushed to create our own custom validation for this because I thought forcing users to add http://
or https://
before a url was silly. Though I got overridden pre-mvp. There is a ticket for it, it's out of scope for this PR.
809b074
to
0d6d99c
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.
These tests are super comprehensive, great work! I've reviewed everything except the file widget, which I'm going to spend a little more time with today. Re my comments about adding test coverage--I've mentioned things I noticed aren't covered, but I'm not sure they do need to be covered (e.g. custom onBlur). Just wanted to points out gaps in case you hadn't already considered them.
bciers/apps/registration/tests/components/form/widgets/CheckboxWidget.test.tsx
Show resolved
Hide resolved
expect(checkbox).toBeChecked(); | ||
}); | ||
|
||
it("should allow unchecking the checkbox", 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.
Missing tests for:
- when field is required
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 boolean field can't be required. It's either true or it's false.
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 think if it's optional users can just not select anything and the form will still submit. I added a test for when it's required and I did get an error 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.
good call @BCerki - we will need the option to make checkboxes required when external users are accepting terms & conditions (or the equivalent for BCIERS - more likely to be something like "I confirm that the information I've submitted is accurate")
"data:application/pdf;name=dummy.pdf;base64,ZHVtbXk="; | ||
const mockFile = new File(["test"], "test.pdf", { type: "application/pdf" }); | ||
|
||
vi.resetAllMocks(); |
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 think this is needed here; it's in already in beforeEach
const selectedOption1 = screen.getByRole("button", { name: "Option 2" }); | ||
const selectedOption2 = screen.getByRole("button", { name: "Option 3" }); |
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.
Suggest naming the variables the same number as the option to avoid confusion
const optionCancelIcon = screen.getByTestId("CloseIcon"); | ||
|
||
await userEvent.click(optionCancelIcon); |
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 would have expected this to fail because if there are two chips, then getByTestId
would choke because there are two close icons. But it seems to have worked?
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.
TestId is CancelIcon
bciers/apps/registration/tests/components/form/widgets/TextWidget.test.tsx
Show resolved
Hide resolved
bciers/apps/registration/tests/components/form/widgets/URLWidget.test.tsx
Show resolved
Hide resolved
} from "@/tests/components/form/widgets/ComboBox.test"; | ||
|
||
describe("RJSF ReadOnlyComboBoxWidget", () => { | ||
it("should render a combo box field", 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.
This additionally checks that the form data comes through correctly, so suggest adding something about that to the test name
} from "@/tests/components/form/widgets/MultiSelectWidget.test"; | ||
|
||
describe("RJSF ReadOnlyMultiSelectWidget", () => { | ||
it("should render a multi select field", 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.
same, the formData part isn't captured in the test name
bciers/apps/registration/tests/components/form/widgets/PostalCodeWidget.test.tsx
Show resolved
Hide resolved
48d615c
to
a0e9971
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.
Anything marked with the rocket ship emoji I've implemented
|
||
const fileFieldLabel = "FileWidget test field"; | ||
const fileLabelRequired = `${fileFieldLabel}*`; | ||
export const dummyDataUri = |
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.
Can we please use something other than "dummy"? "Mock," "sample," whatever
bciers/apps/registration/tests/components/form/widgets/FileWidget.test.tsx
Show resolved
Hide resolved
const input = screen.getByLabelText(fileLabelRequired); | ||
await userEvent.upload(input, mockFile); | ||
|
||
actionHandler.mockResolvedValueOnce({}); |
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 do we need to mock the actionHandler here? If I remember right, the file doesn't get uploaded until the user clicks submit, so I wouldn't expect the actionHandler to fire at this point
screen.queryByRole("button", { name: "Upload attachment" }), | ||
).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.
Possible tests to add coverage:
- something for this:
We need to store the value in state to prevent loosing the value when user switches between tabs
- file input is correctly hidden
- required
- replacing an uploaded file when there was one in the formData (I already see a test for replacing one before it got submitted)
- it looks sort of like the file widget is set up to upload more than one file (
processFiles
function) but we only allow uploading one
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 didn't find a way to test tab-switching-- Document.visibilityState was the closest and that's not really it. Did the rest
expect(checkbox).toBeChecked(); | ||
}); | ||
|
||
it("should allow unchecking the checkbox", 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 think if it's optional users can just not select anything and the form will still submit. I added a test for when it's required and I did get an error message
const optionCancelIcon = screen.getByTestId("CloseIcon"); | ||
|
||
await userEvent.click(optionCancelIcon); |
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.
TestId is CancelIcon
"12345678", | ||
); | ||
}); | ||
}); |
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.
The error for this case is about formatting, which isn't accurate, so created this ticket: https://github.com/orgs/bcgov/projects/122/views/2?filterQuery=&pane=issue&itemId=62787538
expect(optionYes).not.toBeChecked(); | ||
expect(optionNo).toBeChecked(); | ||
expect(optionMaybe).not.toBeChecked(); | ||
}); |
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.
Did the required errors part, not sure if the custom functions need tests; they look like they're coming from node_modules
fc0c845
to
b08b4f6
Compare
expect(inputBorderElement).toHaveStyle(errorStyle); | ||
}; | ||
|
||
export const checkNoValidationErrorIsTriggered = 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.
Sometimes this causes test errors, so not using it everywhere yet
4a3a31c
to
666a911
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.
my brain is kaput - will continue reviewing this tomorrow
expect(checkbox).toBeChecked(); | ||
}); | ||
|
||
it("should allow unchecking the checkbox", 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.
good call @BCerki - we will need the option to make checkboxes required when external users are accepting terms & conditions (or the equivalent for BCIERS - more likely to be something like "I confirm that the information I've submitted is accurate")
expect(comboBoxInput.value).toBe("Option 3"); | ||
}); | ||
|
||
it("should allow clearing a combo box value", 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.
re-review: not seeing a test case for multiple simultaneous values...?
666a911
to
f75bbd4
Compare
<FormBase schema={emailFieldSchema} uiSchema={emailFieldUiSchema} />, | ||
); | ||
const input = screen.getByLabelText(emailLabelRequired); | ||
await userEvent.type(input, "test.email@test.com"); |
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.
This input doesn't match the test description of a "subdomain" - I propose changing the input to test@email.test.com
}, | ||
}; | ||
|
||
describe("RJSF FileWidget", () => { |
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.
the test cases for FileWidget are very comprehensive now - great work @BCerki and @marcellmueller !
|
||
await userEvent.click(submitButton); | ||
|
||
expect(screen.getByText("Format should be A1A 1A1")).toBeVisible(); |
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.
Horrible thought: if we're accepting American phone numbers, should we also be accepting American zip codes...? (This thought makes me sad.)
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'll ask the designers
screen.getByPlaceholderText("Select regulated products..."), | ||
).toBeVisible(); | ||
}); | ||
it("should use the enum values as the names if no enumNames are provided, use the enum values as the names", 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.
this test name seems a little repetitive, a little bit
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.
good point point
f75bbd4
to
7916473
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.
Not able to run the tests locally because something wacky is going on with my local git. (Grrrr).
But code LGTM and it's the end of day before a long weekend so I'm feeling especially reckless.
I too like to live dangerously |
Implements #1222
Added Vitest coverage report which can be run using
yarn coverage
. We haven't discussed testing coverage but could be a good topic for dev team agreements. Most of these tests have good coverage but there are a few that could be improved especially theFileWidget
.