Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release: 0.2.0 #7

Merged
merged 5 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ yarn add --cwd packages/backend @pagerduty/backstage-plugin-backend

### Configuration

To use the custom actions as part of your custom project templates follow the instructions on the `Create PagerDuty service with Software Templates` section of the project's documentation [here](https://pagerduty.github.io/backstage-plugin-docs/).

To use the custom actions as part of your custom project templates follow the instructions on the `Create PagerDuty service with Software Templates` section of the project's documentation [here](https://pagerduty.github.io/backstage-plugin-docs/advanced/create-service-software-template/).

## Support

Expand Down
33 changes: 33 additions & 0 deletions config.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export interface Config {
/**
* Configuration for the PagerDuty plugin
* @visibility frontend
*/
pagerDuty?: {
/**
* Optional Events Base URL to override the default.
* @visibility frontend
*/
eventsBaseUrl?: string;
/**
* Optional PagerDuty API Token used in API calls from the backend component.
* @visibility frontend
*/
apiToken?: string;
};
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
"typescript": "^4.8.4"
},
"files": [
"dist"
"dist",
"config.d.ts"
],
"configSchema": "config.d.ts",
"packageManager": "[email protected]"
}
277 changes: 265 additions & 12 deletions src/apis/pagerduty.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable jest/no-conditional-expect */
import { createService, createServiceIntegration } from "./pagerduty";
import { HttpError } from "../types";
import { createService, createServiceIntegration, getAllEscalationPolicies } from "./pagerduty";

describe("PagerDuty API", () => {
afterEach(() => {
Expand Down Expand Up @@ -141,14 +142,15 @@ describe("PagerDuty API", () => {
global.fetch = jest.fn(() =>
Promise.resolve({
status: 400,
json: () => Promise.resolve({})
})
) as jest.Mock;

const expectedErrorMessage = "Failed to create service integration. Caller provided invalid arguments.";

try {
await createServiceIntegration(serviceId, vendorId);
} catch (error) {
expect(((error as Error).message)).toEqual("Failed to create service integration. Caller provided invalid arguments.");
expect(((error as Error).message)).toEqual(expectedErrorMessage);
}
});

Expand All @@ -158,15 +160,16 @@ describe("PagerDuty API", () => {

global.fetch = jest.fn(() =>
Promise.resolve({
status: 401,
json: () => Promise.resolve({})
status: 401
})
) as jest.Mock;

const expectedErrorMessage = "Failed to create service integration. Caller did not supply credentials or did not provide the correct credentials.";

try {
await createServiceIntegration(serviceId, vendorId);
} catch (error) {
expect(((error as Error).message)).toEqual("Failed to create service integration. Caller did not supply credentials or did not provide the correct credentials.");
expect(((error as Error).message)).toEqual(expectedErrorMessage);
}
});

Expand All @@ -176,15 +179,16 @@ describe("PagerDuty API", () => {

global.fetch = jest.fn(() =>
Promise.resolve({
status: 403,
json: () => Promise.resolve({})
status: 403
})
) as jest.Mock;

const expectedErrorMessage = "Failed to create service integration. Caller is not authorized to view the requested resource.";

try {
await createServiceIntegration(serviceId, vendorId);
} catch (error) {
expect(((error as Error).message)).toEqual("Failed to create service integration. Caller is not authorized to view the requested resource.");
expect(((error as Error).message)).toEqual(expectedErrorMessage);
}
});

Expand All @@ -194,17 +198,266 @@ describe("PagerDuty API", () => {

global.fetch = jest.fn(() =>
Promise.resolve({
status: 429,
json: () => Promise.resolve({})
status: 429
})
) as jest.Mock;

const expectedErrorMessage = "Failed to create service integration. Rate limit exceeded.";

try {
await createServiceIntegration(serviceId, vendorId);
} catch (error) {
expect(((error as Error).message)).toEqual("Failed to create service integration. Rate limit exceeded.");
expect(((error as Error).message)).toEqual(expectedErrorMessage);
}
});
});

describe("getAllEscalationPolicies", () => {
it("should return ok", async () => {
const expectedId = "P0L1CY1D";
const expectedName = "Test Escalation Policy";

const expectedResponse = [
{
id: expectedId,
name: expectedName
}
];

global.fetch = jest.fn(() =>
Promise.resolve({
status: 200,
json: () => Promise.resolve({
escalation_policies: [
{
id: expectedId,
name: expectedName,
}
]
})
})
) as jest.Mock;

const result = await getAllEscalationPolicies();

expect(result).toEqual(expectedResponse);
expect(result.length).toEqual(1);
expect(fetch).toHaveBeenCalledTimes(1);
});

it("should NOT list escalation policies when caller provides invalid arguments", async () => {
global.fetch = jest.fn(() =>
Promise.resolve({
status: 400,
json: () => Promise.resolve({})
})
) as jest.Mock;

const expectedStatusCode = 400;
const expectedErrorMessage = "Failed to list escalation policies. Caller provided invalid arguments.";

try {
await getAllEscalationPolicies();
} catch (error) {
expect(((error as HttpError).status)).toEqual(expectedStatusCode);
expect(((error as HttpError).message)).toEqual(expectedErrorMessage);
}
});

it("should NOT list escalation policies when correct credentials are not provided", async () => {
global.fetch = jest.fn(() =>
Promise.resolve({
status: 401
})
) as jest.Mock;

const expectedStatusCode = 401;
const expectedErrorMessage = "Failed to list escalation policies. Caller did not supply credentials or did not provide the correct credentials.";

try {
await getAllEscalationPolicies();
} catch (error) {
expect(((error as HttpError).status)).toEqual(expectedStatusCode);
expect(((error as HttpError).message)).toEqual(expectedErrorMessage);
}
});

it("should NOT list escalation policies when account does not have abilities to perform the action", async () => {
global.fetch = jest.fn(() =>
Promise.resolve({
status: 403
})
) as jest.Mock;

const expectedStatusCode = 403;
const expectedErrorMessage = "Failed to list escalation policies. Caller is not authorized to view the requested resource.";

try {
await getAllEscalationPolicies();
} catch (error) {
expect(((error as HttpError).status)).toEqual(expectedStatusCode);
expect(((error as HttpError).message)).toEqual(expectedErrorMessage);
}
});

it("should NOT list escalation policies when user is not allowed to view the requested resource", async () => {
global.fetch = jest.fn(() =>
Promise.resolve({
status: 429
})
) as jest.Mock;

const expectedStatusCode = 429;
const expectedErrorMessage = "Failed to list escalation policies. Rate limit exceeded.";

try {
await getAllEscalationPolicies();
} catch (error) {
expect(((error as HttpError).status)).toEqual(expectedStatusCode);
expect(((error as HttpError).message)).toEqual(expectedErrorMessage);
}
});

it("should work with pagination", async () => {
const expectedId = ["P0L1CY1D1", "P0L1CY1D2", "P0L1CY1D3", "P0L1CY1D4", "P0L1CY1D5", "P0L1CY1D6", "P0L1CY1D7", "P0L1CY1D8", "P0L1CY1D9", "P0L1CY1D10"];
const expectedName = ["Test Escalation Policy 1", "Test Escalation Policy 2", "Test Escalation Policy 3", "Test Escalation Policy 4", "Test Escalation Policy 5", "Test Escalation Policy 6", "Test Escalation Policy 7", "Test Escalation Policy 8", "Test Escalation Policy 9", "Test Escalation Policy 10"];

const expectedResponse = [
{
id: expectedId[0],
name: expectedName[0]
},
{
id: expectedId[1],
name: expectedName[1]
},
{
id: expectedId[2],
name: expectedName[2]
},
{
id: expectedId[3],
name: expectedName[3]
},
{
id: expectedId[4],
name: expectedName[4]
},
{
id: expectedId[5],
name: expectedName[5]
},
{
id: expectedId[6],
name: expectedName[6]
},
{
id: expectedId[7],
name: expectedName[7]
},
{
id: expectedId[8],
name: expectedName[8]
},
{
id: expectedId[9],
name: expectedName[9]
}
];

global.fetch = jest.fn().mockReturnValueOnce(
Promise.resolve({
status: 200,
json: () => Promise.resolve({
escalation_policies: [
{
id: expectedId[0],
name: expectedName[0],
},
{
id: expectedId[1],
name: expectedName[1],
}
],
more: true
})
})
).mockReturnValueOnce(
Promise.resolve({
status: 200,
json: () => Promise.resolve({
escalation_policies: [
{
id: expectedId[2],
name: expectedName[2],
},
{
id: expectedId[3],
name: expectedName[3],
}
],
more: true
})
})
).mockReturnValueOnce(
Promise.resolve({
status: 200,
json: () => Promise.resolve({
escalation_policies: [
{
id: expectedId[4],
name: expectedName[4],
},
{
id: expectedId[5],
name: expectedName[5],
}
],
more: true
})
})
).mockReturnValueOnce(
Promise.resolve({
status: 200,
json: () => Promise.resolve({
escalation_policies: [
{
id: expectedId[6],
name: expectedName[6],
},
{
id: expectedId[7],
name: expectedName[7],
}
],
more: true
})
})
).mockReturnValueOnce(
Promise.resolve({
status: 200,
json: () => Promise.resolve({
escalation_policies: [
{
id: expectedId[8],
name: expectedName[8],
},
{
id: expectedId[9],
name: expectedName[9],
}
],
more: false
})
})
) as jest.Mock;

const result = await getAllEscalationPolicies();

expect(result).toEqual(expectedResponse);
expect(result.length).toEqual(10);
expect(fetch).toHaveBeenCalledTimes(5);
});
});
});

Loading