Merge pull request #5814 from splunk/feature/update-splunk-on-call-invalid-team
Splunk On Call Card - Show blank card when team does not exist instead of no incidents found
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-splunk-on-call': patch
|
||||
---
|
||||
|
||||
Update Splunk On Call plugin to render warning message about incorrectly configured team annotation
|
||||
@@ -88,6 +88,12 @@ export const MOCK_TEAM: Team = {
|
||||
isDefaultTeam: false,
|
||||
};
|
||||
|
||||
export const MOCK_TEAM_NO_INCIDENTS: Team = {
|
||||
...MOCK_TEAM,
|
||||
name: 'test-noincidents',
|
||||
slug: 'team-O9SqT13fsnCstjMj',
|
||||
};
|
||||
|
||||
export const ESCALATION_POLICIES: EscalationPolicyInfo[] = [
|
||||
{
|
||||
policy: {
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
MOCKED_USER,
|
||||
MOCK_INCIDENT,
|
||||
MOCK_TEAM,
|
||||
MOCK_TEAM_NO_INCIDENTS,
|
||||
} from '../api/mocks';
|
||||
import { EntitySplunkOnCallCard } from './EntitySplunkOnCallCard';
|
||||
|
||||
@@ -76,7 +77,22 @@ const mockEntityData = {
|
||||
metadata: {
|
||||
name: 'splunkoncall-test',
|
||||
annotations: {
|
||||
'splunk.com/on-call-team': 'Example',
|
||||
'splunk.com/on-call-team': 'test',
|
||||
},
|
||||
},
|
||||
} as Entity,
|
||||
};
|
||||
|
||||
const mockEntityDataNoIncidents = {
|
||||
loading: false,
|
||||
error: undefined,
|
||||
entity: {
|
||||
apiVersion: 'backstage.io/v1alpha1',
|
||||
kind: 'Component',
|
||||
metadata: {
|
||||
name: 'splunkoncall-test',
|
||||
annotations: {
|
||||
'splunk.com/on-call-team': 'test-noincidents',
|
||||
},
|
||||
},
|
||||
} as Entity,
|
||||
@@ -87,11 +103,14 @@ describe('SplunkOnCallCard', () => {
|
||||
mockSplunkOnCallApi.getUsers = jest
|
||||
.fn()
|
||||
.mockImplementationOnce(async () => [MOCKED_USER]);
|
||||
mockSplunkOnCallApi.getTeams = jest
|
||||
.fn()
|
||||
.mockImplementation(async () => [MOCK_TEAM_NO_INCIDENTS]);
|
||||
|
||||
const { getByText, queryByTestId } = render(
|
||||
wrapInTestApp(
|
||||
<ApiProvider apis={apis}>
|
||||
<EntityContext.Provider value={mockEntityData}>
|
||||
<EntityContext.Provider value={mockEntityDataNoIncidents}>
|
||||
<EntitySplunkOnCallCard />
|
||||
</EntityContext.Provider>
|
||||
</ApiProvider>,
|
||||
@@ -148,10 +167,36 @@ describe('SplunkOnCallCard', () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('handles warning for incorrect team annotation', async () => {
|
||||
mockSplunkOnCallApi.getUsers = jest
|
||||
.fn()
|
||||
.mockImplementationOnce(async () => [MOCKED_USER]);
|
||||
mockSplunkOnCallApi.getTeams = jest
|
||||
.fn()
|
||||
.mockImplementationOnce(async () => []);
|
||||
|
||||
const { getByText, queryByTestId } = render(
|
||||
wrapInTestApp(
|
||||
<ApiProvider apis={apis}>
|
||||
<EntityContext.Provider value={mockEntityData}>
|
||||
<EntitySplunkOnCallCard />
|
||||
</EntityContext.Provider>
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
await waitFor(() => !queryByTestId('progress'));
|
||||
expect(
|
||||
getByText('Could not find team named "test" in the Splunk On-Call API'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('opens the dialog when trigger button is clicked', async () => {
|
||||
mockSplunkOnCallApi.getUsers = jest
|
||||
.fn()
|
||||
.mockImplementationOnce(async () => [MOCKED_USER]);
|
||||
mockSplunkOnCallApi.getTeams = jest
|
||||
.fn()
|
||||
.mockImplementationOnce(async () => [MOCK_TEAM]);
|
||||
|
||||
const { getByText, queryByTestId, getByRole } = render(
|
||||
wrapInTestApp(
|
||||
|
||||
@@ -49,6 +49,16 @@ export const MissingTeamAnnotation = () => (
|
||||
<MissingAnnotationEmptyState annotation={SPLUNK_ON_CALL_TEAM} />
|
||||
);
|
||||
|
||||
export const InvalidTeamAnnotation = ({ teamName }: { teamName: string }) => (
|
||||
<CardContent>
|
||||
<EmptyState
|
||||
title={`Could not find team named "${teamName}" in the Splunk On-Call API`}
|
||||
missing="info"
|
||||
description={`Escalation Policy and incident information unavailable. Please verify that the team you added "${teamName}" is valid if you want to enable Splunk On-Call.`}
|
||||
/>
|
||||
</CardContent>
|
||||
);
|
||||
|
||||
export const MissingEventsRestEndpoint = () => (
|
||||
<CardContent>
|
||||
<EmptyState
|
||||
@@ -81,7 +91,7 @@ export const EntitySplunkOnCallCard = () => {
|
||||
setShowDialog(x => !x);
|
||||
}, []);
|
||||
|
||||
const { value: users, loading, error } = useAsync(async () => {
|
||||
const { value: usersAndTeam, loading, error } = useAsync(async () => {
|
||||
const allUsers = await api.getUsers();
|
||||
const usersHashMap = allUsers.reduce(
|
||||
(map: Record<string, User>, obj: User) => {
|
||||
@@ -92,7 +102,9 @@ export const EntitySplunkOnCallCard = () => {
|
||||
},
|
||||
{},
|
||||
);
|
||||
return { usersHashMap, userList: allUsers };
|
||||
const teams = await api.getTeams();
|
||||
const foundTeam = teams.find(teamValue => teamValue.name === team);
|
||||
return { usersHashMap, foundTeam };
|
||||
});
|
||||
|
||||
if (error instanceof UnauthorizedError) {
|
||||
@@ -116,6 +128,10 @@ export const EntitySplunkOnCallCard = () => {
|
||||
return <MissingTeamAnnotation />;
|
||||
}
|
||||
|
||||
if (!usersAndTeam?.foundTeam) {
|
||||
return <InvalidTeamAnnotation teamName={team} />;
|
||||
}
|
||||
|
||||
if (!eventsRestEndpoint) {
|
||||
return <MissingEventsRestEndpoint />;
|
||||
}
|
||||
@@ -123,8 +139,8 @@ export const EntitySplunkOnCallCard = () => {
|
||||
return (
|
||||
<>
|
||||
<Incidents team={team} refreshIncidents={refreshIncidents} />
|
||||
{users?.usersHashMap && team && (
|
||||
<EscalationPolicy team={team} users={users.usersHashMap} />
|
||||
{usersAndTeam?.usersHashMap && team && (
|
||||
<EscalationPolicy team={team} users={usersAndTeam.usersHashMap} />
|
||||
)}
|
||||
<TriggerDialog
|
||||
team={team}
|
||||
|
||||
Reference in New Issue
Block a user