mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-04 00:08:55 +00:00
fix(iam): cancelling the Edit User dialog no longer reopens it (#15879)
This commit is contained in:
@@ -128,6 +128,7 @@
|
||||
"landing-regression.spec.js",
|
||||
"internal-route-guards.spec.js",
|
||||
"datetime-paste-invalid-values-14648.spec.js",
|
||||
"iam-users-15546-edit-dialog-cancel.spec.js",
|
||||
"query-management-sql-tooltip.spec.js"
|
||||
],
|
||||
"disabled": []
|
||||
|
||||
@@ -355,6 +355,12 @@ export class IamFormValidationPage {
|
||||
return this.page.locator(this.editBasicUserFirstBtn).count();
|
||||
}
|
||||
|
||||
async clickFirstEditUserButton() {
|
||||
await this.page.locator(this.editBasicUserFirstBtn).first().click();
|
||||
}
|
||||
|
||||
getUrlWithUserActionPattern() { return /[?&]action=(update|add)\b|[?&]email=/; }
|
||||
|
||||
async navigateToUsersTab() {
|
||||
await this.navigateToIam();
|
||||
const tab = this.page.locator(this.iamUsersTab);
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
const { test, expect, navigateToBase } = require('../../utils/enhanced-baseFixtures.js');
|
||||
const testLogger = require('../../utils/test-logger.js');
|
||||
const PageManager = require('../../../pages/page-manager.js');
|
||||
|
||||
test.describe("IAM Users edit dialog cancel Regression", () => {
|
||||
let pm;
|
||||
|
||||
test.beforeEach(async ({ page }, testInfo) => {
|
||||
testLogger.testStart(testInfo.title, testInfo.file);
|
||||
await navigateToBase(page);
|
||||
pm = new PageManager(page);
|
||||
await pm.iamFormValidation.navigateToUsersTab();
|
||||
});
|
||||
|
||||
test("cancelled edit dialog stays closed and leaves no action in the URL @bug-15546 @P3 @regression @iamUsers", async ({ page }) => {
|
||||
const iam = pm.iamFormValidation;
|
||||
|
||||
await iam.openUpdateRoleDialogForFirstUser();
|
||||
await expect(page).toHaveURL(/action=update/);
|
||||
|
||||
await iam.getUpdateRoleCancelBtnLocator().click();
|
||||
await expect(iam.getUpdateRoleDialogLocator()).toBeHidden();
|
||||
await expect(page).not.toHaveURL(iam.getUrlWithUserActionPattern());
|
||||
|
||||
// Outlast the dialog's 100ms open timer so a late reopen is caught.
|
||||
await page.waitForTimeout(2000);
|
||||
await expect(iam.getUpdateRoleDialogLocator()).toBeHidden();
|
||||
testLogger.info('Edit dialog stayed closed and URL is clean after Cancel');
|
||||
});
|
||||
|
||||
test("edit dialog cancelled during a slow roles load does not reopen @bug-15546 @P3 @regression @iamUsers", async ({ page }) => {
|
||||
const iam = pm.iamFormValidation;
|
||||
await page.route(/\/api\/[^/]+\/users\/roles(\?.*)?$/, async (route) => {
|
||||
await new Promise((r) => setTimeout(r, 3000));
|
||||
await route.continue();
|
||||
});
|
||||
|
||||
await page.reload();
|
||||
await iam.clickFirstEditUserButton();
|
||||
await expect(iam.getUpdateRoleDialogLocator()).toBeVisible();
|
||||
await iam.getUpdateRoleCancelBtnLocator().click();
|
||||
await expect(iam.getUpdateRoleDialogLocator()).toBeHidden();
|
||||
|
||||
await page.waitForTimeout(4500);
|
||||
await expect(iam.getUpdateRoleDialogLocator()).toBeHidden();
|
||||
await expect(page).not.toHaveURL(iam.getUrlWithUserActionPattern());
|
||||
});
|
||||
});
|
||||
@@ -1051,6 +1051,62 @@ describe("User Component", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("AddUser dialog dismissal (#15546)", () => {
|
||||
it("clears action/email from the URL when the dialog is cancelled", async () => {
|
||||
const replaceSpy = vi.spyOn(router, "replace").mockImplementation(() => Promise.resolve());
|
||||
wrapper.vm.showAddUserDialog = true;
|
||||
await flushPromises();
|
||||
|
||||
wrapper.findComponent(AddUserStub).vm.$emit("update:open", false);
|
||||
await flushPromises();
|
||||
|
||||
expect(wrapper.vm.showAddUserDialog).toBe(false);
|
||||
expect(replaceSpy).toHaveBeenCalledWith({
|
||||
name: "users",
|
||||
query: { org_identifier: store.state.selectedOrganization.identifier },
|
||||
});
|
||||
replaceSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("drops a pending open timer when the form is hidden", async () => {
|
||||
const replaceSpy = vi.spyOn(router, "replace").mockImplementation(() => Promise.resolve());
|
||||
wrapper.vm.addUser({ row: { email: "test@example.com" } }, true);
|
||||
wrapper.vm.hideForm();
|
||||
await new Promise((r) => setTimeout(r, 150));
|
||||
|
||||
expect(wrapper.vm.showAddUserDialog).toBe(false);
|
||||
replaceSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("does not reopen the edit dialog when it was cancelled while the page was still loading", async () => {
|
||||
sharedUsersState.users = [];
|
||||
queryClient.clear();
|
||||
let resolveRoles: (v: any) => void = () => {};
|
||||
mockUsersService.getRoles.mockReturnValue(new Promise((r) => (resolveRoles = r)) as any);
|
||||
await router.push({
|
||||
name: "users",
|
||||
query: {
|
||||
action: "update",
|
||||
email: "test@example.com",
|
||||
org_identifier: store.state.selectedOrganization.identifier,
|
||||
},
|
||||
});
|
||||
const late = mountUser();
|
||||
await flushPromises();
|
||||
|
||||
late.findComponent(AddUserStub).vm.$emit("update:open", false);
|
||||
await flushPromises();
|
||||
expect(router.currentRoute.value.query.action).toBeUndefined();
|
||||
|
||||
resolveRoles({ data: [{ label: "admin", value: "admin" }] });
|
||||
await flushPromises();
|
||||
await new Promise((r) => setTimeout(r, 150));
|
||||
|
||||
expect((late.vm as any).showAddUserDialog).toBe(false);
|
||||
late.unmount();
|
||||
});
|
||||
});
|
||||
|
||||
describe("hideForm", () => {
|
||||
it("should hide add user dialog and navigate", () => {
|
||||
const replaceSpy = vi.spyOn(router, "replace").mockImplementation(() => Promise.resolve());
|
||||
|
||||
@@ -283,7 +283,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
/>
|
||||
|
||||
<AddUser
|
||||
v-model:open="showAddUserDialog"
|
||||
:open="showAddUserDialog"
|
||||
@update:open="onAddUserOpenChange"
|
||||
v-model="selectedUser"
|
||||
:isUpdated="isUpdated"
|
||||
:userRole="currentUserRole"
|
||||
@@ -1117,6 +1118,8 @@ export default defineComponent({
|
||||
showUpdateUserDialog.value = true;
|
||||
};
|
||||
|
||||
let openAddUserTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
const addUser = (props: any, is_updated: boolean) => {
|
||||
isUpdated.value = is_updated;
|
||||
selectedUser.value.organization = store.state.selectedOrganization.identifier;
|
||||
@@ -1133,7 +1136,8 @@ export default defineComponent({
|
||||
} else {
|
||||
selectedUser.value = {};
|
||||
}
|
||||
setTimeout(() => {
|
||||
clearTimeout(openAddUserTimer);
|
||||
openAddUserTimer = setTimeout(() => {
|
||||
showAddUserDialog.value = true;
|
||||
}, 100);
|
||||
};
|
||||
@@ -1227,6 +1231,7 @@ export default defineComponent({
|
||||
};
|
||||
|
||||
const hideForm = () => {
|
||||
clearTimeout(openAddUserTimer);
|
||||
showAddUserDialog.value = false;
|
||||
router.replace({
|
||||
name: "users",
|
||||
@@ -1236,6 +1241,11 @@ export default defineComponent({
|
||||
});
|
||||
};
|
||||
|
||||
const onAddUserOpenChange = (open: boolean) => {
|
||||
if (open) showAddUserDialog.value = true;
|
||||
else hideForm();
|
||||
};
|
||||
|
||||
const addMember = async (res: any, data: any, operationType: string) => {
|
||||
showAddUserDialog.value = false;
|
||||
if (res.code == 200) {
|
||||
@@ -1576,6 +1586,7 @@ export default defineComponent({
|
||||
addRoutePush,
|
||||
addMember,
|
||||
hideForm,
|
||||
onAddUserOpenChange,
|
||||
isUpdated,
|
||||
showAddUserDialog,
|
||||
selectedUser,
|
||||
|
||||
Reference in New Issue
Block a user