Move Send Invitation Email checkbox into modal footer, add tests
Place the checkbox inline with the submit button (left-aligned, vertically centered) in both the embedded and standalone forms. Add Vitest tests verifying the /user/new payload shape: default true, false when unchecked, in both form variants, plus an initial-state check for the modal.
This commit is contained in:
parent
3ce67bacad
commit
fde7c1087a
@ -354,4 +354,126 @@ describe("CreateUserButton", () => {
|
||||
expect(mockOrganizationMemberAddCall).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("send invitation email toggle", () => {
|
||||
it("should send send_invite_email true by default in embedded mode", async () => {
|
||||
const user = userEvent.setup();
|
||||
mockUserCreateCall.mockResolvedValue({ data: { user_id: "default-on-user" } });
|
||||
|
||||
renderWithProviders(
|
||||
<CreateUserButton {...defaultProps} possibleUIRoles={{ proxy_user: { ui_label: "User", description: "" } }} isEmbedded />,
|
||||
);
|
||||
|
||||
await user.type(screen.getByLabelText(/user email/i), "default@example.com");
|
||||
await user.click(screen.getByRole("combobox", { name: /user role/i }));
|
||||
await user.click(screen.getByText("User"));
|
||||
await user.click(screen.getByRole("button", { name: /create user/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockUserCreateCall).toHaveBeenCalledWith("token", null, expect.objectContaining({
|
||||
send_invite_email: true,
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
it("should send send_invite_email false when the checkbox is unchecked in embedded mode", async () => {
|
||||
const user = userEvent.setup();
|
||||
mockUserCreateCall.mockResolvedValue({ data: { user_id: "unchecked-user" } });
|
||||
|
||||
renderWithProviders(
|
||||
<CreateUserButton {...defaultProps} possibleUIRoles={{ proxy_user: { ui_label: "User", description: "" } }} isEmbedded />,
|
||||
);
|
||||
|
||||
await user.type(screen.getByLabelText(/user email/i), "off@example.com");
|
||||
await user.click(screen.getByRole("combobox", { name: /user role/i }));
|
||||
await user.click(screen.getByText("User"));
|
||||
await user.click(screen.getByRole("checkbox", { name: /send invitation email/i }));
|
||||
await user.click(screen.getByRole("button", { name: /create user/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockUserCreateCall).toHaveBeenCalledWith("token", null, expect.objectContaining({
|
||||
send_invite_email: false,
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
it("should send send_invite_email true by default in standalone mode", async () => {
|
||||
const user = userEvent.setup();
|
||||
mockUserCreateCall.mockResolvedValue({ data: { user_id: "standalone-default-user" } });
|
||||
mockInvitationCreateCall.mockResolvedValue({
|
||||
id: "inv-default",
|
||||
user_id: "standalone-default-user",
|
||||
has_user_setup_sso: false,
|
||||
} as any);
|
||||
|
||||
renderWithProviders(
|
||||
<CreateUserButton {...defaultProps} possibleUIRoles={{ proxy_user: { ui_label: "User", description: "" } }} />,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("button", { name: /\+ invite user/i })).toBeInTheDocument();
|
||||
});
|
||||
await user.click(screen.getByRole("button", { name: /\+ invite user/i }));
|
||||
|
||||
const dialog = screen.getByRole("dialog", { name: /invite user/i });
|
||||
await user.type(within(dialog).getByLabelText(/user email/i), "standalone-default@example.com");
|
||||
await user.click(within(dialog).getByRole("combobox", { name: /global proxy role/i }));
|
||||
await user.click(screen.getByText("User"));
|
||||
await user.click(within(dialog).getByRole("button", { name: /invite user/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockUserCreateCall).toHaveBeenCalledWith("token", null, expect.objectContaining({
|
||||
send_invite_email: true,
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
it("should send send_invite_email false when the checkbox is unchecked in standalone mode", async () => {
|
||||
const user = userEvent.setup();
|
||||
mockUserCreateCall.mockResolvedValue({ data: { user_id: "standalone-off-user" } });
|
||||
mockInvitationCreateCall.mockResolvedValue({
|
||||
id: "inv-off",
|
||||
user_id: "standalone-off-user",
|
||||
has_user_setup_sso: false,
|
||||
} as any);
|
||||
|
||||
renderWithProviders(
|
||||
<CreateUserButton {...defaultProps} possibleUIRoles={{ proxy_user: { ui_label: "User", description: "" } }} />,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("button", { name: /\+ invite user/i })).toBeInTheDocument();
|
||||
});
|
||||
await user.click(screen.getByRole("button", { name: /\+ invite user/i }));
|
||||
|
||||
const dialog = screen.getByRole("dialog", { name: /invite user/i });
|
||||
await user.type(within(dialog).getByLabelText(/user email/i), "standalone-off@example.com");
|
||||
await user.click(within(dialog).getByRole("combobox", { name: /global proxy role/i }));
|
||||
await user.click(screen.getByText("User"));
|
||||
await user.click(within(dialog).getByRole("checkbox", { name: /send invitation email/i }));
|
||||
await user.click(within(dialog).getByRole("button", { name: /invite user/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockUserCreateCall).toHaveBeenCalledWith("token", null, expect.objectContaining({
|
||||
send_invite_email: false,
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
it("should keep the checkbox checked by default when the modal is opened in standalone mode", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
renderWithProviders(
|
||||
<CreateUserButton {...defaultProps} possibleUIRoles={{ proxy_user: { ui_label: "User", description: "" } }} />,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("button", { name: /\+ invite user/i })).toBeInTheDocument();
|
||||
});
|
||||
await user.click(screen.getByRole("button", { name: /\+ invite user/i }));
|
||||
|
||||
const dialog = screen.getByRole("dialog", { name: /invite user/i });
|
||||
expect(within(dialog).getByRole("checkbox", { name: /send invitation email/i })).toBeChecked();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -225,15 +225,21 @@ export const CreateUserButton: React.FC<CreateuserProps> = ({
|
||||
<Input.TextArea rows={4} placeholder="Enter metadata as JSON" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="send_invite_email"
|
||||
valuePropName="checked"
|
||||
wrapperCol={{ offset: 8, span: 16 }}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
marginTop: "10px",
|
||||
}}
|
||||
>
|
||||
<Checkbox>Send invitation email</Checkbox>
|
||||
</Form.Item>
|
||||
|
||||
<div style={{ textAlign: "right", marginTop: "10px" }}>
|
||||
<Form.Item
|
||||
name="send_invite_email"
|
||||
valuePropName="checked"
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Checkbox>Send invitation email</Checkbox>
|
||||
</Form.Item>
|
||||
<Button htmlType="submit">Create User</Button>
|
||||
</div>
|
||||
</Form>
|
||||
@ -370,15 +376,21 @@ export const CreateUserButton: React.FC<CreateuserProps> = ({
|
||||
</AccordionBody>
|
||||
</Accordion>
|
||||
|
||||
<Form.Item
|
||||
name="send_invite_email"
|
||||
valuePropName="checked"
|
||||
wrapperCol={{ offset: 8, span: 16 }}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
marginTop: "10px",
|
||||
}}
|
||||
>
|
||||
<Checkbox>Send invitation email</Checkbox>
|
||||
</Form.Item>
|
||||
|
||||
<div style={{ textAlign: "right", marginTop: "10px" }}>
|
||||
<Form.Item
|
||||
name="send_invite_email"
|
||||
valuePropName="checked"
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Checkbox>Send invitation email</Checkbox>
|
||||
</Form.Item>
|
||||
<Button type="primary" icon={<UserAddOutlined />} htmlType="submit">
|
||||
Invite User
|
||||
</Button>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user