mirror of
https://github.com/prymitive/karma
synced 2026-05-13 03:56:59 +00:00
fix(ui): silence ID link doesn't point to the right URI
This commit is contained in:
@@ -94,7 +94,7 @@ const Alert = observer(
|
||||
am.silencedBy.map(silenceID => (
|
||||
<Silence
|
||||
key={silenceID}
|
||||
alertmanager={am}
|
||||
alertmanagerState={am}
|
||||
silenceID={silenceID}
|
||||
afterUpdate={afterUpdate}
|
||||
/>
|
||||
|
||||
@@ -123,17 +123,17 @@ SilenceDetails.propTypes = {
|
||||
};
|
||||
|
||||
//
|
||||
const FallbackSilenceDesciption = ({ alertmanager, silenceID }) => {
|
||||
const FallbackSilenceDesciption = ({ alertmanagerName, silenceID }) => {
|
||||
return (
|
||||
<div>
|
||||
<small className="text-muted">
|
||||
Silenced by {alertmanager.name}/{silenceID}
|
||||
Silenced by {alertmanagerName}/{silenceID}
|
||||
</small>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
FallbackSilenceDesciption.propTypes = {
|
||||
alertmanager: PropTypes.object.isRequired,
|
||||
alertmanagerName: PropTypes.string.isRequired,
|
||||
silenceID: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
@@ -142,7 +142,7 @@ const Silence = inject("alertStore")(
|
||||
class Silence extends Component {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.object.isRequired,
|
||||
alertmanager: PropTypes.object.isRequired,
|
||||
alertmanagerState: PropTypes.object.isRequired,
|
||||
silenceID: PropTypes.string.isRequired,
|
||||
afterUpdate: PropTypes.func.isRequired
|
||||
};
|
||||
@@ -187,14 +187,28 @@ const Silence = inject("alertStore")(
|
||||
this.progressTimer = setInterval(this.recalculateProgress, 30 * 1000);
|
||||
}
|
||||
|
||||
getAlertmanager = () => {
|
||||
const { alertStore, alertmanagerState } = this.props;
|
||||
|
||||
const alertmanager = alertStore.data.upstreams.instances.find(
|
||||
am => am.name === alertmanagerState.name
|
||||
);
|
||||
|
||||
if (alertmanager) return alertmanager;
|
||||
|
||||
return {
|
||||
name: alertmanagerState.name
|
||||
};
|
||||
};
|
||||
|
||||
getSilence = () => {
|
||||
const { alertStore, alertmanager, silenceID } = this.props;
|
||||
const { alertStore, alertmanagerState, silenceID } = this.props;
|
||||
|
||||
// We pass alertmanager name and silence ID to Silence component
|
||||
// and we need to lookup the actual silence data in the store.
|
||||
// Data might be missing from the store so first check if we have
|
||||
// anything for this alertmanager instance
|
||||
const amSilences = alertStore.data.silences[alertmanager.name];
|
||||
const amSilences = alertStore.data.silences[alertmanagerState.name];
|
||||
if (!amSilences) return null;
|
||||
|
||||
// next check if alertmanager has our silence ID
|
||||
@@ -222,17 +236,19 @@ const Silence = inject("alertStore")(
|
||||
}
|
||||
|
||||
render() {
|
||||
const { alertmanager, silenceID } = this.props;
|
||||
const { alertmanagerState, silenceID } = this.props;
|
||||
|
||||
const silence = this.getSilence();
|
||||
if (!silence)
|
||||
return (
|
||||
<FallbackSilenceDesciption
|
||||
alertmanager={alertmanager}
|
||||
alertmanagerName={alertmanagerState.name}
|
||||
silenceID={silenceID}
|
||||
/>
|
||||
);
|
||||
|
||||
const alertmanager = this.getAlertmanager();
|
||||
|
||||
return (
|
||||
<div className="card mt-1 border-0 p-1">
|
||||
<div className="card-text mb-0">
|
||||
|
||||
@@ -16,7 +16,6 @@ const mockAfterUpdate = jest.fn();
|
||||
|
||||
const alertmanager = {
|
||||
name: "default",
|
||||
uri: "file:///mock",
|
||||
state: "suppressed",
|
||||
startsAt: "2000-01-01T10:00:00Z",
|
||||
endsAt: "0001-01-01T00:00:00Z",
|
||||
@@ -78,12 +77,12 @@ afterEach(() => {
|
||||
clear();
|
||||
});
|
||||
|
||||
const MountedSilence = () => {
|
||||
const MountedSilence = alertmanagerState => {
|
||||
return mount(
|
||||
<Provider alertStore={alertStore}>
|
||||
<Silence
|
||||
alertStore={alertStore}
|
||||
alertmanager={alertmanager}
|
||||
alertmanagerState={alertmanagerState}
|
||||
silenceID="4cf5fd82-1edd-4169-99d1-ff8415e72179"
|
||||
afterUpdate={mockAfterUpdate}
|
||||
/>
|
||||
@@ -91,27 +90,36 @@ const MountedSilence = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const ShallowSilenceDetails = () => {
|
||||
return shallow(
|
||||
<SilenceDetails
|
||||
alertmanager={alertStore.data.upstreams.instances[0]}
|
||||
silence={silence}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
describe("<Silence />", () => {
|
||||
it("matches snapshot when data is present in alertStore", () => {
|
||||
const tree = MountedSilence().find("Silence");
|
||||
const tree = MountedSilence(alertmanager).find("Silence");
|
||||
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders full silence when data is present in alertStore", () => {
|
||||
const tree = MountedSilence().find("Silence");
|
||||
const tree = MountedSilence(alertmanager).find("Silence");
|
||||
const fallback = tree.find("FallbackSilenceDesciption");
|
||||
expect(fallback).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("matches snapshot when data is not present in alertStore", () => {
|
||||
alertStore.data.silences = {};
|
||||
const tree = MountedSilence().find("Silence");
|
||||
const tree = MountedSilence(alertmanager).find("Silence");
|
||||
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders FallbackSilenceDesciption when Alertmanager data is not present in alertStore", () => {
|
||||
alertStore.data.silences = {};
|
||||
const tree = MountedSilence();
|
||||
const tree = MountedSilence(alertmanager);
|
||||
const fallback = tree.find("FallbackSilenceDesciption");
|
||||
expect(fallback).toHaveLength(1);
|
||||
expect(tree.text()).toBe(
|
||||
@@ -121,7 +129,7 @@ describe("<Silence />", () => {
|
||||
|
||||
it("renders FallbackSilenceDesciption when silence data is not present in alertStore", () => {
|
||||
alertStore.data.silences.default = {};
|
||||
const tree = MountedSilence();
|
||||
const tree = MountedSilence(alertmanager);
|
||||
const fallback = tree.find("FallbackSilenceDesciption");
|
||||
expect(fallback).toHaveLength(1);
|
||||
expect(tree.text()).toBe(
|
||||
@@ -130,7 +138,7 @@ describe("<Silence />", () => {
|
||||
});
|
||||
|
||||
it("clicking on expand toggle shows silence details", () => {
|
||||
const tree = MountedSilence();
|
||||
const tree = MountedSilence(alertmanager);
|
||||
const toggle = tree.find("a.float-right.cursor-pointer");
|
||||
toggle.simulate("click");
|
||||
const details = tree.find("SilenceDetails");
|
||||
@@ -138,7 +146,7 @@ describe("<Silence />", () => {
|
||||
});
|
||||
|
||||
it("matches snapshot with expaned details", () => {
|
||||
const tree = MountedSilence().find("Silence");
|
||||
const tree = MountedSilence(alertmanager).find("Silence");
|
||||
tree.instance().collapse.toggle();
|
||||
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
|
||||
});
|
||||
@@ -146,26 +154,41 @@ describe("<Silence />", () => {
|
||||
it("renders comment as link when jiraURL is set", () => {
|
||||
alertStore.data.silences.default[silence.id].jiraURL =
|
||||
"http://jira.example.com";
|
||||
const tree = MountedSilence().find("Silence");
|
||||
const tree = MountedSilence(alertmanager).find("Silence");
|
||||
const link = tree.find("a[href='http://jira.example.com']");
|
||||
expect(link).toHaveLength(1);
|
||||
expect(link.text()).toBe("Fake silence");
|
||||
});
|
||||
|
||||
it("clears progress timer on unmount", () => {
|
||||
const tree = MountedSilence().find("Silence");
|
||||
const tree = MountedSilence(alertmanager).find("Silence");
|
||||
const instance = tree.instance();
|
||||
expect(instance.progressTimer).toBeTruthy();
|
||||
instance.componentWillUnmount();
|
||||
expect(instance.progressTimer).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
const ShallowSilenceDetails = () => {
|
||||
return shallow(
|
||||
<SilenceDetails alertmanager={alertmanager} silence={silence} />
|
||||
);
|
||||
};
|
||||
it("getAlertmanager() returns alertmanager object from alertStore.data.upstreams.instances", () => {
|
||||
const tree = MountedSilence(alertmanager).find("Silence");
|
||||
const instance = tree.instance();
|
||||
const am = instance.getAlertmanager();
|
||||
expect(am).toEqual({
|
||||
name: "default",
|
||||
uri: "file:///mock",
|
||||
error: ""
|
||||
});
|
||||
});
|
||||
|
||||
it("getAlertmanager() return object with only name if given name is not in alertStore", () => {
|
||||
const missingAlertmanager = { ...alertmanager, name: "notDefault" };
|
||||
const tree = MountedSilence(missingAlertmanager).find("Silence");
|
||||
const instance = tree.instance();
|
||||
const am = instance.getAlertmanager();
|
||||
expect(am).toEqual({
|
||||
name: "notDefault"
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("<SilenceDetails />", () => {
|
||||
it("unexpired silence endsAt label uses 'secondary' class", () => {
|
||||
@@ -180,25 +203,33 @@ describe("<SilenceDetails />", () => {
|
||||
const endsAt = tree.find("span.badge").at(1);
|
||||
expect(endsAt.html()).toMatch(/badge-danger/);
|
||||
});
|
||||
|
||||
it("id links to Alertmanager silence view", () => {
|
||||
const tree = ShallowSilenceDetails();
|
||||
const link = tree.find("a");
|
||||
expect(link.props().href).toBe(
|
||||
"file:///mock/#/silences/4cf5fd82-1edd-4169-99d1-ff8415e72179"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("<SilenceExpiryBadgeWithProgress />", () => {
|
||||
it("renders with class 'danger' and no progressbar when expired", () => {
|
||||
advanceTo(new Date(2001, 0, 1, 23, 0, 0));
|
||||
const tree = MountedSilence();
|
||||
const tree = MountedSilence(alertmanager);
|
||||
expect(tree.html()).toMatch(/badge-danger/);
|
||||
expect(tree.text()).toMatch(/Expired a year ago/);
|
||||
});
|
||||
|
||||
it("progressbar uses class 'danger' when > 90%", () => {
|
||||
advanceTo(new Date(2000, 0, 1, 19, 30, 0));
|
||||
const tree = MountedSilence();
|
||||
const tree = MountedSilence(alertmanager);
|
||||
expect(tree.html()).toMatch(/progress-bar bg-danger/);
|
||||
});
|
||||
|
||||
it("progressbar uses class 'danger' when > 75%", () => {
|
||||
advanceTo(new Date(2000, 0, 1, 17, 45, 0));
|
||||
const tree = MountedSilence();
|
||||
const tree = MountedSilence(alertmanager);
|
||||
expect(tree.html()).toMatch(/progress-bar bg-warning/);
|
||||
});
|
||||
|
||||
@@ -206,7 +237,7 @@ describe("<SilenceExpiryBadgeWithProgress />", () => {
|
||||
const startsAt = new Date(2000, 0, 1, 10, 0, 0);
|
||||
const endsAt = new Date(2000, 0, 1, 20, 0, 0);
|
||||
|
||||
const tree = MountedSilence().find("Silence");
|
||||
const tree = MountedSilence(alertmanager).find("Silence");
|
||||
const instance = tree.instance();
|
||||
|
||||
const value = toJS(instance.progress.value);
|
||||
|
||||
Reference in New Issue
Block a user