-
Notifications
You must be signed in to change notification settings - Fork 8.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0b706c9
commit bdd7295
Showing
2 changed files
with
241 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
184 changes: 184 additions & 0 deletions
184
...ages/features/ee/organizations/pages/settings/attributes/__tests__/AttributeForm.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import { render, screen, waitFor } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
import React from "react"; | ||
import type { Mock } from "vitest"; | ||
import { vi } from "vitest"; | ||
|
||
import { Button } from "@calcom/ui"; | ||
|
||
import { AttributeForm } from "../AttributesForm"; | ||
|
||
vi.mock("@calcom/lib/hooks/useLocale", () => ({ | ||
useLocale: vi.fn(() => ({ | ||
t: (key: string) => key, | ||
})), | ||
})); | ||
|
||
type InitialOption = { | ||
id?: string; | ||
value: string; | ||
isGroup?: boolean; | ||
contains?: string[]; | ||
attributeOptionId?: string; | ||
assignedUsers?: number; | ||
}; | ||
|
||
// Page Object Functions | ||
const AttributeFormActions = { | ||
setup: () => { | ||
const user = userEvent.setup(); | ||
const mockOnSubmit = vi.fn(); | ||
return { user, mockOnSubmit }; | ||
}, | ||
|
||
render: (initialOptions: InitialOption[], mockOnSubmit: Mock) => { | ||
return render( | ||
<AttributeForm | ||
onSubmit={mockOnSubmit} | ||
initialValues={{ | ||
attrName: "Teams", | ||
type: "MULTI_SELECT", | ||
options: initialOptions, | ||
}} | ||
header={<Button type="submit">Save</Button>} | ||
/> | ||
); | ||
}, | ||
|
||
addOptionToGroup: async (user: ReturnType<typeof userEvent.setup>) => { | ||
const selects = await screen.findAllByText("choose_an_option"); | ||
await user.click(selects[0]); | ||
}, | ||
|
||
selectOption: async (user: ReturnType<typeof userEvent.setup>, optionText: string) => { | ||
const option = await screen.findByText(optionText); | ||
await user.click(option); | ||
}, | ||
|
||
submitForm: async (user: ReturnType<typeof userEvent.setup>) => { | ||
const submitButton = screen.getByRole("button", { name: "Save" }); | ||
await user.click(submitButton); | ||
}, | ||
|
||
deleteOption: async (user: ReturnType<typeof userEvent.setup>, index: number) => { | ||
const deleteButtons = screen.getAllByTitle("remove_option"); | ||
await user.click(deleteButtons[index]); | ||
}, | ||
|
||
expectGroupContainsOptions: async (mockOnSubmit: Mock, groupValue: string, containsIds: string[]) => { | ||
await waitFor(() => { | ||
expect(mockOnSubmit).toHaveBeenCalledWith( | ||
expect.objectContaining({ | ||
options: expect.arrayContaining([ | ||
expect.objectContaining({ | ||
value: groupValue, | ||
isGroup: true, | ||
contains: expect.arrayContaining(containsIds), | ||
}), | ||
]), | ||
}) | ||
); | ||
}); | ||
}, | ||
|
||
expectGroupNotContainsOptions: async (mockOnSubmit: Mock, groupValue: string, notContainsIds: string[]) => { | ||
await waitFor(() => { | ||
expect(mockOnSubmit).toHaveBeenCalledWith( | ||
expect.objectContaining({ | ||
options: expect.arrayContaining([ | ||
expect.objectContaining({ | ||
value: groupValue, | ||
isGroup: true, | ||
contains: expect.not.arrayContaining(notContainsIds), | ||
}), | ||
]), | ||
}) | ||
); | ||
}); | ||
}, | ||
|
||
expectDeleteConfirmationDialog: () => { | ||
expect(screen.getByText("delete_attribute")).toBeInTheDocument(); | ||
expect(screen.getByText("delete_attribute_description")).toBeInTheDocument(); | ||
}, | ||
|
||
expectOptionToBeDeleted: async (mockOnSubmit: Mock, optionValue: string) => { | ||
await waitFor(() => { | ||
expect(mockOnSubmit).toHaveBeenCalledWith( | ||
expect.objectContaining({ | ||
options: expect.not.arrayContaining([ | ||
expect.objectContaining({ | ||
value: optionValue, | ||
}), | ||
]), | ||
}) | ||
); | ||
}); | ||
}, | ||
}; | ||
|
||
const initialOptionsWithAGroupHavingOptions: InitialOption[] = [ | ||
{ id: "1", value: "Engineering", isGroup: false, attributeOptionId: "1" }, | ||
{ id: "2", value: "Design", isGroup: false, attributeOptionId: "2" }, | ||
{ id: "3", value: "Product", isGroup: false, attributeOptionId: "3" }, | ||
{ | ||
id: "4", | ||
value: "Tech Teams", | ||
isGroup: true, | ||
contains: ["1", "3"], | ||
attributeOptionId: "4", | ||
}, | ||
]; | ||
|
||
const initialOptionsWithAGroupHavingNoOptions: InitialOption[] = [ | ||
{ id: "1", value: "Engineering", isGroup: false, attributeOptionId: "1" }, | ||
{ id: "2", value: "Design", isGroup: false, attributeOptionId: "2" }, | ||
{ id: "3", value: "Product", isGroup: false, attributeOptionId: "3" }, | ||
{ | ||
id: "4", | ||
value: "Tech Teams", | ||
isGroup: true, | ||
contains: [], | ||
attributeOptionId: "4", | ||
}, | ||
]; | ||
|
||
describe("AttributeForm", () => { | ||
describe("Group Options Handling", () => { | ||
it("should handle adding non-group options to existing group", async () => { | ||
const { user, mockOnSubmit } = AttributeFormActions.setup(); | ||
AttributeFormActions.render(initialOptionsWithAGroupHavingNoOptions, mockOnSubmit); | ||
|
||
await AttributeFormActions.addOptionToGroup(user); | ||
await AttributeFormActions.selectOption(user, "Design"); | ||
await AttributeFormActions.submitForm(user); | ||
|
||
await AttributeFormActions.expectGroupContainsOptions(mockOnSubmit, "Tech Teams", ["2"]); | ||
}); | ||
|
||
it.only("should handle removing options from group when the option is deleted", async () => { | ||
const { user, mockOnSubmit } = AttributeFormActions.setup(); | ||
AttributeFormActions.render(initialOptionsWithAGroupHavingOptions, mockOnSubmit); | ||
|
||
await AttributeFormActions.deleteOption(user, 0); | ||
await AttributeFormActions.submitForm(user); | ||
await AttributeFormActions.expectGroupNotContainsOptions(mockOnSubmit, "Tech Teams", ["1"]); | ||
await AttributeFormActions.expectOptionToBeDeleted(mockOnSubmit, "Engineering"); | ||
}); | ||
|
||
it("should take confirmation before deleting option with assigned users", async () => { | ||
const { user, mockOnSubmit } = AttributeFormActions.setup(); | ||
const optionsWithAssignedUsers = initialOptionsWithAGroupHavingOptions.map((opt) => | ||
opt.value === "Engineering" ? { ...opt, assignedUsers: 5 } : opt | ||
); | ||
|
||
AttributeFormActions.render(optionsWithAssignedUsers, mockOnSubmit); | ||
await AttributeFormActions.deleteOption(user, 0); | ||
AttributeFormActions.expectDeleteConfirmationDialog(); | ||
const confirmationButton = screen.getByTestId("dialog-confirmation"); | ||
await user.click(confirmationButton); | ||
await AttributeFormActions.submitForm(user); | ||
await AttributeFormActions.expectGroupNotContainsOptions(mockOnSubmit, "Tech Teams", ["1"]); | ||
}); | ||
}); | ||
}); |