Skip to content

Commit

Permalink
fix(ui): display machine notifications on the summary only (#1853)
Browse files Browse the repository at this point in the history
Move the machine notifications to only display on the summary page and update the component for use
with other tabs.

Fixes: #1851.

Co-authored-by: Caleb Ellis <[email protected]>
  • Loading branch information
huwshimi and Caleb Ellis authored Nov 10, 2020
1 parent 5a587c7 commit a4bb445
Show file tree
Hide file tree
Showing 7 changed files with 410 additions and 320 deletions.
4 changes: 2 additions & 2 deletions ui/src/app/machines/views/MachineDetails/MachineDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, { useEffect, useState } from "react";
import type { RouteParams } from "app/base/types";
import { machine as machineActions } from "app/base/actions";
import MachineHeader from "./MachineHeader";
import MachineNotifications from "./MachineNotifications";
import SummaryNotifications from "./MachineSummary/SummaryNotifications";
import machineSelectors from "app/store/machine/selectors";
import MachineStorage from "./MachineStorage";
import MachineSummary, { SelectedAction } from "./MachineSummary";
Expand Down Expand Up @@ -51,10 +51,10 @@ const MachineDetails = (): JSX.Element => {
}
headerClassName="u-no-padding--bottom"
>
<MachineNotifications />
{machine && (
<Switch>
<Route exact path="/machine/:id/summary">
<SummaryNotifications id={id} />
<MachineSummary setSelectedAction={setSelectedAction} />
</Route>
<Route exact path="/machine/:id/storage">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,213 +1,39 @@
import { MemoryRouter, Route } from "react-router-dom";
import { mount } from "enzyme";
import { Provider } from "react-redux";
import configureStore from "redux-mock-store";
import React from "react";

import {
architecturesState as architecturesStateFactory,
generalState as generalStateFactory,
machine as machineFactory,
machineEvent as machineEventFactory,
machineState as machineStateFactory,
powerType as powerTypeFactory,
powerTypesState as powerTypesStateFactory,
rootState as rootStateFactory,
} from "testing/factories";
import MachineNotifications from "./MachineNotifications";
import type { RootState } from "app/store/root/types";

const mockStore = configureStore();

describe("MachineNotifications", () => {
let state: RootState;
beforeEach(() => {
state = rootStateFactory({
general: generalStateFactory({
architectures: architecturesStateFactory({
data: ["amd64"],
}),
powerTypes: powerTypesStateFactory({
data: [powerTypeFactory()],
}),
}),
machine: machineStateFactory({
items: [
machineFactory({
architecture: "amd64",
events: [machineEventFactory()],
system_id: "abc123",
}),
],
}),
});
});

it("handles no notifications", () => {
const store = mockStore(state);
it("can render", () => {
const wrapper = mount(
<Provider store={store}>
<MemoryRouter
initialEntries={[{ pathname: "/machine/abc123", key: "testKey" }]}
>
<Route
exact
path="/machine/:id"
component={() => <MachineNotifications />}
/>
</MemoryRouter>
</Provider>
<MachineNotifications
notifications={[
{
active: true,
content:
"Editing is currently disabled because no rack controller is currently connected to the region.",
status: "Error:",
type: "negative",
},
]}
/>
);
expect(wrapper.find("Notification").exists()).toBe(false);
expect(wrapper.find("MachineNotifications")).toMatchSnapshot();
});

it("can display a power error", () => {
state.machine.items = [
machineFactory({
architecture: "amd64",
events: [
machineEventFactory({
description: "machine timed out",
}),
],
power_state: "error",
system_id: "abc123",
}),
];
const store = mockStore(state);
it("ignores inactive notifications", () => {
const wrapper = mount(
<Provider store={store}>
<MemoryRouter
initialEntries={[{ pathname: "/machine/abc123", key: "testKey" }]}
>
<Route
exact
path="/machine/:id"
component={() => <MachineNotifications />}
/>
</MemoryRouter>
</Provider>
<MachineNotifications
notifications={[
{
active: false,
content: "Don't show me!",
status: "Error:",
type: "negative",
},
]}
/>
);
expect(
wrapper
.findWhere(
(n) =>
n.name() === "Notification" &&
n.text().includes("Script - machine timed out")
)
.exists()
).toBe(true);
});

it("can display a rack connection error", () => {
state.general.powerTypes.data = [];
const store = mockStore(state);
const wrapper = mount(
<Provider store={store}>
<MemoryRouter
initialEntries={[{ pathname: "/machine/abc123", key: "testKey" }]}
>
<Route
exact
path="/machine/:id"
component={() => <MachineNotifications />}
/>
</MemoryRouter>
</Provider>
);
expect(
wrapper
.findWhere(
(n) =>
n.name() === "Notification" &&
n.text().includes("no rack controller is currently connected")
)
.exists()
).toBe(true);
});

it("can display an architecture error", () => {
state.machine.items[0].architecture = "";
const store = mockStore(state);
const wrapper = mount(
<Provider store={store}>
<MemoryRouter
initialEntries={[{ pathname: "/machine/abc123", key: "testKey" }]}
>
<Route
exact
path="/machine/:id"
component={() => <MachineNotifications />}
/>
</MemoryRouter>
</Provider>
);
expect(
wrapper
.findWhere(
(n) =>
n.name() === "Notification" &&
n
.text()
.includes("This machine currently has an invalid architecture")
)
.exists()
).toBe(true);
});

it("can display a boot images error", () => {
state.general.architectures = architecturesStateFactory({
data: [],
});
const store = mockStore(state);
const wrapper = mount(
<Provider store={store}>
<MemoryRouter
initialEntries={[{ pathname: "/machine/abc123", key: "testKey" }]}
>
<Route
exact
path="/machine/:id"
component={() => <MachineNotifications />}
/>
</MemoryRouter>
</Provider>
);
expect(
wrapper
.findWhere(
(n) =>
n.name() === "Notification" &&
n.text().includes("No boot images have been imported")
)
.exists()
).toBe(true);
});

it("can display a hardware error", () => {
state.machine.items[0].cpu_count = 0;
const store = mockStore(state);
const wrapper = mount(
<Provider store={store}>
<MemoryRouter
initialEntries={[{ pathname: "/machine/abc123", key: "testKey" }]}
>
<Route
exact
path="/machine/:id"
component={() => <MachineNotifications />}
/>
</MemoryRouter>
</Provider>
);
expect(
wrapper
.findWhere(
(n) =>
n.name() === "Notification" &&
n.text().includes("Commission this machine to get CPU")
)
.exists()
).toBe(true);
expect(wrapper.find("Notification").exists()).toBe(false);
});
});
Loading

0 comments on commit a4bb445

Please sign in to comment.