-
Notifications
You must be signed in to change notification settings - Fork 976
fix: fix workspaces pagination #19448
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
Changes from 2 commits
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 | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -305,6 +305,66 @@ describe("WorkspacesPage", () => { | |||||||
MockStoppedWorkspace.latest_build.template_version_id, | ||||||||
); | ||||||||
}); | ||||||||
|
||||||||
it("correctly handles pagination by including pagination parameters in query key", async () => { | ||||||||
const totalWorkspaces = 50; | ||||||||
const workspacesPage1 = Array.from({ length: 25 }, (_, i) => ({ | ||||||||
...MockWorkspace, | ||||||||
id: `page1-workspace-${i}`, | ||||||||
name: `page1-workspace-${i}`, | ||||||||
})); | ||||||||
const workspacesPage2 = Array.from({ length: 25 }, (_, i) => ({ | ||||||||
...MockWorkspace, | ||||||||
id: `page2-workspace-${i}`, | ||||||||
name: `page2-workspace-${i}`, | ||||||||
})); | ||||||||
|
||||||||
const getWorkspacesSpy = jest.spyOn(API, "getWorkspaces"); | ||||||||
|
||||||||
getWorkspacesSpy | ||||||||
.mockResolvedValueOnce({ | ||||||||
workspaces: workspacesPage1, | ||||||||
count: totalWorkspaces, | ||||||||
}) | ||||||||
.mockResolvedValueOnce({ | ||||||||
workspaces: workspacesPage2, | ||||||||
count: totalWorkspaces, | ||||||||
}); | ||||||||
|
||||||||
const user = userEvent.setup(); | ||||||||
renderWithAuth(<WorkspacesPage />); | ||||||||
|
||||||||
await waitFor(() => { | ||||||||
expect(screen.getByText("page1-workspace-0")).toBeInTheDocument(); | ||||||||
}); | ||||||||
|
||||||||
expect(getWorkspacesSpy).toHaveBeenNthCalledWith( | ||||||||
1, | ||||||||
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.
Suggested change
one last thing, I think https://jestjs.io/docs/expect#tohavebeenlastcalledwitharg1-arg2- 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. Makes sense! 👍 |
||||||||
expect.objectContaining({ | ||||||||
q: "owner:me", | ||||||||
offset: 0, | ||||||||
limit: 25, | ||||||||
}), | ||||||||
); | ||||||||
|
||||||||
const nextPageButton = screen.getByRole("button", { name: /next page/i }); | ||||||||
await user.click(nextPageButton); | ||||||||
|
||||||||
await waitFor(() => { | ||||||||
expect(screen.getByText("page2-workspace-0")).toBeInTheDocument(); | ||||||||
}); | ||||||||
|
||||||||
expect(getWorkspacesSpy).toHaveBeenNthCalledWith( | ||||||||
2, | ||||||||
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.
Suggested change
same thought here |
||||||||
expect.objectContaining({ | ||||||||
q: "owner:me", | ||||||||
offset: 25, | ||||||||
limit: 25, | ||||||||
}), | ||||||||
); | ||||||||
|
||||||||
expect(screen.queryByText("page1-workspace-0")).not.toBeInTheDocument(); | ||||||||
}); | ||||||||
}); | ||||||||
|
||||||||
const getWorkspaceCheckbox = (workspace: Workspace) => { | ||||||||
|
Uh oh!
There was an error while loading. Please reload this page.
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 feel like this setup is a little fragile. I've never stacked multiple calls to
mockResolvedValueOnce
onto the same spy before, but if I'm reading it right, it means that, no matter what we actually call the function with, we'll always get page 1 for the first call, and page 2 for the second call. But then:I don't know all the details, but I know that MSW has tools to mock out the API response. Maybe that's not needed and we could keep the Jest Spys, but I think I'd rather make it so that we have a mock that stays locked in for the duration of the test, and then checks the page input:
Uh oh!
There was an error while loading. Please reload this page.
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 know you have the checks for the exact inputs a little bit below, but if the React testing tools ever add double-rendering to help check for correctness (like what you get with
StrictMode
and dev mode), that would immediately cause this test to breakThere 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 sure if I got it. Let me share what I understood.
The issue with this test is it is using stacked
mockResolvedValueOnce
to mock the responses for the first and second calls so, if react renders twice in the same page, the test would break. Is that right?Uh oh!
There was an error while loading. Please reload this page.
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.
Yeah, if React ever double-mounts the same hook for the data fetching, this will happen if we start at page 1:
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.
Updated the
spyOn
to use themockImplementation
, wdyt?