-
-
Notifications
You must be signed in to change notification settings - Fork 694
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
94a7179
commit 7e67484
Showing
7 changed files
with
425 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`Should call New Relic Event API for $type toggle 1`] = ` | ||
{ | ||
"Api-Key": "fakeLicenseKey", | ||
"Content-Encoding": "gzip", | ||
"Content-Type": "application/json", | ||
} | ||
`; | ||
|
||
exports[`Should call New Relic Event API for $type toggle 2`] = `"{"eventType":"Unleash Service Event","unleashEventType":"feature-created","featureName":"some-toggle","createdBy":"[email protected]","createdByUserId":-1337,"createdAt":1719580982209,"name":"some-toggle","enabled":false,"strategies":[{"name":"default"}]}"`; | ||
|
||
exports[`Should call New Relic Event API for FEATURE_ARCHIVED toggle with project info 1`] = ` | ||
{ | ||
"Api-Key": "fakeLicenseKey", | ||
"Content-Encoding": "gzip", | ||
"Content-Type": "application/json", | ||
} | ||
`; | ||
|
||
exports[`Should call New Relic Event API for FEATURE_ARCHIVED toggle with project info 2`] = `"{"eventType":"Unleash Service Event","unleashEventType":"feature-archived","featureName":"some-toggle","createdBy":"[email protected]","createdByUserId":-1337,"createdAt":1719580982209,"name":"some-toggle"}"`; | ||
|
||
exports[`Should call New Relic Event API for FEATURE_ARCHIVED with project info 1`] = ` | ||
{ | ||
"Api-Key": "fakeLicenseKey", | ||
"Content-Encoding": "gzip", | ||
"Content-Type": "application/json", | ||
} | ||
`; | ||
|
||
exports[`Should call New Relic Event API for FEATURE_ARCHIVED with project info 2`] = `"{"eventType":"Unleash Service Event","unleashEventType":"feature-archived","featureName":"some-toggle","createdBy":"[email protected]","createdByUserId":-1337,"createdAt":1719580982209,"name":"some-toggle"}"`; | ||
|
||
exports[`Should call New Relic Event API for custom body template 1`] = ` | ||
{ | ||
"Api-Key": "fakeLicenseKey", | ||
"Content-Encoding": "gzip", | ||
"Content-Type": "application/json", | ||
} | ||
`; | ||
|
||
exports[`Should call New Relic Event API for custom body template 2`] = `"{"eventType":"Unleash Service Event","unleashEventType":"feature-environment-disabled","featureName":"some-toggle","environment":"development","createdBy":"[email protected]","createdByUserId":-1337,"createdAt":1719580982209,"name":"some-toggle","enabled":false,"strategies":[{"name":"default"}]}"`; | ||
|
||
exports[`Should call New Relic Event API for customHeaders in headers when calling service 1`] = ` | ||
{ | ||
"Api-Key": "fakeLicenseKey", | ||
"Content-Encoding": "gzip", | ||
"Content-Type": "application/json", | ||
"MY_CUSTOM_HEADER": "MY_CUSTOM_VALUE", | ||
} | ||
`; | ||
|
||
exports[`Should call New Relic Event API for customHeaders in headers when calling service 2`] = `"{"eventType":"Unleash Service Event","unleashEventType":"feature-environment-disabled","featureName":"some-toggle","environment":"development","createdBy":"[email protected]","createdByUserId":-1337,"createdAt":1719580982209,"name":"some-toggle","enabled":false,"strategies":[{"name":"default"}]}"`; | ||
|
||
exports[`Should call New Relic Event API for toggled environment 1`] = ` | ||
{ | ||
"Api-Key": "fakeLicenseKey", | ||
"Content-Encoding": "gzip", | ||
"Content-Type": "application/json", | ||
} | ||
`; | ||
|
||
exports[`Should call New Relic Event API for toggled environment 2`] = `"{"eventType":"Unleash Service Event","unleashEventType":"feature-environment-disabled","featureName":"some-toggle","environment":"development","createdBy":"[email protected]","createdByUserId":-1337,"createdAt":1719580982209,"name":"some-toggle","enabled":false,"strategies":[{"name":"default"}]}"`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { | ||
FEATURE_CREATED, | ||
FEATURE_UPDATED, | ||
FEATURE_ARCHIVED, | ||
FEATURE_REVIVED, | ||
FEATURE_STALE_ON, | ||
FEATURE_STALE_OFF, | ||
FEATURE_ENVIRONMENT_ENABLED, | ||
FEATURE_ENVIRONMENT_DISABLED, | ||
FEATURE_STRATEGY_REMOVE, | ||
FEATURE_STRATEGY_UPDATE, | ||
FEATURE_STRATEGY_ADD, | ||
FEATURE_METADATA_UPDATED, | ||
FEATURE_PROJECT_CHANGE, | ||
FEATURE_POTENTIALLY_STALE_ON, | ||
FEATURE_ENVIRONMENT_VARIANTS_UPDATED, | ||
} from '../types/events'; | ||
import type { IAddonDefinition } from '../types/model'; | ||
|
||
const newRelicDefinition: IAddonDefinition = { | ||
name: 'new-relic', | ||
displayName: 'New Relic', | ||
description: 'Allows Unleash to post updates to New Relic Event API.', | ||
documentationUrl: 'https://docs.getunleash.io/docs/addons/new-relic', | ||
howTo: 'The New Relic integration allows Unleash to post Updates to New Relic Event API when a feature flag is updated.', | ||
parameters: [ | ||
{ | ||
name: 'url', | ||
displayName: 'New Relic Event URL', | ||
description: | ||
"(Required) If data is hosted in EU then use the EU region endpoints (https://docs.newrelic.com/docs/using-new-relic/welcome-new-relic/getting-started/introduction-eu-region-data-center/#endpoints). Otherwise, it should be something like this: https://insights-collector.newrelic.com/v1/accounts/YOUR_ACCOUNT_ID/events", | ||
type: 'url', | ||
required: true, | ||
sensitive: false, | ||
}, | ||
{ | ||
name: 'licenseKey', | ||
displayName: 'New Relic License Key', | ||
placeholder: 'eu01xx0f12a6b3434a8d710110bd862', | ||
description: '(Required) License key to connect to New Relic', | ||
type: 'text', | ||
required: true, | ||
sensitive: true, | ||
}, | ||
{ | ||
name: 'customHeaders', | ||
displayName: 'Extra HTTP Headers', | ||
placeholder: `{ | ||
"SOME_CUSTOM_HTTP_HEADER": "SOME_VALUE", | ||
"SOME_OTHER_CUSTOM_HTTP_HEADER": "SOME_OTHER_VALUE" | ||
}`, | ||
description: | ||
'(Optional) Used to add extra HTTP Headers to the request the plugin fires off. This must be a valid json object of key-value pairs where both the key and the value are strings', | ||
required: false, | ||
sensitive: true, | ||
type: 'textfield', | ||
}, | ||
{ | ||
name: 'bodyTemplate', | ||
displayName: 'Body template', | ||
placeholder: `{ | ||
"event": "{{event.type}}", | ||
"eventType": "unleash", | ||
"createdBy": "{{event.createdBy}}", | ||
"featureToggle": "{{event.data.name}}", | ||
"timestamp": "{{event.data.createdAt}}" | ||
}`, | ||
description: | ||
'(Optional) The default format is a markdown string formatted by Unleash. You may override the format of the body using a mustache template.', | ||
required: false, | ||
sensitive: false, | ||
type: 'textfield', | ||
}, | ||
], | ||
events: [ | ||
FEATURE_CREATED, | ||
FEATURE_UPDATED, | ||
FEATURE_ARCHIVED, | ||
FEATURE_REVIVED, | ||
FEATURE_STALE_ON, | ||
FEATURE_STALE_OFF, | ||
FEATURE_ENVIRONMENT_ENABLED, | ||
FEATURE_ENVIRONMENT_DISABLED, | ||
FEATURE_STRATEGY_REMOVE, | ||
FEATURE_STRATEGY_UPDATE, | ||
FEATURE_STRATEGY_ADD, | ||
FEATURE_METADATA_UPDATED, | ||
FEATURE_PROJECT_CHANGE, | ||
FEATURE_ENVIRONMENT_VARIANTS_UPDATED, | ||
FEATURE_POTENTIALLY_STALE_ON, | ||
], | ||
tagTypes: [ | ||
{ | ||
name: 'new-relic', | ||
description: | ||
'All New Relic tags added to a specific feature are sent to New Relic Event API.', | ||
icon: 'D', | ||
}, | ||
], | ||
}; | ||
|
||
export default newRelicDefinition; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import {FEATURE_ARCHIVED, FEATURE_CREATED, FEATURE_ENVIRONMENT_DISABLED, type IEvent,} from '../types/events'; | ||
import type {Logger} from '../logger'; | ||
|
||
import NewRelicAddon, {INewRelicParameters} from './new-relic'; | ||
|
||
import noLogger from '../../test/fixtures/no-logger'; | ||
|
||
let fetchRetryCalls: any[] = []; | ||
|
||
jest.mock( | ||
'./addon', | ||
() => | ||
class Addon { | ||
logger: Logger; | ||
|
||
constructor(definition, {getLogger}) { | ||
this.logger = getLogger('addon/test'); | ||
fetchRetryCalls = []; | ||
} | ||
|
||
async fetchRetry(url, options, retries, backoff) { | ||
fetchRetryCalls.push({ | ||
url, | ||
options, | ||
retries, | ||
backoff, | ||
}); | ||
return Promise.resolve({status: 200}); | ||
} | ||
}, | ||
); | ||
|
||
const defaultParameters = { | ||
url: 'fakeUrl', | ||
licenseKey: 'fakeLicenseKey', | ||
} as INewRelicParameters; | ||
|
||
const defaultEvent = { | ||
id: 1, | ||
createdAt: new Date(), | ||
type: FEATURE_CREATED, | ||
createdBy: '[email protected]', | ||
createdByUserId: -1337, | ||
featureName: 'some-toggle', | ||
data: { | ||
name: 'some-toggle', | ||
enabled: false, | ||
strategies: [{name: 'default'}], | ||
}, | ||
} as IEvent; | ||
|
||
const makeAddHandleEvent = (event: IEvent, parameters: INewRelicParameters,) => { | ||
const addon = new NewRelicAddon({ | ||
getLogger: noLogger, | ||
unleashUrl: 'http://some-url.com', | ||
}); | ||
|
||
return () => addon.handleEvent(event, parameters); | ||
} | ||
|
||
|
||
test.each([ | ||
{ | ||
partialEvent: {type: FEATURE_CREATED}, | ||
test: '$type toggle', | ||
}, | ||
{ | ||
partialEvent: { | ||
type: FEATURE_ARCHIVED, | ||
data: { | ||
name: 'some-toggle', | ||
}, | ||
}, | ||
test: 'FEATURE_ARCHIVED toggle with project info' | ||
}, | ||
{ | ||
partialEvent: { | ||
type: FEATURE_ARCHIVED, | ||
project: 'some-project', | ||
data: { | ||
name: 'some-toggle', | ||
}, | ||
}, | ||
test: 'FEATURE_ARCHIVED with project info' | ||
}, | ||
{ | ||
partialEvent: { | ||
type: FEATURE_ENVIRONMENT_DISABLED, | ||
environment: 'development', | ||
}, | ||
test: 'toggled environment' | ||
}, | ||
{ | ||
partialEvent: { | ||
type: FEATURE_ENVIRONMENT_DISABLED, | ||
environment: 'development', | ||
}, | ||
partialParameters: { | ||
customHeaders: `{ "MY_CUSTOM_HEADER": "MY_CUSTOM_VALUE" }`, | ||
}, | ||
test: 'customHeaders in headers when calling service' | ||
}, | ||
{ | ||
partialEvent: { | ||
type: FEATURE_ENVIRONMENT_DISABLED, | ||
environment: 'development', | ||
}, | ||
partialParameters: { | ||
bodyTemplate: | ||
'{\n "eventType": "{{event.type}}",\n "createdBy": "{{event.createdBy}}"\n}', | ||
}, | ||
test: 'custom body template' | ||
} | ||
] as Array<{ | ||
partialEvent: Partial<IEvent>, | ||
partialParameters?: Partial<INewRelicParameters>, | ||
test: String | ||
}>)('Should call New Relic Event API for $test', async ({partialEvent, partialParameters}) => { | ||
const event = { | ||
...defaultEvent, | ||
...partialEvent, | ||
} | ||
|
||
const parameters = { | ||
...defaultParameters, | ||
...partialParameters, | ||
} | ||
|
||
const handleEvent = makeAddHandleEvent(event, parameters); | ||
|
||
await handleEvent(); | ||
expect(fetchRetryCalls.length).toBe(1); | ||
|
||
const {url, options} = fetchRetryCalls[0]; | ||
const jsonBody = JSON.parse(options.body); | ||
expect(url).toBe(parameters.url); | ||
expect(options.method).toBe('POST'); | ||
expect(options.headers['Api-Key']).toBe(parameters.licenseKey); | ||
expect(options.headers['Content-Type']).toBe('application/json'); | ||
expect(options.headers['Content-Encoding']).toBe('gzip'); | ||
expect(options.headers).toMatchSnapshot(); | ||
|
||
expect(jsonBody.eventType).toBe('Unleash Service Event'); | ||
expect(jsonBody.unleashEventType).toBe(event.type); | ||
expect(jsonBody.featureName).toBe(event.data.name); | ||
expect(jsonBody.environment).toBe(event.environment); | ||
expect(jsonBody.createdBy).toBe(event.createdBy); | ||
expect(jsonBody.createdByUserId).toBe(event.createdByUserId); | ||
expect(jsonBody.createdAt).toBe(event.createdAt.getTime()); | ||
|
||
expect(options.body).toMatchSnapshot(); | ||
}); |
Oops, something went wrong.