Skip to content

Commit

Permalink
prepare 4.1.0 release (#67)
Browse files Browse the repository at this point in the history
* initial move of code from js-client-sdk-private

* changelog note

* rm obsolete comment

* add npm audit helper

* update babel, jest, rollup

* fix rollup config

* fix ES build, dependency cleanup

* add Releaser metadata

* Update babel config to work in `test` without `useBuiltIns`

* copyedits

* fix misnamed directory

* use spread operator instead of Object.assign

* add issue templates

* add babel-eslint

* add event capacity config property

* re-add deprecation warning on samplingInterval

* better config validation

* remove rollup-plugins-node-resolve

* use newer Rollup node-resolve plugin

* rm rollup-plugin-includepaths (unused)

* npm audit fix (handlebars dependency from jest)

* comment

* copyedit

* use new test helpers + misc test cleanup

* clean up stream testing logic

* fix hash parameter

* linter

* clearer way to model the config option defaults/types

* test improvements

* change internal param name

* comment

* fix default logger logic

* simpler way to enforce minimum values

* implement diagnostic events in common JS package (#11)

* add support for function type in config options

* add support for function type in config options (#13)

* add wrapper metadata options and fix custom header logic

* lint

* lint

* remove image-loading logic from common code, replace it with an abstraction

* add validation for options.streaming

* typo

* rm unused params

* typo in comment

* misc fixes to merged code from external PR

* add event payload ID header

* npm audit fix

* change exact dependencies to best-compatible

* standardize linting

* disallow "window" and "document"

* improve diag event tests + debug logging

* misc cleanup

* fix updating secure mode hash with identify()

* don't omit streamInits.failed when it's false

* clean up init state logic, prevent unhandled rejections

* lint

* less strict matching of json content-type header

* remove unsafe usage of hasOwnProperty

* console logger must tolerate console object not always existing

* fix double initialization of diagnostics manager

* fix TypeScript declaration for track() and add more TS compilation tests (#27)

* remove startsWith usage (#28)

* prevent poll caused by a stream ping from overwriting later poll for another user (#29)

* upgrade jest dependency and transitive yargs-parser dependency (#30)

* Add null to LDEvaluationDetail.reason type (#31)

* Revert "Add null to LDEvaluationDetail.reason type (#31)"

This reverts commit bcb1573.

* Revert "Add null to LDEvaluationDetail.reason type (#31)"

This reverts commit bcb1573.

* nullable evaluation reason (#32)

* adding alias event functionality (#33)

* set stream read timeout

* Add prepare script (#34)

* add a missing typescript verification (#36)

* Removed the guides link

* Correct doc link (#36)

* Fix typo in LDClient.on jsdoc (#37)

* add inlineUsersInEvents option in TypeScript (#37)

* Filter private attributes on debug event users. Send variation for debug events.

* update uuid package version (#39)

* use Releaser v2 config + newer CI image

* First half, add the type, create the new options, add the new util method, and add tests

* Second half, call the tranform util method before calling any HTTP requests

* Update the transform to work on a copy of headers instead of mutating it

* add comments about removing custom event warning logic in the future

* revert updating of UUID dependency (#43)

* Revert "update uuid package version (#39)"

This reverts commit 3b2ff6c.

* update package-lock.json

* better error handling for local storage operations (#44)

* better error handling for local storage operations

* lint

* fix obsolete comments

* add basic logger similar to server-side Node SDK (#45)

* fix exports and add validation of custom logger (#46)

* remove typedoc.js file that interferes with Releaser's docs build

* update typescript version

* add maintenance branch

* remove deprecated things (#48)

* remove deprecated options and function

* rm references to obsolete function

* restore deprecation logic, just leave the data empty

* remove samplingInterval from TS test code

* fix TS test code again

* fix EvaluationDetail.reason to be nullable so we can get rid of NonNullableLDEvaluationReason type (#49)

* remove deprecated options and function

* rm references to obsolete function

* restore deprecation logic, just leave the data empty

* remove samplingInterval from TS test code

* fix TS test code again

* fix EvaluationDetail.reason to be nullable so we can get rid of NonNullableLDEvaluationReason type

* fix TS test code

* re-bump uuid package (#50)

* Revert "Revert "update uuid package version (#39)""

This reverts commit 89359b1bf4ddbe6b2fedb95f1dc11240483c60f7.

* remove lockfile (sc-107301)

* use regular User-Agent header name unless overridden by js-client-sdk (#52)

* switch to publishing js-sdk-common as a regular Node module (#51)

* fix CI

* remove `version` constant which can't be exported from js-sdk-common (#53)

* catch errors in JSON parsing of stream data (#54)

* catch errors in JSON parsing of stream data

* lint

* backport sc-142333 fix

* prepare 3.5.1 release (#63)

* initial move of code from js-client-sdk-private

* changelog note

* rm obsolete comment

* add npm audit helper

* update babel, jest, rollup

* fix rollup config

* fix ES build, dependency cleanup

* add Releaser metadata

* Update babel config to work in `test` without `useBuiltIns`

* copyedits

* fix misnamed directory

* use spread operator instead of Object.assign

* add issue templates

* add babel-eslint

* add event capacity config property

* re-add deprecation warning on samplingInterval

* better config validation

* remove rollup-plugins-node-resolve

* use newer Rollup node-resolve plugin

* rm rollup-plugin-includepaths (unused)

* npm audit fix (handlebars dependency from jest)

* comment

* copyedit

* use new test helpers + misc test cleanup

* clean up stream testing logic

* fix hash parameter

* linter

* clearer way to model the config option defaults/types

* test improvements

* change internal param name

* comment

* fix default logger logic

* simpler way to enforce minimum values

* implement diagnostic events in common JS package (#11)

* add support for function type in config options

* add support for function type in config options (#13)

* add wrapper metadata options and fix custom header logic

* lint

* lint

* remove image-loading logic from common code, replace it with an abstraction

* add validation for options.streaming

* typo

* rm unused params

* typo in comment

* misc fixes to merged code from external PR

* add event payload ID header

* npm audit fix

* change exact dependencies to best-compatible

* standardize linting

* disallow "window" and "document"

* improve diag event tests + debug logging

* misc cleanup

* fix updating secure mode hash with identify()

* don't omit streamInits.failed when it's false

* clean up init state logic, prevent unhandled rejections

* lint

* less strict matching of json content-type header

* remove unsafe usage of hasOwnProperty

* console logger must tolerate console object not always existing

* fix double initialization of diagnostics manager

* fix TypeScript declaration for track() and add more TS compilation tests (#27)

* remove startsWith usage (#28)

* prevent poll caused by a stream ping from overwriting later poll for another user (#29)

* upgrade jest dependency and transitive yargs-parser dependency (#30)

* Add null to LDEvaluationDetail.reason type (#31)

* Revert "Add null to LDEvaluationDetail.reason type (#31)"

This reverts commit bcb1573.

* Revert "Add null to LDEvaluationDetail.reason type (#31)"

This reverts commit bcb1573.

* nullable evaluation reason (#32)

* adding alias event functionality (#33)

* set stream read timeout

* Add prepare script (#34)

* add a missing typescript verification (#36)

* Removed the guides link

* Correct doc link (#36)

* Fix typo in LDClient.on jsdoc (#37)

* add inlineUsersInEvents option in TypeScript (#37)

* Filter private attributes on debug event users. Send variation for debug events.

* update uuid package version (#39)

* use Releaser v2 config + newer CI image

* First half, add the type, create the new options, add the new util method, and add tests

* Second half, call the tranform util method before calling any HTTP requests

* Update the transform to work on a copy of headers instead of mutating it

* add comments about removing custom event warning logic in the future

* revert updating of UUID dependency (#43)

* Revert "update uuid package version (#39)"

This reverts commit 3b2ff6c.

* update package-lock.json

* better error handling for local storage operations (#44)

* better error handling for local storage operations

* lint

* fix obsolete comments

* add basic logger similar to server-side Node SDK (#45)

* fix exports and add validation of custom logger (#46)

* remove typedoc.js file that interferes with Releaser's docs build

* update typescript version

* add maintenance branch

* backport sc-142333 fix

Co-authored-by: Eli Bishop <[email protected]>
Co-authored-by: Zach Davis <[email protected]>
Co-authored-by: LaunchDarklyCI <[email protected]>
Co-authored-by: Ben Woskow <[email protected]>
Co-authored-by: Ben Woskow <[email protected]>
Co-authored-by: Michael Siadak <[email protected]>
Co-authored-by: Jeff Wen <[email protected]>
Co-authored-by: Andrey Krasnov <[email protected]>
Co-authored-by: Gavin Whelan <[email protected]>
Co-authored-by: LaunchDarklyReleaseBot <[email protected]>
Co-authored-by: Louis Chan <[email protected]>
Co-authored-by: Louis Chan <[email protected]>

* Releasing version 3.5.1

* rm obsolete file to fix merge

* Releasing version 3.5.1

* make URL path concatenation work right whether base URL has a trailing slash or not (#61)

* make URL path concatenation work right whether base URL has a trailing slash or not

* lint

* Implement support for application tags. (#55)

* Fix typing of LDOptionsBase. (#63)

* Implement application tags for 3.x. (#62)

* lint

Co-authored-by: Eli Bishop <[email protected]>
Co-authored-by: Zach Davis <[email protected]>
Co-authored-by: LaunchDarklyCI <[email protected]>
Co-authored-by: Ben Woskow <[email protected]>
Co-authored-by: Ben Woskow <[email protected]>
Co-authored-by: Michael Siadak <[email protected]>
Co-authored-by: Jeff Wen <[email protected]>
Co-authored-by: Andrey Krasnov <[email protected]>
Co-authored-by: Gavin Whelan <[email protected]>
Co-authored-by: LaunchDarklyReleaseBot <[email protected]>
Co-authored-by: Louis Chan <[email protected]>
Co-authored-by: Louis Chan <[email protected]>
Co-authored-by: Ryan Lamb <[email protected]>
  • Loading branch information
14 people authored Apr 21, 2022
1 parent bee90f5 commit 63976cd
Show file tree
Hide file tree
Showing 16 changed files with 332 additions and 113 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ All notable changes to the `launchdarkly-js-sdk-common` package will be document
- Removed the type `NonNullableLDEvaluationReason`, which was a side effect of the `LDEvaluationDetail.reason` being incorrectly defined before.
- Removed all types, properties, and functions that were deprecated as of the last 3.x release.

## [3.5.1] - 2022-02-17
### Fixed:
- If the SDK receives invalid JSON data from a streaming connection (possibly as a result of the connection being cut off), it now uses its regular error-handling logic: the error is emitted as an `error` event or, if there are no `error` event listeners, it is logged. Previously, it would be thrown as an unhandled exception.

## [3.5.0] - 2022-01-14
### Added:
- New configurable logger factory `commonBasicLogger` and `BasicLoggerOptions`. The `commonBasicLogger` method is not intended to be exported directly in the SDKs, but wrapped to provide platform-specific behavior.
Expand Down
2 changes: 1 addition & 1 deletion src/EventProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function EventProcessor(
) {
const processor = {};
const eventSender = sender || EventSender(platform, environmentId, options);
const mainEventsUrl = options.eventsUrl + '/events/bulk/' + environmentId;
const mainEventsUrl = utils.appendUrlPath(options.eventsUrl, '/events/bulk/' + environmentId);
const summarizer = EventSummarizer();
const userFilter = UserFilter(options);
const inlineUsers = options.inlineUsersInEvents;
Expand Down
5 changes: 3 additions & 2 deletions src/EventSender.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
const errors = require('./errors');
const utils = require('./utils');
const { v1: uuidv1 } = require('uuid');
const { getLDHeaders, transformHeaders } = require('./headers');

const MAX_URL_LENGTH = 2000;

function EventSender(platform, environmentId, options) {
const imageUrlPath = '/a/' + environmentId + '.gif';
const baseHeaders = utils.extend({ 'Content-Type': 'application/json' }, utils.getLDHeaders(platform, options));
const baseHeaders = utils.extend({ 'Content-Type': 'application/json' }, getLDHeaders(platform, options));
const httpFallbackPing = platform.httpFallbackPing; // this will be set for us if we're in the browser SDK
const sender = {};

Expand Down Expand Up @@ -34,7 +35,7 @@ function EventSender(platform, environmentId, options) {
'X-LaunchDarkly-Payload-ID': payloadId,
});
return platform
.httpRequest('POST', url, utils.transformHeaders(headers, options), jsonBody)
.httpRequest('POST', url, transformHeaders(headers, options), jsonBody)
.promise.then(result => {
if (!result) {
// This was a response from a fire-and-forget request, so we won't have a status.
Expand Down
7 changes: 4 additions & 3 deletions src/Requestor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const utils = require('./utils');
const errors = require('./errors');
const messages = require('./messages');
const promiseCoalescer = require('./promiseCoalescer');
const { transformHeaders, getLDHeaders } = require('./headers');

const jsonContentType = 'application/json';

Expand Down Expand Up @@ -31,7 +32,7 @@ function Requestor(platform, options, environment) {
}

const method = body ? 'REPORT' : 'GET';
const headers = utils.getLDHeaders(platform, options);
const headers = getLDHeaders(platform, options);
if (body) {
headers['Content-Type'] = jsonContentType;
}
Expand All @@ -45,7 +46,7 @@ function Requestor(platform, options, environment) {
activeRequests[endpoint] = coalescer;
}

const req = platform.httpRequest(method, endpoint, utils.transformHeaders(headers, options), body);
const req = platform.httpRequest(method, endpoint, transformHeaders(headers, options), body);
const p = req.promise.then(
result => {
if (result.status === 200) {
Expand Down Expand Up @@ -75,7 +76,7 @@ function Requestor(platform, options, environment) {
// Performs a GET request to an arbitrary path under baseUrl. Returns a Promise which will resolve
// with the parsed JSON response, or will be rejected if the request failed.
requestor.fetchJSON = function(path) {
return fetchJSON(baseUrl + path, null);
return fetchJSON(utils.appendUrlPath(baseUrl, path), null);
};

// Requests the current state of all flags for the given user from LaunchDarkly. Returns a Promise
Expand Down
7 changes: 4 additions & 3 deletions src/Stream.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const messages = require('./messages');
const { base64URLEncode, getLDHeaders, transformHeaders, objectHasOwnProperty } = require('./utils');
const { appendUrlPath, base64URLEncode, objectHasOwnProperty } = require('./utils');
const { getLDHeaders, transformHeaders } = require('./headers');

// The underlying event source implementation is abstracted via the platform object, which should
// have these three properties:
Expand All @@ -20,7 +21,7 @@ function Stream(platform, config, environment, diagnosticsAccumulator) {
const baseUrl = config.streamUrl;
const logger = config.logger;
const stream = {};
const evalUrlPrefix = baseUrl + '/eval/' + environment;
const evalUrlPrefix = appendUrlPath(baseUrl, '/eval/' + environment);
const useReport = config.useReport;
const withReasons = config.evaluationReasons;
const streamReconnectDelay = config.streamReconnectDelay;
Expand Down Expand Up @@ -98,7 +99,7 @@ function Stream(platform, config, environment, diagnosticsAccumulator) {
options.body = JSON.stringify(user);
} else {
// if we can't do REPORT, fall back to the old ping-based stream
url = baseUrl + '/ping/' + environment;
url = appendUrlPath(baseUrl, '/ping/' + environment);
query = '';
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/Stream-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DiagnosticsAccumulator } from '../diagnosticEvents';
import * as messages from '../messages';
import Stream from '../Stream';
import { getLDHeaders } from '../utils';
import { getLDHeaders } from '../headers';

import { sleepAsync } from 'launchdarkly-js-test-helpers';
import EventSource from './EventSource-mock';
Expand Down
39 changes: 39 additions & 0 deletions src/__tests__/configuration-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,43 @@ describe('configuration', () => {
expect(config.extraFunctionOption).toBe(fn);
await listener.expectError(messages.wrongOptionType('extraNumericOptionWithoutDefault', 'number', 'string'));
});

it('handles a valid application id', async () => {
const listener = errorListener();
const configIn = { application: { id: 'test-application' } };
expect(configuration.validate(configIn, listener.emitter, null, listener.logger).application.id).toEqual(
'test-application'
);
});

it('logs a warning with an invalid application id', async () => {
const listener = errorListener();
const configIn = { application: { id: 'test #$#$#' } };
expect(configuration.validate(configIn, listener.emitter, null, listener.logger).application.id).toBeUndefined();
await listener.expectWarningOnly(messages.invalidTagValue('application.id'));
});

it('handles a valid application version', async () => {
const listener = errorListener();
const configIn = { application: { version: 'test-version' } };
expect(configuration.validate(configIn, listener.emitter, null, listener.logger).application.version).toEqual(
'test-version'
);
});

it('logs a warning with an invalid application version', async () => {
const listener = errorListener();
const configIn = { application: { version: 'test #$#$#' } };
expect(
configuration.validate(configIn, listener.emitter, null, listener.logger).application.version
).toBeUndefined();
await listener.expectWarningOnly(messages.invalidTagValue('application.version'));
});

it('includes application id and version in tags when present', async () => {
expect(configuration.getTags({ application: { id: 'test-id', version: 'test-version' } })).toEqual({
'application-id': ['test-id'],
'application-version': ['test-version'],
});
});
});
117 changes: 117 additions & 0 deletions src/__tests__/headers-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { getLDHeaders, transformHeaders } from '../headers';
import { getLDUserAgentString } from '../utils';
import * as stubPlatform from './stubPlatform';

describe('getLDHeaders', () => {
it('sends no headers unless sendLDHeaders is true', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, {});
expect(headers).toEqual({});
});

it('adds user-agent header', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, { sendLDHeaders: true });
expect(headers).toMatchObject({ 'User-Agent': getLDUserAgentString(platform) });
});

it('adds user-agent header with custom name', () => {
const platform = stubPlatform.defaults();
platform.userAgentHeaderName = 'X-Fake-User-Agent';
const headers = getLDHeaders(platform, { sendLDHeaders: true });
expect(headers).toMatchObject({ 'X-Fake-User-Agent': getLDUserAgentString(platform) });
});

it('adds wrapper info if specified, without version', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, { sendLDHeaders: true, wrapperName: 'FakeSDK' });
expect(headers).toMatchObject({
'User-Agent': getLDUserAgentString(platform),
'X-LaunchDarkly-Wrapper': 'FakeSDK',
});
});

it('adds wrapper info if specified, with version', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, { sendLDHeaders: true, wrapperName: 'FakeSDK', wrapperVersion: '9.9' });
expect(headers).toMatchObject({
'User-Agent': getLDUserAgentString(platform),
'X-LaunchDarkly-Wrapper': 'FakeSDK/9.9',
});
});

it('sets the X-LaunchDarkly-Tags header with valid id and version.', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, {
sendLDHeaders: true,
application: {
id: 'test-application',
version: 'test-version',
},
});
expect(headers).toMatchObject({
'User-Agent': getLDUserAgentString(platform),
'x-launchdarkly-tags': 'application-id/test-application application-version/test-version',
});
});

it('sets the X-LaunchDarkly-Tags header with just application id', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, {
sendLDHeaders: true,
application: {
id: 'test-application',
},
});
expect(headers).toMatchObject({
'User-Agent': getLDUserAgentString(platform),
'x-launchdarkly-tags': 'application-id/test-application',
});
});

it('sets the X-LaunchDarkly-Tags header with just application version.', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, {
sendLDHeaders: true,
application: {
version: 'test-version',
},
});
expect(headers).toMatchObject({
'User-Agent': getLDUserAgentString(platform),
'x-launchdarkly-tags': 'application-version/test-version',
});
});
});

describe('transformHeaders', () => {
it('does not modify the headers if the option is not available', () => {
const inputHeaders = { a: '1', b: '2' };
const headers = transformHeaders(inputHeaders, {});
expect(headers).toEqual(inputHeaders);
});

it('modifies the headers if the option has a transform', () => {
const inputHeaders = { c: '3', d: '4' };
const outputHeaders = { c: '9', d: '4', e: '5' };
const headerTransform = input => {
const output = { ...input };
output['c'] = '9';
output['e'] = '5';
return output;
};
const headers = transformHeaders(inputHeaders, { requestHeaderTransform: headerTransform });
expect(headers).toEqual(outputHeaders);
});

it('cannot mutate the input header object', () => {
const inputHeaders = { f: '6' };
const expectedInputHeaders = { f: '6' };
const headerMutate = input => {
input['f'] = '7'; // eslint-disable-line no-param-reassign
return input;
};
transformHeaders(inputHeaders, { requestHeaderTransform: headerMutate });
expect(inputHeaders).toEqual(expectedInputHeaders);
});
});
81 changes: 8 additions & 73 deletions src/__tests__/utils-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
appendUrlPath,
base64URLEncode,
getLDHeaders,
transformHeaders,
getLDUserAgentString,
wrapPromiseCallback,
chunkUserEventsForUrl,
Expand All @@ -10,6 +9,13 @@ import {
import * as stubPlatform from './stubPlatform';

describe('utils', () => {
it('appendUrlPath', () => {
expect(appendUrlPath('http://base', '/path')).toEqual('http://base/path');
expect(appendUrlPath('http://base', 'path')).toEqual('http://base/path');
expect(appendUrlPath('http://base/', '/path')).toEqual('http://base/path');
expect(appendUrlPath('http://base/', '/path')).toEqual('http://base/path');
});

describe('wrapPromiseCallback', () => {
it('should resolve to the value', done => {
const promise = wrapPromiseCallback(Promise.resolve('woohoo'));
Expand Down Expand Up @@ -48,77 +54,6 @@ describe('utils', () => {
});
});

describe('getLDHeaders', () => {
it('sends no headers unless sendLDHeaders is true', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, {});
expect(headers).toEqual({});
});

it('adds user-agent header', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, { sendLDHeaders: true });
expect(headers).toMatchObject({ 'User-Agent': getLDUserAgentString(platform) });
});

it('adds user-agent header with custom name', () => {
const platform = stubPlatform.defaults();
platform.userAgentHeaderName = 'X-Fake-User-Agent';
const headers = getLDHeaders(platform, { sendLDHeaders: true });
expect(headers).toMatchObject({ 'X-Fake-User-Agent': getLDUserAgentString(platform) });
});

it('adds wrapper info if specified, without version', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, { sendLDHeaders: true, wrapperName: 'FakeSDK' });
expect(headers).toMatchObject({
'User-Agent': getLDUserAgentString(platform),
'X-LaunchDarkly-Wrapper': 'FakeSDK',
});
});

it('adds wrapper info if specified, with version', () => {
const platform = stubPlatform.defaults();
const headers = getLDHeaders(platform, { sendLDHeaders: true, wrapperName: 'FakeSDK', wrapperVersion: '9.9' });
expect(headers).toMatchObject({
'User-Agent': getLDUserAgentString(platform),
'X-LaunchDarkly-Wrapper': 'FakeSDK/9.9',
});
});
});

describe('transformHeaders', () => {
it('does not modify the headers if the option is not available', () => {
const inputHeaders = { a: '1', b: '2' };
const headers = transformHeaders(inputHeaders, {});
expect(headers).toEqual(inputHeaders);
});

it('modifies the headers if the option has a transform', () => {
const inputHeaders = { c: '3', d: '4' };
const outputHeaders = { c: '9', d: '4', e: '5' };
const headerTransform = input => {
const output = { ...input };
output['c'] = '9';
output['e'] = '5';
return output;
};
const headers = transformHeaders(inputHeaders, { requestHeaderTransform: headerTransform });
expect(headers).toEqual(outputHeaders);
});

it('cannot mutate the input header object', () => {
const inputHeaders = { f: '6' };
const expectedInputHeaders = { f: '6' };
const headerMutate = input => {
input['f'] = '7'; // eslint-disable-line no-param-reassign
return input;
};
transformHeaders(inputHeaders, { requestHeaderTransform: headerMutate });
expect(inputHeaders).toEqual(expectedInputHeaders);
});
});

describe('getLDUserAgentString', () => {
it('uses platform user-agent and unknown version by default', () => {
const platform = stubPlatform.defaults();
Expand Down
Loading

0 comments on commit 63976cd

Please sign in to comment.