Skip to content

Commit e388f8a

Browse files
committed
Add tests
1 parent 8957339 commit e388f8a

File tree

5 files changed

+107
-7
lines changed

5 files changed

+107
-7
lines changed

site/jest.setup.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import "@testing-library/jest-dom"
2+
import crypto from "crypto"
23
import { server } from "./src/testHelpers/server"
34

5+
// Polyfill the getRandomValues that is used on utils/random.ts
6+
Object.defineProperty(global.self, "crypto", {
7+
value: {
8+
getRandomValues: function (buffer: Buffer) {
9+
return crypto.randomFillSync(buffer)
10+
},
11+
},
12+
})
13+
414
// Establish API mocking before all tests through MSW.
515
beforeAll(() =>
616
server.listen({

site/src/components/ResetPasswordDialog/ResetPasswordDialog.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ export interface ResetPasswordDialogProps {
1313
onConfirm: () => void
1414
user?: TypesGen.User
1515
newPassword?: string
16+
loading: boolean
17+
}
18+
19+
export const Language = {
20+
title: "Reset password",
21+
message: (username?: string): JSX.Element => (
22+
<>
23+
You will need to send <strong>{username}</strong> the following password:
24+
</>
25+
),
26+
confirmText: "Reset password",
1627
}
1728

1829
export const ResetPasswordDialog: React.FC<ResetPasswordDialogProps> = ({
@@ -21,25 +32,29 @@ export const ResetPasswordDialog: React.FC<ResetPasswordDialogProps> = ({
2132
onConfirm,
2233
user,
2334
newPassword,
35+
loading,
2436
}) => {
2537
const styles = useStyles()
2638

2739
return (
2840
<Dialog open={open} onClose={onClose}>
29-
<DialogTitle title="Reset password" />
41+
<DialogTitle title={Language.title} />
3042

3143
<DialogContent>
32-
<DialogContentText variant="subtitle2">
33-
You will need to send <strong>{user?.username}</strong> the following password:
34-
</DialogContentText>
44+
<DialogContentText variant="subtitle2">{Language.message(user?.username)}</DialogContentText>
3545

3646
<DialogContentText component="div">
3747
<CodeBlock lines={[newPassword ?? ""]} className={styles.codeBlock} />
3848
</DialogContentText>
3949
</DialogContent>
4050

4151
<DialogActions>
42-
<DialogActionButtons onCancel={onClose} confirmText="Reset password" onConfirm={onConfirm} />
52+
<DialogActionButtons
53+
onCancel={onClose}
54+
confirmText={Language.confirmText}
55+
onConfirm={onConfirm}
56+
confirmLoading={loading}
57+
/>
4358
</DialogActions>
4459
</Dialog>
4560
)

site/src/pages/UsersPage/UsersPage.test.tsx

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { fireEvent, screen, waitFor, within } from "@testing-library/react"
22
import React from "react"
33
import * as API from "../../api"
44
import { GlobalSnackbar } from "../../components/GlobalSnackbar/GlobalSnackbar"
5+
import { Language as ResetPasswordDialogLanguage } from "../../components/ResetPasswordDialog/ResetPasswordDialog"
56
import { Language as UsersTableLanguage } from "../../components/UsersTable/UsersTable"
67
import { MockUser, MockUser2, render } from "../../testHelpers"
78
import { Language as usersXServiceLanguage } from "../../xServices/users/usersXService"
@@ -34,6 +35,33 @@ const suspendUser = async (setupActionSpies: () => void) => {
3435
fireEvent.click(confirmButton)
3536
}
3637

38+
const resetUserPassword = async (setupActionSpies: () => void) => {
39+
// Get the first user in the table
40+
const users = await screen.findAllByText(/.*@coder.com/)
41+
const firstUserRow = users[0].closest("tr")
42+
if (!firstUserRow) {
43+
throw new Error("Error on get the first user row")
44+
}
45+
46+
// Click on the "more" button to display the "Suspend" option
47+
const moreButton = within(firstUserRow).getByLabelText("more")
48+
fireEvent.click(moreButton)
49+
const menu = screen.getByRole("menu")
50+
const resetPasswordButton = within(menu).getByText(UsersTableLanguage.resetPasswordMenuItem)
51+
fireEvent.click(resetPasswordButton)
52+
53+
// Check if the confirm message is displayed
54+
const confirmDialog = screen.getByRole("dialog")
55+
expect(confirmDialog).toHaveTextContent(`You will need to send ${MockUser.username} the following password:`)
56+
57+
// Setup spies to check the actions after
58+
setupActionSpies()
59+
60+
// Click on the "Confirm" button
61+
const confirmButton = within(confirmDialog).getByRole("button", { name: ResetPasswordDialogLanguage.confirmText })
62+
fireEvent.click(confirmButton)
63+
}
64+
3765
describe("Users Page", () => {
3866
it("shows users", async () => {
3967
render(<UsersPage />)
@@ -81,7 +109,7 @@ describe("Users Page", () => {
81109
jest.spyOn(API, "suspendUser").mockRejectedValueOnce({})
82110
})
83111

84-
// Check if the success message is displayed
112+
// Check if the error message is displayed
85113
await screen.findByText(usersXServiceLanguage.suspendUserError)
86114

87115
// Check if the API was called correctly
@@ -90,4 +118,50 @@ describe("Users Page", () => {
90118
})
91119
})
92120
})
121+
122+
describe("reset user password", () => {
123+
describe("when it is success", () => {
124+
it("shows a success message", async () => {
125+
render(
126+
<>
127+
<UsersPage />
128+
<GlobalSnackbar />
129+
</>,
130+
)
131+
132+
await resetUserPassword(() => {
133+
jest.spyOn(API, "updateUserPassword").mockResolvedValueOnce(undefined)
134+
})
135+
136+
// Check if the success message is displayed
137+
await screen.findByText(usersXServiceLanguage.resetUserPasswordSuccess)
138+
139+
// Check if the API was called correctly
140+
expect(API.updateUserPassword).toBeCalledTimes(1)
141+
expect(API.updateUserPassword).toBeCalledWith(expect.any(String), MockUser.id)
142+
})
143+
})
144+
145+
describe("when it fails", () => {
146+
it("shows an error message", async () => {
147+
render(
148+
<>
149+
<UsersPage />
150+
<GlobalSnackbar />
151+
</>,
152+
)
153+
154+
await resetUserPassword(() => {
155+
jest.spyOn(API, "updateUserPassword").mockRejectedValueOnce({})
156+
})
157+
158+
// Check if the error message is displayed
159+
await screen.findByText(usersXServiceLanguage.resetUserPasswordError)
160+
161+
// Check if the API was called correctly
162+
expect(API.updateUserPassword).toBeCalledTimes(1)
163+
expect(API.updateUserPassword).toBeCalledWith(expect.any(String), MockUser.id)
164+
})
165+
})
166+
})
93167
})

site/src/pages/UsersPage/UsersPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export const UsersPage: React.FC = () => {
6868
/>
6969

7070
<ResetPasswordDialog
71+
loading={usersState.matches("resettingUserPassword")}
7172
user={userToResetPassword}
7273
newPassword={newUserPassword}
7374
open={usersState.matches("confirmUserPasswordReset")}

site/src/xServices/users/usersXService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ export const usersMachine = createMachine(
255255
displaySuccess(Language.resetUserPasswordSuccess)
256256
},
257257
displayResetPasswordErrorMessage: () => {
258-
displaySuccess(Language.resetUserPasswordError)
258+
displayError(Language.resetUserPasswordError)
259259
},
260260
generateRandomPassword: assign({
261261
newUserPassword: (_) => generateRandomString(12),

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy