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

341 lines
9.8 KiB
TypeScript

import { fireEvent, screen, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { HttpResponse, http } from "msw";
import * as API from "api/api";
import type { Role } from "api/typesGenerated";
import {
MockUser,
MockUser2,
SuspendedMockUser,
MockAuditorRole,
} from "testHelpers/entities";
import { renderWithAuth } from "testHelpers/renderHelpers";
import { server } from "testHelpers/server";
import { Language as ResetPasswordDialogLanguage } from "./ResetPasswordDialog";
import { UsersPage } from "./UsersPage";
const renderPage = () => {
return renderWithAuth(<UsersPage />);
};
const suspendUser = async () => {
const user = userEvent.setup();
// Get the first user in the table
const moreButtons = await screen.findAllByLabelText("More options");
const firstMoreButton = moreButtons[0];
await user.click(firstMoreButton);
const suspendButton = screen.getByTestId("suspend-button");
await user.click(suspendButton);
// Check if the confirm message is displayed
const confirmDialog = await screen.findByRole("dialog");
const confirmButton = await within(confirmDialog).findByRole("button", {
name: "Suspend",
});
await user.click(confirmButton);
};
const deleteUser = async () => {
const user = userEvent.setup();
// Click on the "More options" button to display the "Delete" option
// Needs to await fetching users and fetching permissions, because they're needed to see the more button
const moreButtons = await screen.findAllByLabelText("More options");
// get MockUser2
const selectedMoreButton = moreButtons[1];
await user.click(selectedMoreButton);
const deleteButton = screen.getByText(/Delete/);
await user.click(deleteButton);
// Confirm with text input
const textField = screen.getByLabelText("Name of the user to delete");
const dialog = screen.getByRole("dialog");
await user.type(textField, MockUser2.username);
// Click on the "Confirm" button
const confirmButton = within(dialog).getByRole("button", { name: "Delete" });
await user.click(confirmButton);
};
const activateUser = async () => {
const moreButtons = await screen.findAllByLabelText("More options");
const suspendedMoreButton = moreButtons[2];
fireEvent.click(suspendedMoreButton);
const activateButton = screen.getByText(/Activate/);
fireEvent.click(activateButton);
// Check if the confirm message is displayed
const confirmDialog = screen.getByRole("dialog");
// Click on the "Confirm" button
const confirmButton = within(confirmDialog).getByRole("button", {
name: "Activate",
});
fireEvent.click(confirmButton);
};
const resetUserPassword = async (setupActionSpies: () => void) => {
const moreButtons = await screen.findAllByLabelText("More options");
const firstMoreButton = moreButtons[0];
fireEvent.click(firstMoreButton);
const resetPasswordButton = screen.getByText(/Reset password/);
fireEvent.click(resetPasswordButton);
// Check if the confirm message is displayed
const confirmDialog = screen.getByRole("dialog");
expect(confirmDialog).toHaveTextContent(
`You will need to send ${MockUser.username} the following password:`,
);
// Setup spies to check the actions after
setupActionSpies();
// Click on the "Confirm" button
const confirmButton = within(confirmDialog).getByRole("button", {
name: ResetPasswordDialogLanguage.confirmText,
});
fireEvent.click(confirmButton);
};
const updateUserRole = async (role: Role) => {
// Get the first user in the table
const users = await screen.findAllByText(/.*@coder.com/);
const userRow = users[0].closest("tr");
if (!userRow) {
throw new Error("Error on get the first user row");
}
// Click on the "edit icon" to display the role options
const editButton = within(userRow).getByTitle("Edit user roles");
fireEvent.click(editButton);
// Click on the role option
const fieldset = await screen.findByTitle("Available roles");
const auditorOption = within(fieldset).getByText(role.display_name);
fireEvent.click(auditorOption);
return {
userRow,
};
};
jest.spyOn(console, "error").mockImplementation(() => {});
describe("UsersPage", () => {
describe("suspend user", () => {
describe("when it is success", () => {
it("shows a success message", async () => {
renderPage();
server.use(
http.put(`/api/v2/users/${MockUser.id}/status/suspend`, async () => {
return HttpResponse.json(SuspendedMockUser);
}),
);
await suspendUser();
// Check if the success message is displayed
await screen.findByText("Successfully suspended the user.");
});
});
describe("when it fails", () => {
it("shows an error message", async () => {
renderPage();
server.use(
http.put(`/api/v2/users/${MockUser.id}/status/suspend`, async () => {
return HttpResponse.json(
{
message: "Error suspending user.",
},
{ status: 400 },
);
}),
);
await suspendUser();
// Check if the error message is displayed
await screen.findByText("Error suspending user.");
});
});
});
describe("delete user", () => {
describe("when it is success", () => {
it("shows a success message", async () => {
renderPage();
server.use(
http.delete(`/api/v2/users/${MockUser2.id}`, async () => {
return HttpResponse.json(MockUser2);
}),
);
await deleteUser();
// Check if the success message is displayed
await screen.findByText("Successfully deleted the user.");
});
});
describe("when it fails", () => {
it("shows an error message", async () => {
renderPage();
server.use(
http.delete(`/api/v2/users/${MockUser2.id}`, async () => {
return HttpResponse.json(
{
message: "Error deleting user.",
},
{ status: 400 },
);
}),
);
await deleteUser();
// Check if the error message is displayed
await screen.findByText("Error deleting user.");
});
});
});
describe("activate user", () => {
describe("when user is successfully activated", () => {
it("shows a success message and refreshes the page", async () => {
renderPage();
server.use(
http.put(
`/api/v2/users/${SuspendedMockUser.id}/status/activate`,
async () => {
return HttpResponse.json(MockUser);
},
),
);
await activateUser();
// Check if the success message is displayed
await screen.findByText("Successfully activated the user.");
});
});
describe("when activation fails", () => {
it("shows an error message", async () => {
renderPage();
server.use(
http.put(
`/api/v2/users/${SuspendedMockUser.id}/status/activate`,
async () => {
return HttpResponse.json(
{
message: "Error activating user.",
},
{ status: 400 },
);
},
),
);
await activateUser();
// Check if the error message is displayed
await screen.findByText("Error activating user.");
});
});
});
describe("reset user password", () => {
describe("when it is success", () => {
it("shows a success message", async () => {
renderPage();
await resetUserPassword(() => {
jest
.spyOn(API, "updateUserPassword")
.mockResolvedValueOnce(undefined);
});
// Check if the success message is displayed
await screen.findByText("Successfully updated the user password.");
// Check if the API was called correctly
expect(API.updateUserPassword).toBeCalledTimes(1);
expect(API.updateUserPassword).toBeCalledWith(MockUser.id, {
password: expect.any(String),
old_password: "",
});
});
});
describe("when it fails", () => {
it("shows an error message", async () => {
renderPage();
await resetUserPassword(() => {
jest.spyOn(API, "updateUserPassword").mockRejectedValueOnce({});
});
// Check if the error message is displayed
await screen.findByText("Error on resetting the user password.");
// Check if the API was called correctly
expect(API.updateUserPassword).toBeCalledTimes(1);
expect(API.updateUserPassword).toBeCalledWith(MockUser.id, {
password: expect.any(String),
old_password: "",
});
});
});
});
describe("Update user role", () => {
describe("when it is success", () => {
it("updates the roles", async () => {
renderPage();
server.use(
http.put(`/api/v2/users/${MockUser.id}/roles`, async () => {
return HttpResponse.json({
...MockUser,
roles: [...MockUser.roles, MockAuditorRole],
});
}),
);
await updateUserRole(MockAuditorRole);
await screen.findByText("Successfully updated the user roles.");
});
});
describe("when it fails", () => {
it("shows an error message", async () => {
renderPage();
server.use(
http.put(`/api/v2/users/${MockUser.id}/roles`, () => {
return HttpResponse.json(
{ message: "Error on updating the user roles." },
{ status: 400 },
);
}),
);
await updateUserRole(MockAuditorRole);
// Check if the error message is displayed
await screen.findByText("Error on updating the user roles.");
});
});
});
});