-
Notifications
You must be signed in to change notification settings - Fork 51
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
dfb398a
commit 36f3ca3
Showing
25 changed files
with
514 additions
and
101 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { generateMAASURL, generateName } from "../../utils"; | ||
|
||
context("Settings - DHCP Snippets", () => { | ||
beforeEach(() => { | ||
cy.login(); | ||
cy.addMachine(); | ||
cy.visit(generateMAASURL("/settings/dhcp/add")); | ||
}); | ||
|
||
it("can add a DHCP snippet to a machine", () => { | ||
const snippetName = generateName("dhcp-snippet"); | ||
cy.get("[data-testid='section-header-title']").contains("Settings"); | ||
cy.findByLabelText("Snippet name").type(snippetName); | ||
cy.findByLabelText("Type").select("Machine"); | ||
cy.findByRole("button", { name: /Choose machine/ }).click(); | ||
// ensure the data has loaded | ||
cy.findByRole("grid").should("have.attr", "aria-busy", "false"); | ||
cy.get("tbody").within(() => { | ||
cy.findAllByRole("row").first().click(); | ||
}); | ||
cy.findByLabelText("DHCP snippet").type("ddns-update-style none;"); | ||
cy.findByRole("button", { name: "Save snippet" }).click(); | ||
// expect to be redirected to the list page | ||
cy.findByLabelText("Search DHCP snippets").type(snippetName); | ||
cy.findByRole("grid").within(() => { | ||
cy.findByText(snippetName).should("be.visible"); | ||
cy.findByRole("button", { name: /Delete/ }).click(); | ||
cy.get("[data-testid='action-confirm']").click(); | ||
}); | ||
}); | ||
}); |
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
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
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
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
27 changes: 27 additions & 0 deletions
27
src/app/base/components/DhcpFormFields/MachineSelect/MachineSelect.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,27 @@ | ||
import { screen } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
|
||
import MachineSelect, { Labels } from "./MachineSelect"; | ||
|
||
import { renderWithMockStore } from "testing/utils"; | ||
|
||
it("can open select box on click", async () => { | ||
renderWithMockStore(<MachineSelect onSelect={jest.fn()} />); | ||
|
||
expect(screen.queryByRole("listbox")).not.toBeInTheDocument(); | ||
await userEvent.click( | ||
screen.getByRole("button", { name: Labels.ChooseMachine }) | ||
); | ||
expect(screen.getByRole("listbox")).toBeInTheDocument(); | ||
}); | ||
|
||
it("sets focus on the input field on open", async () => { | ||
renderWithMockStore(<MachineSelect onSelect={jest.fn()} />); | ||
|
||
await userEvent.click( | ||
screen.getByRole("button", { name: Labels.ChooseMachine }) | ||
); | ||
expect( | ||
screen.getByPlaceholderText("Search by hostname, system ID or tags") | ||
).toHaveFocus(); | ||
}); |
75 changes: 75 additions & 0 deletions
75
src/app/base/components/DhcpFormFields/MachineSelect/MachineSelect.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,75 @@ | ||
import { useEffect, useState } from "react"; | ||
|
||
import { Label, useId } from "@canonical/react-components"; | ||
import className from "classnames"; | ||
import { useDispatch } from "react-redux"; | ||
|
||
import SelectButton from "../../SelectButton"; | ||
|
||
import MachineSelectBox from "./MachineSelectBox"; | ||
|
||
import type { Machine } from "app/store/machine/types"; | ||
import { useFetchMachine } from "app/store/machine/utils/hooks"; | ||
import { actions as tagActions } from "app/store/tag"; | ||
|
||
export enum Labels { | ||
AppliesTo = "Applies to", | ||
Loading = "Loading...", | ||
ChooseMachine = "Choose machine", | ||
} | ||
|
||
type Props = { | ||
label?: string; | ||
onSelect: (machine: Machine | null) => void; | ||
selected?: Machine["system_id"] | null; | ||
}; | ||
|
||
export const MachineSelect = ({ | ||
label = Labels.AppliesTo, | ||
onSelect, | ||
selected = null, | ||
}: Props): JSX.Element => { | ||
const dispatch = useDispatch(); | ||
const [isOpen, setIsOpen] = useState(false); | ||
const selectId = useId(); | ||
const handleSelect = (machine: Machine | null) => { | ||
setIsOpen(false); | ||
onSelect(machine); | ||
}; | ||
|
||
const { machine: selectedMachine } = useFetchMachine(selected, { | ||
keepPreviousData: true, | ||
}); | ||
|
||
useEffect(() => { | ||
dispatch(tagActions.fetch()); | ||
}, [dispatch]); | ||
|
||
return ( | ||
<div className="machine-select"> | ||
<Label id={selectId}>{label}</Label> | ||
<SelectButton | ||
aria-describedby={selectId} | ||
aria-haspopup="listbox" | ||
className="u-no-margin--bottom" | ||
onClick={() => { | ||
setIsOpen(!isOpen); | ||
if (!isOpen) { | ||
onSelect(null); | ||
} | ||
}} | ||
> | ||
{selectedMachine?.hostname || Labels.ChooseMachine} | ||
</SelectButton> | ||
<div | ||
className={className("machine-select-box-wrapper", { | ||
"machine-select-box-wrapper--is-open": isOpen, | ||
})} | ||
> | ||
{isOpen ? <MachineSelectBox onSelect={handleSelect} /> : null} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default MachineSelect; |
Oops, something went wrong.