Skip to content

Commit

Permalink
Hide creation buttons on search and recents tabs (#42977)
Browse files Browse the repository at this point in the history
* hide creation buttons on search and recents tabs

* update e2e tests
  • Loading branch information
iethree committed May 24, 2024
1 parent e1e845a commit c77f7f2
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 85 deletions.
4 changes: 4 additions & 0 deletions e2e/test/scenarios/dashboard/dashboard.cy.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ describe("scenarios > dashboard", () => {
.should("have.text", "Our analytics")
.click();
});

entityPickerModal()
.findByRole("tab", { name: /Collections/ })
.click();
entityPickerModal()
.findByText("Create a new collection")
.click({ force: true });
Expand Down
5 changes: 5 additions & 0 deletions e2e/test/scenarios/question/new.cy.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,11 @@ describe("scenarios > question > new", () => {
cy.findByTestId("save-question-modal")
.findByLabelText(/Which collection/)
.click();

entityPickerModal()
.findByRole("tab", { name: /Collections/ })
.click();

entityPickerModal().findByText("Create a new collection").click();

const NEW_COLLECTION = "Foo";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ export function EntityPickerModal<
null,
);

const [showActionButtons, setShowActionButtons] = useState<boolean>(
!!actionButtons.length,
);

const hydratedOptions = useMemo(
() => ({ ...defaultOptions, ...options }),
[options],
Expand Down Expand Up @@ -206,6 +210,7 @@ export function EntityPickerModal<
selectedItem={selectedItem}
initialValue={initialValue}
defaultToRecentTab={defaultToRecentTab}
setShowActionButtons={setShowActionButtons}
/>
) : (
<SinglePickerView>{tabs[0].element}</SinglePickerView>
Expand All @@ -215,7 +220,7 @@ export function EntityPickerModal<
onConfirm={onConfirm}
onCancel={onClose}
canConfirm={canSelectItem}
actionButtons={actionButtons}
actionButtons={showActionButtons ? actionButtons : []}
confirmButtonText={options?.confirmButtonText}
cancelButtonText={options?.cancelButtonText}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,28 @@ const TEST_TABLE_TAB: EntityTab<SampleModelType> = {
element: <TestPicker name="bar" />,
};

const mockSearchResults = createMockSearchResults({
items: [
createMockSearchResult({
name: "Search Result 1",
model: "collection",
can_write: true,
id: 100,
}),
createMockSearchResult({
name: "Search Result 2",
model: "collection",
can_write: true,
id: 101,
}),
],
});

const setup = ({
title = "Pick a thing",
onItemSelect = jest.fn(),
onClose = jest.fn(),
onConfirm,
onConfirm = jest.fn(),
tabs = [TEST_CARD_TAB],
selectedItem = null,
recentItems = [],
Expand All @@ -73,6 +90,10 @@ const setup = ({
mockScrollBy();
setupRecentViewsEndpoints(recentItems);

fetchMock.get("path:/api/search", mockSearchResults);

fetchMock.get("path:/api/user/recipients", { data: [] });

renderWithProviders(
<EntityPickerModal
title={title}
Expand All @@ -99,41 +120,18 @@ describe("EntityPickerModal", () => {
options: {
hasConfirmButtons: true,
},
onConfirm: undefined,
// @ts-expect-error testing invalid prop
onConfirm: null,
});
}).toThrow("onConfirm prop is required when hasConfirmButtons is true");
});

it("should render a picker", async () => {
setup({
onConfirm: jest.fn(),
});
setup();

expect(await screen.findByText("Test picker foo")).toBeInTheDocument();
});

it("should render a search bar by default and show confirmation button", async () => {
setup({
onConfirm: jest.fn(),
});

expect(await screen.findByPlaceholderText("Search…")).toBeInTheDocument();
expect(
await screen.findByRole("button", { name: "Select" }),
).toBeInTheDocument();
});

it("should be able to disable the search bar", () => {
setup({
options: {
showSearch: false,
},
onConfirm: jest.fn(),
});

expect(screen.queryByPlaceholderText("Search…")).not.toBeInTheDocument();
});

it("should show a tab list when more than 1 tab is supplied", async () => {
setup({
tabs: [
Expand All @@ -145,7 +143,6 @@ describe("EntityPickerModal", () => {
element: <TestPicker name="bar" />,
},
],
onConfirm: jest.fn(),
});

const tabList = await screen.findByRole("tablist");
Expand All @@ -166,52 +163,6 @@ describe("EntityPickerModal", () => {
expect(await screen.findByText("Test picker bar")).toBeInTheDocument();
});

it("should show a search tab list when we type in the search input", async () => {
fetchMock.get(
"path:/api/search",
createMockSearchResults({
items: [
createMockSearchResult({
name: "Search Result 1",
model: "collection",
can_write: true,
id: 100,
}),
createMockSearchResult({
name: "Search Result 2",
model: "collection",
can_write: true,
id: 101,
}),
],
}),
);

fetchMock.get("path:/api/user/recipients", { data: [] });

const onItemSelect = jest.fn();

setup({
onItemSelect,
onConfirm: jest.fn(),
});

await userEvent.type(await screen.findByPlaceholderText("Search…"), "My ", {
delay: 50,
});

expect(await screen.findByRole("tablist")).toBeInTheDocument();
expect(
await screen.findByRole("tab", { name: /2 results for "My"/ }),
).toBeInTheDocument();

expect(await screen.findAllByTestId("result-item")).toHaveLength(2);

await userEvent.click(await screen.findByText("Search Result 1"));

expect(onItemSelect).toHaveBeenCalledTimes(1);
});

it("should accept an array of action buttons", async () => {
const actionFn = jest.fn();

Expand All @@ -221,10 +172,7 @@ describe("EntityPickerModal", () => {
</Button>,
];

setup({
actionButtons,
onConfirm: jest.fn(),
});
setup({ actionButtons });

expect(
await screen.findByRole("button", { name: "Click Me" }),
Expand All @@ -236,6 +184,86 @@ describe("EntityPickerModal", () => {
expect(actionFn).toHaveBeenCalledTimes(1);
});

describe("Search", () => {
it("should show a search tab list when we type in the search input", async () => {
const onItemSelect = jest.fn();

setup({
onItemSelect,
});

await userEvent.type(
await screen.findByPlaceholderText("Search…"),
"My ",
{
delay: 50,
},
);

expect(await screen.findByRole("tablist")).toBeInTheDocument();
expect(
await screen.findByRole("tab", { name: /2 results for "My"/ }),
).toBeInTheDocument();

expect(await screen.findAllByTestId("result-item")).toHaveLength(2);

await userEvent.click(await screen.findByText("Search Result 1"));

expect(onItemSelect).toHaveBeenCalledTimes(1);
});

it("should render a search bar by default and show confirmation button", async () => {
setup();

expect(await screen.findByPlaceholderText("Search…")).toBeInTheDocument();
expect(
await screen.findByRole("button", { name: "Select" }),
).toBeInTheDocument();
});

it("should be able to disable the search bar", () => {
setup({
options: {
showSearch: false,
},
});

expect(screen.queryByPlaceholderText("Search…")).not.toBeInTheDocument();
});

it("should not show action buttons on search tab", async () => {
const actionFn = jest.fn();

const actionButtons = [
<Button onClick={actionFn} key="1">
Click Me
</Button>,
];

setup({
actionButtons,
});

expect(
await screen.findByRole("button", { name: "Click Me" }),
).toBeInTheDocument();

await userEvent.type(
await screen.findByPlaceholderText("Search…"),
"caterpie",
{
delay: 50,
},
);

await userEvent.click(await screen.findByRole("tab", { name: /Search/ }));

expect(
screen.queryByRole("button", { name: "Click Me" }),
).not.toBeInTheDocument();
});
});

describe("Recents Tab", () => {
const recentItems = [
createMockRecentCollectionItem({
Expand Down Expand Up @@ -270,7 +298,7 @@ describe("EntityPickerModal", () => {
];

it("should not show a recents tab when there are no recent items", async () => {
setup({ onConfirm: jest.fn() });
setup();

await screen.findByText("Test picker foo");

Expand All @@ -280,7 +308,6 @@ describe("EntityPickerModal", () => {
it("should show a recents tab when there are recent items", async () => {
setup({
recentItems,
onConfirm: jest.fn(),
});

expect(
Expand All @@ -294,7 +321,6 @@ describe("EntityPickerModal", () => {
recentItems,
defaultToRecentTab: false,
initialValue: { model: "card" },
onConfirm: jest.fn(),
});

expect(
Expand All @@ -306,15 +332,13 @@ describe("EntityPickerModal", () => {
it("should group recents by time", async () => {
setup({
recentItems,
onConfirm: jest.fn(),
});

expect(await screen.findByText("Earlier")).toBeInTheDocument();
});

it("should filter out irrelevant models", async () => {
setup({
onConfirm: jest.fn(),
recentItems,
tabs: [TEST_CARD_TAB, TEST_TABLE_TAB],
});
Expand All @@ -326,7 +350,6 @@ describe("EntityPickerModal", () => {

it("should accept an arbitrary filter", async () => {
setup({
onConfirm: jest.fn(),
recentItems,
recentFilter: items =>
items.filter(item => !item.description?.includes("invisible")),
Expand All @@ -335,5 +358,34 @@ describe("EntityPickerModal", () => {
expect(await screen.findByText("Recent Question")).toBeInTheDocument();
expect(screen.queryByText("Recent Question 2")).not.toBeInTheDocument();
});

it("should not show action buttons on recents tab", async () => {
const actionFn = jest.fn();

const actionButtons = [
<Button onClick={actionFn} key="1">
Click Me
</Button>,
];

setup({
actionButtons,
recentItems,
});

await screen.findByRole("tab", { name: /Recents/ });

expect(
screen.queryByRole("button", { name: "Click Me" }),
).not.toBeInTheDocument();

await userEvent.click(
await screen.findByRole("tab", { name: /All the foo/ }),
);

expect(
await screen.findByRole("button", { name: "Click Me" }),
).toBeInTheDocument();
});
});
});
Loading

0 comments on commit c77f7f2

Please sign in to comment.