Add smoke test and zapier.

This commit is contained in:
Nawaz Dhandala
2019-08-02 22:58:56 +05:30
parent 97438a6497
commit c95a039c3b
35 changed files with 4060 additions and 0 deletions

7
smoke-test/README.md Executable file
View File

@@ -0,0 +1,7 @@
# FYIPE SMOKE TESTS #
Smoke tests for fyipe
### Tools used ###
* `puppeteer`

3
smoke-test/index.test.js Executable file
View File

@@ -0,0 +1,3 @@
const smoketest = require('./smokeTest.test')
smoketest.smokeTest()

215
smoke-test/smokeTest.test.js Executable file
View File

@@ -0,0 +1,215 @@
module.exports = {
smokeTest: () => {
const faker = require('faker')
const puppeteer = require('puppeteer')
const user = {
name: faker.name.findName(),
email: faker.internet.email(),
website: 'www.testcompanyfyipe.com',
company: faker.company.companyName(),
companySize: 8,
message: faker.company.catchPhraseDescriptor(),
}
let page
let browser
const baseURL = 'http://localhost:1444'
// Enable for live viewing of tests.
/* beforeAll(async () => {
const width = 1200
const height = 720
browser = await puppeteer.launch(
{
headless: false,
slowMo: 60,
arg: [`--window-size=${width},${height}`],
},
)
page = await browser.newPage()
await page.setViewport({ width, height })
}) */
// Run this for headless testing with puppeteer.
beforeAll(async () => {
browser = await puppeteer.launch()
page = await browser.newPage()
})
afterAll(() => {
browser.close()
})
describe('Request demo', () => {
test('user can submit request a demo form', async () => {
await page.goto(`${baseURL}/enterprise/demo`)
await page.waitForSelector('#form-section')
await page.type('#fullname', user.name)
await page.type('#email', user.email)
await page.type('#website', user.website)
await page.click('#country')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#volume')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.type('#message', user.message)
await page.click('#request-demo-btn')
await page.waitForSelector('#success')
// Check if user's email is submitted successfully
const emailSubmitted = await page.evaluate(() => document.querySelector('.submitted-email').innerText)
expect(emailSubmitted).toBe(user.email)
}, 30000)
test('user can request for website monitoring resource', async () => {
await page.goto(`${baseURL}/enterprise/resources`)
await page.waitForSelector('#website-monitoring')
await Promise.all([
page.waitForNavigation(),
page.click('#website-monitoring'),
])
await page.waitForSelector('#form-section')
await page.type('#fullname', user.name)
await page.type('#email', user.email)
await page.type('#website', user.website)
await page.click('#country')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#volume')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#request-resource-btn')
// Check if user's email is submitted successfully
const emailSubmitted = await page.evaluate(() => document.querySelector('.submitted-email').innerText)
expect(emailSubmitted).toBe(user.email)
}, 30000)
test('user can request for speed equals revenue resource', async () => {
await page.goto(`${baseURL}/enterprise/resources`)
await page.waitForSelector('#speed-revenue')
await Promise.all([
page.waitForNavigation(),
page.click('#speed-revenue'),
])
await page.waitForSelector('#form-section')
await page.type('#fullname', user.name)
await page.type('#email', user.email)
await page.type('#website', user.website)
await page.click('#country')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#volume')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#request-resource-btn')
// Check if user's email is submitted successfully
const emailSubmitted = await page.evaluate(() => document.querySelector('.submitted-email').innerText)
expect(emailSubmitted).toBe(user.email)
}, 30000)
test('user can request for best practices resource', async () => {
await page.goto(`${baseURL}/enterprise/resources`)
await page.waitForSelector('#best-practices')
await Promise.all([
page.waitForNavigation(),
page.click('#best-practices'),
])
await page.waitForSelector('#form-section')
await page.type('#fullname', user.name)
await page.type('#email', user.email)
await page.type('#website', user.website)
await page.click('#country')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#volume')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#request-resource-btn')
// Check if user's email is submitted successfully
const emailSubmitted = await page.evaluate(() => document.querySelector('.submitted-email').innerText)
expect(emailSubmitted).toBe(user.email)
}, 30000)
test('user can request for peak performance resource', async () => {
await page.goto(`${baseURL}/enterprise/resources`)
await page.waitForSelector('#peak-performance')
await Promise.all([
page.waitForNavigation(),
page.click('#peak-performance'),
])
await page.waitForSelector('#form-section')
await page.type('#fullname', user.name)
await page.type('#email', user.email)
await page.type('#website', user.website)
await page.click('#country')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#volume')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#request-resource-btn')
// Check if user's email is submitted successfully
const emailSubmitted = await page.evaluate(() => document.querySelector('.submitted-email').innerText)
expect(emailSubmitted).toBe(user.email)
}, 30000)
test('user can signup for a fyipe account and logout', async () => {
await page.goto(baseURL)
await page.waitForSelector('#create-account-top')
await Promise.all([
page.waitForNavigation(),
page.click('#create-account-top'),
])
await page.waitForSelector('#main-body')
await page.type('#email', user.email)
await page.type('#name', user.name)
await page.type('#password', user.password)
await page.type('#confirmPassword', user.password)
await page.click('#create-account-button')
await page.waitForSelector('#card-form')
await page.type('#cardName', user.name)
await page.type('#cardNumber', user.cardNumber)
await page.type('#cvv', user.cvv)
await page.type('#expiry', user.expiry)
await page.type('#address1', user.address1)
await page.type('#address2', user.address2)
await page.type('#city', user.city)
await page.type('#state', user.state)
await page.type('#zipCode', user.zipCode)
await page.click('#country')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#create-account-button')
await page.waitForSelector('#companyName')
await page.type('#companyName', user.company)
await page.type('#companyRole', user.companyRole)
await page.click('#country')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.click('#companySize')
await page.keyboard.press('ArrowDown')
await page.keyboard.down('Enter')
await page.type('#companyPhoneNumber', user.companyPhoneNumber)
await page.type('#reference', user.reference)
await page.click('#create-account-button')
await page.waitForNavigation()
await page.click('#profile-menu')
await page.click('#logout-button')
await page.waitForSelector('#login')
}, 60000)
test('user can login to and logout of fyipe', async () => {
await page.goto(baseURL)
await page.waitForSelector('#sign-in')
await Promise.all([
page.waitForNavigation(),
page.click('#sign-in'),
])
await page.waitFor(5000)
await page.waitForSelector('#login')
await page.type('#email', user.email)
await page.type('#password', user.password)
await page.click('#login-button')
await page.waitForNavigation()
await page.click('#profile-menu')
await page.click('#logout-button')
await page.waitForSelector('#login')
}, 30000)
})
},
}

4
zapier/.eslintignore Executable file
View File

@@ -0,0 +1,4 @@
/node_modules
/build
/coverage
*.test.js

77
zapier/.eslintrc.json Executable file
View File

@@ -0,0 +1,77 @@
{
"parserOptions": {
"ecmaVersion": 8,
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true,
"spread": true
},
"sourceType": "module"
},
"env": {
"browser": true,
"node": true,
"jquery": true,
"es6": true,
"mocha": true
},
"plugins": [
"react"
],
"extends": ["eslint:recommended", "plugin:react/recommended"],
"parser": "babel-eslint",
"rules": {
"no-fallthrough": "error",
"no-unreachable": "error",
"no-cond-assign": "error",
"valid-typeof": "error",
"no-func-assign": "error",
"no-extra-semi": "error",
"no-unused-vars": [
"error",
{
"varsIgnorePattern": "[iI]gnored",
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true,
"argsIgnorePattern": "[iI]gnored"
}
],
"no-undef": "error",
"no-empty": "error",
"no-case-declarations": "error",
"no-mixed-spaces-and-tabs": "error",
"no-useless-escape": "error",
"react/jsx-no-undef": "error",
"quotes": ["error", "single"],
"react/jsx-no-bind": ["error", {
"allowArrowFunctions": true,
"allowBind": false,
"ignoreRefs": false
}],
"react/no-children-prop": "error",
"react/no-deprecated": "error",
"react/no-array-index-key": "off",
"react/boolean-prop-naming": "error",
"react/no-is-mounted": "error",
"react/no-find-dom-node": "error",
"react/no-did-update-set-state": "error",
"react/no-unknown-property": "error",
"react/no-unused-prop-types": "error",
"react/jsx-no-duplicate-props": "error",
"react/no-unused-state": "error",
"react/jsx-uses-vars": "error",
"react/prop-types": "error",
"react/react-in-jsx-scope": "error",
"react/no-string-refs": "warn",
"jsx-a11y/href-no-hash": [0],
"react/no-unescaped-entities": "error",
"react/display-name": ["error", {
"ignoreTranspilerName": true
}]
}
}

22
zapier/.gitignore vendored Executable file
View File

@@ -0,0 +1,22 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
#builds
/build
# dependencies
#/backend/node_modules
/node_modules
.vscode/
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
yarn.lock
**/*/paymentService.test.js

41
zapier/.gitlab-ci.yml Executable file
View File

@@ -0,0 +1,41 @@
image: docker:stable
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
services:
- docker:dind
before_script:
- apk update && apk add curl curl-dev bash git python openssl py-pip python-dev libffi-dev openssl-dev gcc g++ libc-dev make nodejs npm
- npm install
- npm run audit
cache:
paths:
- node_modules/
stages:
- build_n_test
- cleanup
build_n_test:
stage: build_n_test
script:
- npm run lint
cleanup_job:
stage: cleanup
script: |
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE}/purge_cache" \
-H "X-Auth-Email: ${CF_EMAIL}" \
-H "X-Auth-Key: ${CF_API_KEY}" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
only:
refs:
- master
- release
when: on_success

4
zapier/.zapierapprc Executable file
View File

@@ -0,0 +1,4 @@
{
"id": 4576,
"key": "App4576"
}

View File

@@ -0,0 +1,55 @@
const acknowledgeAllIncidents = (z, bundle) => {
if (bundle.cleanedRequest) return bundle.cleanedRequest;
const data = {
monitors: bundle.inputData.monitors
};
const responsePromise = z.request({
method: 'POST',
url: 'https://api.fyipe.com/zapier/incident/acknowledgeAllIncidents',
body: data
});
return responsePromise
.then(response => JSON.parse(response.content));
};
module.exports = {
key: 'acknowledge_all_incidents',
noun: 'Acknowledge',
display: {
label: 'Acknowledge All Incidents',
description: 'Acknowledges all incidents.',
important: true
},
operation: {
inputFields: [
{
key: 'monitors',
type: 'string',
placeholder:'list of monitors',
dynamic: 'monitors.id.name',
altersDynamicFields: true,
list:true,
required: true
}
],
perform: acknowledgeAllIncidents,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
acknowledged: true,
resolved: false,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
acknowledgedAt: new Date().toISOString(),
acknowledgedBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};

View File

@@ -0,0 +1,55 @@
const acknowledgeIncident = (z, bundle) => {
if (bundle.cleanedRequest) return bundle.cleanedRequest;
const data = {
incidents: bundle.inputData.incidents
};
const responsePromise = z.request({
method: 'POST',
url: 'https://api.fyipe.com/zapier/incident/acknowledgeIncident',
body: data
});
return responsePromise
.then(response => JSON.parse(response.content));
};
module.exports = {
key: 'acknowledge_incident',
noun: 'Acknowledge',
display: {
label: 'Acknowledge Incident',
description: 'Acknowledges incident.',
important: true
},
operation: {
inputFields: [
{
key: 'incidents',
type: 'string',
placeholder:'list of incidents',
dynamic: 'incidents.id',
altersDynamicFields: true,
list:true,
required: true
}
],
perform: acknowledgeIncident,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
acknowledged: true,
resolved: false,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
acknowledgedAt: new Date().toISOString(),
acknowledgedBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};

View File

@@ -0,0 +1,55 @@
const acknowledgeLastIncident = (z, bundle) => {
if (bundle.cleanedRequest) return bundle.cleanedRequest;
const data = {
monitors: bundle.inputData.monitors
};
const responsePromise = z.request({
method: 'POST',
url: 'https://api.fyipe.com/zapier/incident/acknowledgeLastIncident',
body: data
});
return responsePromise
.then(response => JSON.parse(response.content));
};
module.exports = {
key: 'acknowledge_last_incident',
noun: 'Acknowledge',
display: {
label: 'Acknowledge Last Incident',
description: 'Acknowledges last incident.',
important: true
},
operation: {
inputFields: [
{
key: 'monitors',
type: 'string',
placeholder:'list of monitors',
dynamic: 'monitors.id.name',
altersDynamicFields: true,
list:true,
required: true
}
],
perform: acknowledgeLastIncident,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
acknowledged: true,
resolved: false,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
acknowledgedAt: new Date().toISOString(),
acknowledgedBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};

View File

@@ -0,0 +1,53 @@
const createIncident = (z, bundle) => {
if (bundle.cleanedRequest) return bundle.cleanedRequest;
const data = {
monitors: bundle.inputData.monitors
};
const responsePromise = z.request({
method: 'POST',
url: 'https://api.fyipe.com/zapier/incident/createIncident',
body: data
});
return responsePromise
.then(response => JSON.parse(response.content));
};
module.exports = {
key: 'incident',
noun: 'Incident',
display: {
label: 'Create Incident',
description: 'Creates an incident.',
important: true
},
operation: {
inputFields: [
{
key: 'monitors',
type: 'string',
placeholder:'list of monitors',
dynamic: 'monitors.id.name',
altersDynamicFields: true,
list:true,
required: true
}
],
perform: createIncident,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
acknowledged: false,
resolved: false,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};

View File

@@ -0,0 +1,54 @@
const resolveAllIncidents = (z, bundle) => {
if(bundle.cleanedRequest) return bundle.cleanedRequest;
const data = {
monitors: bundle.inputData.monitors
};
const responsePromise = z.request({
method: 'POST',
url: 'https://api.fyipe.com/zapier/incident/resolveAllIncidents',
body: data
});
return responsePromise
.then(response => JSON.parse(response.content));
};
module.exports = {
key: 'resolve_all_incidents',
noun: 'resolve',
display: {
label: 'Resolve All Incidents',
description: 'Resolves all incidents.',
important: true
},
operation: {
inputFields: [
{
key: 'monitors',
type: 'string',
placeholder:'list of monitors',
dynamic: 'monitors.id.name',
altersDynamicFields: true,
list:true,
required: true
}
],
perform: resolveAllIncidents,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
resolved: true,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
resolvedAt: new Date().toISOString(),
resolvedBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};

View File

@@ -0,0 +1,54 @@
const resolveIncident = (z, bundle) => {
if (bundle.cleanedRequest) return bundle.cleanedRequest;
const data = {
incidents: bundle.inputData.incidents
};
const responsePromise = z.request({
method: 'POST',
url: 'https://api.fyipe.com/zapier/incident/resolveIncident',
body: data
});
return responsePromise
.then(response => JSON.parse(response.content));
};
module.exports = {
key: 'resolve_incident',
noun: 'Resolve',
display: {
label: 'Resolve Incident',
description: 'Resolves incident.',
important: true
},
operation: {
inputFields: [
{
key: 'incidents',
type: 'string',
placeholder:'list of incidents',
dynamic: 'incidents.id',
altersDynamicFields: true,
list:true,
required: true
}
],
perform: resolveIncident,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
resolved: true,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
resolvedAt: new Date().toISOString(),
resolvedBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};

View File

@@ -0,0 +1,54 @@
const resolveLastIncident = (z, bundle) => {
if (bundle.cleanedRequest) return bundle.cleanedRequest;
const data = {
monitors: bundle.inputData.monitors
};
const responsePromise = z.request({
method: 'POST',
url: 'https://api.fyipe.com/zapier/incident/resolveLastIncident',
body: data
});
return responsePromise
.then(response => JSON.parse(response.content));
};
module.exports = {
key: 'resolve_last_incident',
noun: 'resolve',
display: {
label: 'Resolve Last Incident',
description: 'Resolves last incident.',
important: true
},
operation: {
inputFields: [
{
key: 'monitors',
type: 'string',
placeholder:'list of monitors',
dynamic: 'monitors.id.name',
altersDynamicFields: true,
list:true,
required: true
}
],
perform: resolveLastIncident,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
resolved: true,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
resolvedAt: new Date().toISOString(),
resolvedBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};

54
zapier/authentication.js Executable file
View File

@@ -0,0 +1,54 @@
const testAuth = (z, bundle) => {
// Normally you want to make a request to an endpoint that is either specifically designed to test auth, or one that
// every user will have access to, such as an account or profile endpoint like /me.
// In this example, we'll hit httpbin, which validates the Authorization Header against the arguments passed in the URL path
// This method can return any truthy value to indicate the credentials are valid.
// Raise an error to show
if (bundle.cleanedRequest) return bundle.cleanedRequest;
return z.request({
url: 'https://api.fyipe.com/zapier/test',
}).then((response) => {
console.log('response: ', response);
if (response.status === 400) {
throw new Error('The API Key or Project ID you supplied is invalid!');
}
else if (response.status === 401) {
throw new Error('The API Key or Project ID you supplied is invalid!');
}
else if(response.status === 500) {
throw new Error('Server Error!');
}
else if(response.status !== 200) {
throw new Error('An Error has occured please try after sometime!');
}
return response.json;
});
};
module.exports = {
type: 'custom',
// Define any auth fields your app requires here. The user will be prompted to enter this info when
// they connect their account.
fields: [
{
key: 'projectId',
label: 'Project ID',
helpText: 'Your Project ID and API Key are found on the project settings page on your Fyipe dashboard.',
required: true,
type: 'string'
},
{
key: 'apiKey',
label: 'API Key',
required: true,
type: 'string'
}
],
// The test method allows Zapier to verify that the credentials a user provides are valid. We'll execute this
// method whenver a user connects their account for the first time.
test: testAuth,
// assuming "username" is a key in the json returned from testAuth
connectionLabel: (z, bundle) => bundle.inputData.projectName
};

76
zapier/index.js Executable file
View File

@@ -0,0 +1,76 @@
const authentication = require('./authentication');
// import triggers
const resolvedTrigger = require('./triggers/resolved');
const incidentTrigger = require('./triggers/incident');
const monitorTrigger = require('./triggers/monitors');
const acknowledgeTrigger = require('./triggers/acknowledge');
const incidentsTrigger = require('./triggers/incidents');
// import actions
const createIncidentAction = require('./actions/createIncident');
const acknowledgeLastIncidentAction = require('./actions/acknowledgeLastIncident');
const resolveLastIncidentAction = require('./actions/resolveLastIncident');
const acknowledgeAllIncidentsAction = require('./actions/acknowledgeAllIncidents');
const resolveAllIncidentsAction = require('./actions/resolveAllIncidents');
const acknowledgeIncidentAction = require('./actions/acknowledgeIncident');
const resolveIncidentAction = require('./actions/resolveIncident');
// To include the API key on all outbound requests, simply define a function here.
// It runs runs before each request is sent out, allowing you to make tweaks to the request in a centralized spot.
const includeApiKey = (request, z, bundle) => {
if (bundle.authData.apiKey && bundle.authData.projectId) {
request.params = request.params || {};
request.params.apiKey = bundle.authData.apiKey;
request.params.projectId = bundle.authData.projectId;
//
// request.headers.Authorization = bundle.authData.apiKey;
// (If you want to include the key as a header instead)
//
}
return request;
};
const App = {
// This is just shorthand to reference the installed dependencies you have. Zapier will
// need to know these before we can upload
version: require('./package.json').version,
platformVersion: require('zapier-platform-core').version,
authentication: authentication,
beforeRequest: [
includeApiKey
],
afterResponse: [
],
resources: {
},
// If you want your trigger to show up, you better include it here!
triggers: {
[incidentTrigger.key]: incidentTrigger,
[resolvedTrigger.key]: resolvedTrigger,
[monitorTrigger.key]: monitorTrigger,
[acknowledgeTrigger.key]: acknowledgeTrigger,
[incidentsTrigger.key]: incidentsTrigger
},
// If you want your searches to show up, you better include it here!
searches: {
},
// If you want your creates to show up, you better include it here!
creates: {
[createIncidentAction.key]: createIncidentAction,
[acknowledgeLastIncidentAction.key]: acknowledgeLastIncidentAction,
[resolveLastIncidentAction.key]: resolveLastIncidentAction,
[acknowledgeAllIncidentsAction.key]: acknowledgeAllIncidentsAction,
[resolveAllIncidentsAction.key]: resolveAllIncidentsAction,
[acknowledgeIncidentAction.key]: acknowledgeIncidentAction,
[resolveIncidentAction.key]: resolveIncidentAction,
}
};
// Finally, export the app.
module.exports = App;

2336
zapier/package-lock.json generated Executable file

File diff suppressed because it is too large Load Diff

31
zapier/package.json Executable file
View File

@@ -0,0 +1,31 @@
{
"name": "fyipe_app",
"version": "1.0.8",
"description": "Fyipe is an automation tool that helps you monitor the performance and downtime of your APIs and Web apps.",
"homepage": "https://fyipe.com",
"author": "Olalekan Ayodele <longyarnz@gmail.com>",
"license": "MIT",
"main": "index.js",
"scripts": {
"lint": "eslint .",
"pretest": "eslint --fix --ignore-path .gitignore .",
"test": "mocha --recursive",
"audit": "npm-audit-ci-wrapper --threshold=high"
},
"engine": {
"node": "6.10.3",
"npm": ">=3.10.10"
},
"dependencies": {
"zapier-platform-core": "8.2.1"
},
"devDependencies": {
"babel-eslint": "^10.0.2",
"babel-preset-react": "^6.24.1",
"eslint": "^6.0.1",
"eslint-plugin-react": "^7.14.2",
"mocha": "^6.1.4",
"npm-audit-ci-wrapper": "^2.2.1",
"should": "11.2.1"
}
}

View File

@@ -0,0 +1,38 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Acknowledge All Incidents Action', () => {
it('passes authentication and acknowledges all incidents', (done) => {
zapier.tools.env.inject();
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY,
projectId: process.env.DEV_PROJECT_ID
},
cleanedRequest: {
projectName: 'New Project',
projectId: '1',
incidents: [{
id: '1',
acknowledged: true,
}],
}
};
appTester(App.creates.acknowledge_all_incidents.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Object);
response.should.have.property('projectName');
response.should.have.property('incidents');
response.incidents.should.be.an.instanceOf(Array);
response.incidents[0].acknowledged.should.be.equal(true);
done();
})
.catch(done);
});
});

View File

@@ -0,0 +1,38 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Acknowledge Incident By ID Action', () => {
it('passes authentication and acknowledges an incident by ID', (done) => {
zapier.tools.env.inject();
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY,
projectId: process.env.DEV_PROJECT_ID
},
cleanedRequest: {
projectName: 'New Project',
projectId: '1',
incidents: [{
id: '1',
acknowledged: true,
}],
}
};
appTester(App.creates.acknowledge_incident.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Object);
response.should.have.property('projectName');
response.should.have.property('incidents');
response.incidents.should.be.an.instanceOf(Array);
response.incidents[0].acknowledged.should.be.equal(true);
done();
})
.catch(done);
});
});

View File

@@ -0,0 +1,42 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Acknowledge Last Incident', () => {
it('passes authentication and acknowledges last incident', (done) => {
zapier.tools.env.inject();
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY,
projectId: process.env.DEV_PROJECT_ID
},
cleanedRequest: {
projectName: 'New Project',
projectId: '1',
incidents: [{
id: '1',
acknowledged: true,
},{
id: '1',
acknowledged: false,
}],
}
};
appTester(App.creates.acknowledge_last_incident.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Object);
response.should.have.property('projectName');
response.should.have.property('incidents');
response.incidents.should.be.an.instanceOf(Array);
response.incidents[0].acknowledged.should.be.equal(true);
response.incidents[1].acknowledged.should.be.equal(false);
done();
})
.catch(done);
});
});

View File

@@ -0,0 +1,41 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Create Incident Action', () => {
it('passes authentication and create new incident', (done) => {
zapier.tools.env.inject();
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY,
projectId: process.env.DEV_PROJECT_ID
},
cleanedRequest: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
acknowledged: false,
resolved: false,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'user',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://data.com'
}
};
appTester(App.creates.incident.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Object);
response.should.have.property('projectName');
done();
})
.catch(done);
});
});

View File

@@ -0,0 +1,38 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Resolve All Incidents Action', () => {
it('passes authentication and resolves all incidents', (done) => {
zapier.tools.env.inject();
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY,
projectId: process.env.DEV_PROJECT_ID
},
cleanedRequest: {
projectName: 'New Project',
projectId: '1',
incidents: [{
id: '1',
resolved: true,
}],
}
};
appTester(App.creates.resolve_all_incidents.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Object);
response.should.have.property('projectName');
response.should.have.property('incidents');
response.incidents.should.be.an.instanceOf(Array);
response.incidents[0].resolved.should.be.equal(true);
done();
})
.catch(done);
});
});

View File

@@ -0,0 +1,38 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Resolve Incident By ID Action', () => {
it('passes authentication and resolves an incident by ID', (done) => {
zapier.tools.env.inject();
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY,
projectId: process.env.DEV_PROJECT_ID
},
cleanedRequest: {
projectName: 'New Project',
projectId: '1',
incidents: [{
id: '1',
resolved: true,
}],
}
};
appTester(App.creates.acknowledge_incident.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Object);
response.should.have.property('projectName');
response.should.have.property('incidents');
response.incidents.should.be.an.instanceOf(Array);
response.incidents[0].resolved.should.be.equal(true);
done();
})
.catch(done);
});
});

View File

@@ -0,0 +1,42 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Resolve Last Incident', () => {
it('passes authentication and resolves last incident', (done) => {
zapier.tools.env.inject();
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY,
projectId: process.env.DEV_PROJECT_ID
},
cleanedRequest: {
projectName: 'New Project',
projectId: '1',
incidents: [{
id: '1',
resolved: true,
},{
id: '1',
resolved: false,
}],
}
};
appTester(App.creates.resolve_last_incident.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Object);
response.should.have.property('projectName');
response.should.have.property('incidents');
response.incidents.should.be.an.instanceOf(Array);
response.incidents[0].resolved.should.be.equal(true);
response.incidents[1].resolved.should.be.equal(false);
done();
})
.catch(done);
});
});

48
zapier/test/authentication.js Executable file
View File

@@ -0,0 +1,48 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../index');
const appTester = zapier.createAppTester(App);
describe('Authenticate API KEY and ProjectID', () => {
zapier.tools.env.inject();
it('passes authentication and returns json', (done) => {
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY,
projectId: process.env.DEV_PROJECT_ID
},
cleanedRequest: {
projectId: '1',
projectName: 'New Project',
monitor: [
{
createdAt: new Date().toTimeString(),
pollTime: new Date().toTimeString(),
_id: '1',
createdBy: 'You',
name: 'New Sample',
type: 'url',
data: {
url: 'https://fyipe.com'
},
projectId: '1',
}
],
}
};
appTester(App.authentication.test, bundle)
.then((json_response) => {
json_response.should.have.property('projectName');
done();
})
.catch(done);
});
});

View File

@@ -0,0 +1,53 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Acknowledge Trigger', ()=>{
zapier.tools.env.inject();
it('passes authentication and returns an acknowledged incident object', done => {
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY,
projectId: process.env.DEV_PROJECT_ID
},
cleanedRequest: [{
projectName: 'New Project',
projectId: '1',
incidentId: '1',
acknowledged: true,
monitor: [
{
createdAt: new Date().toTimeString(),
pollTime: new Date().toTimeString(),
_id: '1',
createdBy: 'You',
name: 'New Sample',
type: 'url',
data: {
url: 'https://fyipe.com'
},
projectId: '1',
}
],
}]
};
appTester(App.triggers.incident_acknowledge.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Array);
response[0].should.have.property('projectName');
response[0].should.have.property('monitor');
response[0].should.have.property('acknowledged');
response[0].acknowledged.should.equal(true);
done();
})
.catch(done);
});
});

View File

@@ -0,0 +1,49 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Incident Trigger', () => {
it('passes authentication and returns an incident object', (done) => {
zapier.tools.env.inject();
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY
},
cleanedRequest: [{
projectName: 'New Project',
id: '1',
monitor: [
{
createdAt: new Date().toTimeString(),
pollTime: new Date().toTimeString(),
_id: '1',
createdBy: 'You',
name: 'New Sample',
type: 'url',
data: {
url: 'https://fyipe.com'
},
projectId: '1',
}
]
}]
};
appTester(App.triggers.incident_created.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Array);
response[0].should.have.property('projectName');
response[0].should.have.property('monitor');
done();
})
.catch(done);
});
});

View File

@@ -0,0 +1,53 @@
require('should');
const zapier = require('zapier-platform-core');
const App = require('../../index');
const appTester = zapier.createAppTester(App);
describe('Resolve Trigger', () => {
it('passes authentication and returns a resolved incident object', done => {
zapier.tools.env.inject();
const bundle = {
authData: {
apiKey: process.env.DEV_API_KEY
},
cleanedRequest: [{
projectName: 'New Project',
projectId: '1',
incidentId: '1',
resolved: true,
monitor: [
{
createdAt: new Date().toTimeString(),
pollTime: new Date().toTimeString(),
_id: '1',
createdBy: 'You',
name: 'New Sample',
type: 'url',
data: {
url: 'https://fyipe.com'
},
projectId: '1',
}
],
}]
};
appTester(App.triggers.incident_resolve.operation.perform, bundle)
.then((response) => {
response.should.be.an.instanceOf(Array);
response[0].should.have.property('projectName');
response[0].should.have.property('monitor');
response[0].should.have.property('resolved');
response[0].resolved.should.equal(true);
done();
})
.catch(done);
});
});

92
zapier/triggers/acknowledge.js Executable file
View File

@@ -0,0 +1,92 @@
const acknowledgeIncident = (z, bundle) => {
return bundle.cleanedRequest;
};
const fallbackHook = (z) => {
// For the test poll, you should get some real data, to aid the setup process.
const options = {
url: 'https://api.fyipe.com/zapier/incident/acknowledged'
};
return z.request(options).then((response) => JSON.parse(response.content));
};
const subscribeHook = (z, bundle) => {
// bundle.targetUrl has the Hook URL this app should call when an incident is acknowledged.
const data = {
url: bundle.targetUrl,
type: 'incident_acknowledge',
input: bundle.inputData
};
const options = {
url: 'https://api.fyipe.com/zapier/subscribe',
method: 'POST',
body: data
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
const unSubscribeHook = (z, bundle) => {
// bundle.subscribeData contains the parsed response JSON from the subscribe
// request made initially.
const hookId = bundle.subscribeData.id;
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: `https://api.fyipe.com/zapier/unSubscribe/${hookId}`,
method: 'DELETE',
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
module.exports = {
key: 'incident_acknowledge',
noun: 'Acknowledge',
display: {
label: 'Acknowledged Incident',
description: 'Triggers when a new incident is acknowledged.',
important: true
},
operation: {
inputFields: [
{
key: 'monitors',
type: 'string',
placeholder:'list of monitors',
dynamic: 'monitors.id.name',
altersDynamicFields: true,
list:true,
required: false
}
],
type: 'hook',
perform: acknowledgeIncident,
performList: fallbackHook,
performSubscribe: subscribeHook,
performUnsubscribe: unSubscribeHook,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
acknowledged: true,
resolved: false,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
acknowledgedAt: new Date().toISOString(),
acknowledgedBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};

90
zapier/triggers/incident.js Executable file
View File

@@ -0,0 +1,90 @@
const triggerIncident = (z, bundle) => {
return bundle.cleanedRequest;
};
const fallbackHook = (z) => {
// For the test poll, you should get some real data, to aid the setup process.
const options = {
url: 'https://api.fyipe.com/zapier/incidents'
};
return z.request(options).then((response) => JSON.parse(response.content));
};
const subscribeHook = (z, bundle) => {
// bundle.targetUrl has the Hook URL this app should call when an incident is created.
const data = {
url: bundle.targetUrl,
type: 'incident_created',
input: bundle.inputData
};
const options = {
url: 'https://api.fyipe.com/zapier/subscribe',
method: 'POST',
body: data
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
const unSubscribeHook = (z, bundle) => {
// bundle.subscribeData contains the parsed response JSON from the subscribe
// request made initially.
const hookId = bundle.subscribeData.id;
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: `https://api.fyipe.com/zapier/unSubscribe/${hookId}`,
method: 'DELETE',
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
module.exports = {
key: 'incident_created',
noun: 'Incident',
display: {
label: 'New Incident',
description: 'Triggers when a new incident is created.',
important: true
},
operation: {
inputFields: [
{
key: 'monitors',
type: 'string',
placeholder:'list of monitors',
dynamic: 'monitors.id.name',
altersDynamicFields: true,
list:true,
required: false
}
],
type: 'hook',
perform: triggerIncident,
performList: fallbackHook,
performSubscribe: subscribeHook,
performUnsubscribe: unSubscribeHook,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
acknowledged: false,
resolved: false,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};

26
zapier/triggers/incidents.js Executable file
View File

@@ -0,0 +1,26 @@
// fetches a list of records from the endpoint
const fetchList = (z, bundle) => { // eslint-disable-line
const options = {
url: 'https://api.fyipe.com/zapier/incidents'
};
return z.request(options).then((response) => JSON.parse(response.content));
};
module.exports = {
key: 'incidents',
noun: 'incidents',
display: {
label: 'List of Incidents',
description: 'List of incidents for dropdown',
hidden: true,
},
operation: {
// since this is a "hidden" trigger, there aren't any inputFields needed
perform: fetchList,
// the folowing is a "hint" to the Zap Editor that this trigger returns data "in pages", and
// that the UI should display an option to "load next page" to the human.
canPaginate: false
}
};

26
zapier/triggers/monitors.js Executable file
View File

@@ -0,0 +1,26 @@
// fetches a list of records from the endpoint
const fetchList = (z, bundle) => { // eslint-disable-line
const options = {
url: 'https://api.fyipe.com/zapier/monitors'
};
return z.request(options).then((response) => JSON.parse(response.content));
};
module.exports = {
key: 'monitors',
noun: 'Monitors',
display: {
label: 'List of Monitors',
description: 'List of monitors for dropdown',
hidden: true,
},
operation: {
// since this is a "hidden" trigger, there aren't any inputFields needed
perform: fetchList,
// the folowing is a "hint" to the Zap Editor that this trigger returns data "in pages", and
// that the UI should display an option to "load next page" to the human.
canPaginate: false
}
};

96
zapier/triggers/resolved.js Executable file
View File

@@ -0,0 +1,96 @@
const resolveIncident = (z, bundle) => {
return bundle.cleanedRequest;
};
const fallbackHook = (z) => {
// For the test poll, you should get some real data, to aid the setup process.
const options = {
url: 'https://api.fyipe.com/zapier/incident/resolved'
};
return z.request(options).then((response) => JSON.parse(response.content));
};
const subscribeHook = (z, bundle) => {
z.console.log(bundle);
// bundle.targetUrl has the Hook URL this app should call when an incident is resolved.
const data = {
url: bundle.targetUrl,
type: 'incident_resolve',
input: bundle.inputData
};
const options = {
url: 'https://api.fyipe.com/zapier/subscribe',
method: 'POST',
body: data
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
const unSubscribeHook = (z, bundle) => {
// bundle.subscribeData contains the parsed response JSON from the subscribe
// request made initially.
const hookId = bundle.subscribeData.id;
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: `https://api.fyipe.com/zapier/unSubscribe/${hookId}`,
method: 'DELETE',
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
module.exports = {
key: 'incident_resolve',
noun: 'Resolve',
display: {
label: 'Resolved Incident',
description: 'Triggers when an incident is resolved.',
important: true
},
operation: {
inputFields: [
{
key: 'monitors',
type: 'string',
placeholder:'list of monitors',
dynamic: 'monitors.id.name',
altersDynamicFields: true,
list:true,
required: false
}
],
type: 'hook',
perform: resolveIncident,
performList: fallbackHook,
performSubscribe: subscribeHook,
performUnsubscribe: unSubscribeHook,
sample: {
projectName: 'New Project',
projectId: '1',
incidentId: '1',
acknowledged: true,
resolved: true,
internalNote: 'New Note',
investigationNote: 'New Investigation',
createdAt: new Date().toISOString(),
createdBy: 'fyipe',
acknowledgedAt: new Date().toISOString(),
acknowledgedBy: 'fyipe',
resolvedAt: new Date().toISOString(),
resolvedBy: 'fyipe',
monitorName: 'New Sample',
monitorType: 'url',
monitorData: 'https://fyipe.com'
}
}
};