mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: disable AccountForm when user is not allowed edit users (#3649)
* RED: add unit tests for AccountForm username field * GREEN: disable username field and button on account form when user edits are not allowed Co-authored-by: Joe Previte <jjprevite@gmail.com>
This commit is contained in:
co-authored by
Joe Previte
parent
b9dd566804
commit
6dacf70898
@@ -0,0 +1,65 @@
|
||||
import { screen } from "@testing-library/react"
|
||||
import { MockUser2 } from "../../testHelpers/entities"
|
||||
import { render } from "../../testHelpers/renderHelpers"
|
||||
import { AccountForm, AccountFormValues } from "./SettingsAccountForm"
|
||||
|
||||
// NOTE: it does not matter what the role props of MockUser are set to,
|
||||
// only that editable is set to true or false. This is passed from
|
||||
// the call to /authorization done by authXService
|
||||
describe("AccountForm", () => {
|
||||
describe("when editable is set to true", () => {
|
||||
it("allows updating username", async () => {
|
||||
// Given
|
||||
const mockInitialValues: AccountFormValues = {
|
||||
username: MockUser2.username,
|
||||
}
|
||||
|
||||
// When
|
||||
render(
|
||||
<AccountForm
|
||||
editable
|
||||
email={MockUser2.email}
|
||||
initialValues={mockInitialValues}
|
||||
isLoading={false}
|
||||
onSubmit={() => {
|
||||
return
|
||||
}}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Then
|
||||
const el = await screen.findByLabelText("Username")
|
||||
expect(el).toBeEnabled()
|
||||
const btn = await screen.findByRole("button", { name: /Update settings/i })
|
||||
expect(btn).toBeEnabled()
|
||||
})
|
||||
})
|
||||
|
||||
describe("when editable is set to false", () => {
|
||||
it("does not allow updating username", async () => {
|
||||
// Given
|
||||
const mockInitialValues: AccountFormValues = {
|
||||
username: MockUser2.username,
|
||||
}
|
||||
|
||||
// When
|
||||
render(
|
||||
<AccountForm
|
||||
editable={false}
|
||||
email={MockUser2.email}
|
||||
initialValues={mockInitialValues}
|
||||
isLoading={false}
|
||||
onSubmit={() => {
|
||||
return
|
||||
}}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Then
|
||||
const el = await screen.findByLabelText("Username")
|
||||
expect(el).toBeDisabled()
|
||||
const btn = await screen.findByRole("button", { name: /Update settings/i })
|
||||
expect(btn).toBeDisabled()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -7,7 +7,7 @@ import { getFormHelpersWithError, nameValidator, onChangeTrimmed } from "../../u
|
||||
import { LoadingButton } from "../LoadingButton/LoadingButton"
|
||||
import { Stack } from "../Stack/Stack"
|
||||
|
||||
interface AccountFormValues {
|
||||
export interface AccountFormValues {
|
||||
username: string
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ const validationSchema = Yup.object({
|
||||
})
|
||||
|
||||
export interface AccountFormProps {
|
||||
editable: boolean
|
||||
email: string
|
||||
isLoading: boolean
|
||||
initialValues: AccountFormValues
|
||||
@@ -32,6 +33,7 @@ export interface AccountFormProps {
|
||||
}
|
||||
|
||||
export const AccountForm: FC<React.PropsWithChildren<AccountFormProps>> = ({
|
||||
editable,
|
||||
email,
|
||||
isLoading,
|
||||
onSubmit,
|
||||
@@ -62,14 +64,22 @@ export const AccountForm: FC<React.PropsWithChildren<AccountFormProps>> = ({
|
||||
<TextField
|
||||
{...getFieldHelpers("username")}
|
||||
onChange={onChangeTrimmed(form)}
|
||||
aria-disabled={!editable}
|
||||
autoComplete="username"
|
||||
disabled={!editable}
|
||||
fullWidth
|
||||
label={Language.usernameLabel}
|
||||
variant="outlined"
|
||||
/>
|
||||
|
||||
<div>
|
||||
<LoadingButton loading={isLoading} type="submit" variant="contained">
|
||||
<LoadingButton
|
||||
loading={isLoading}
|
||||
aria-disabled={!editable}
|
||||
disabled={!editable}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
{isLoading ? "" : Language.updateSettings}
|
||||
</LoadingButton>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,8 @@ export const Language = {
|
||||
export const AccountPage: React.FC = () => {
|
||||
const xServices = useContext(XServiceContext)
|
||||
const [authState, authSend] = useActor(xServices.authXService)
|
||||
const { me, updateProfileError } = authState.context
|
||||
const { me, permissions, updateProfileError } = authState.context
|
||||
const canEditUsers = permissions && permissions.updateUsers
|
||||
|
||||
if (!me) {
|
||||
throw new Error("No current user found")
|
||||
@@ -20,10 +21,13 @@ export const AccountPage: React.FC = () => {
|
||||
return (
|
||||
<Section title={Language.title}>
|
||||
<AccountForm
|
||||
editable={Boolean(canEditUsers)}
|
||||
email={me.email}
|
||||
updateProfileError={updateProfileError}
|
||||
isLoading={authState.matches("signedIn.profile.updatingProfile")}
|
||||
initialValues={{ username: me.username }}
|
||||
initialValues={{
|
||||
username: me.username,
|
||||
}}
|
||||
onSubmit={(data) => {
|
||||
authSend({
|
||||
type: "UPDATE_PROFILE",
|
||||
|
||||
@@ -61,6 +61,16 @@ export const MockUser: TypesGen.User = {
|
||||
roles: [MockOwnerRole],
|
||||
}
|
||||
|
||||
export const MockUserAdmin: TypesGen.User = {
|
||||
id: "test-user",
|
||||
username: "TestUser",
|
||||
email: "test@coder.com",
|
||||
created_at: "",
|
||||
status: "active",
|
||||
organization_ids: ["fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0"],
|
||||
roles: [MockUserAdminRole],
|
||||
}
|
||||
|
||||
export const MockUser2: TypesGen.User = {
|
||||
id: "test-user-2",
|
||||
username: "TestUser2",
|
||||
|
||||
Reference in New Issue
Block a user