Skip to content

Commit 63976cd

Browse files
LaunchDarklyReleaseBoteli-darklyzmdavisLaunchDarklyCIbwoskow-ld
authored
prepare 4.1.0 release (#67)
* 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 <eli@launchdarkly.com> Co-authored-by: Zach Davis <zach@launchdarkly.com> Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com> Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com> Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com> Co-authored-by: Michael Siadak <mike.siadak@gmail.com> Co-authored-by: Jeff Wen <sinchangwen@gmail.com> Co-authored-by: Andrey Krasnov <34657799+Doesntmeananything@users.noreply.github.com> Co-authored-by: Gavin Whelan <gwhelan@launchdarkly.com> Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com> Co-authored-by: Louis Chan <lchan@launchdarkly.com> Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com> * 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 <eli@launchdarkly.com> Co-authored-by: Zach Davis <zach@launchdarkly.com> Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com> Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com> Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com> Co-authored-by: Michael Siadak <mike.siadak@gmail.com> Co-authored-by: Jeff Wen <sinchangwen@gmail.com> Co-authored-by: Andrey Krasnov <34657799+Doesntmeananything@users.noreply.github.com> Co-authored-by: Gavin Whelan <gwhelan@launchdarkly.com> Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com> Co-authored-by: Louis Chan <lchan@launchdarkly.com> Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com> Co-authored-by: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com>
1 parent bee90f5 commit 63976cd

16 files changed

+332
-113
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ All notable changes to the `launchdarkly-js-sdk-common` package will be document
2323
- Removed the type `NonNullableLDEvaluationReason`, which was a side effect of the `LDEvaluationDetail.reason` being incorrectly defined before.
2424
- Removed all types, properties, and functions that were deprecated as of the last 3.x release.
2525

26+
## [3.5.1] - 2022-02-17
27+
### Fixed:
28+
- 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.
29+
2630
## [3.5.0] - 2022-01-14
2731
### Added:
2832
- 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.

src/EventProcessor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function EventProcessor(
1515
) {
1616
const processor = {};
1717
const eventSender = sender || EventSender(platform, environmentId, options);
18-
const mainEventsUrl = options.eventsUrl + '/events/bulk/' + environmentId;
18+
const mainEventsUrl = utils.appendUrlPath(options.eventsUrl, '/events/bulk/' + environmentId);
1919
const summarizer = EventSummarizer();
2020
const userFilter = UserFilter(options);
2121
const inlineUsers = options.inlineUsersInEvents;

src/EventSender.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
const errors = require('./errors');
22
const utils = require('./utils');
33
const { v1: uuidv1 } = require('uuid');
4+
const { getLDHeaders, transformHeaders } = require('./headers');
45

56
const MAX_URL_LENGTH = 2000;
67

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

@@ -34,7 +35,7 @@ function EventSender(platform, environmentId, options) {
3435
'X-LaunchDarkly-Payload-ID': payloadId,
3536
});
3637
return platform
37-
.httpRequest('POST', url, utils.transformHeaders(headers, options), jsonBody)
38+
.httpRequest('POST', url, transformHeaders(headers, options), jsonBody)
3839
.promise.then(result => {
3940
if (!result) {
4041
// This was a response from a fire-and-forget request, so we won't have a status.

src/Requestor.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const utils = require('./utils');
22
const errors = require('./errors');
33
const messages = require('./messages');
44
const promiseCoalescer = require('./promiseCoalescer');
5+
const { transformHeaders, getLDHeaders } = require('./headers');
56

67
const jsonContentType = 'application/json';
78

@@ -31,7 +32,7 @@ function Requestor(platform, options, environment) {
3132
}
3233

3334
const method = body ? 'REPORT' : 'GET';
34-
const headers = utils.getLDHeaders(platform, options);
35+
const headers = getLDHeaders(platform, options);
3536
if (body) {
3637
headers['Content-Type'] = jsonContentType;
3738
}
@@ -45,7 +46,7 @@ function Requestor(platform, options, environment) {
4546
activeRequests[endpoint] = coalescer;
4647
}
4748

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

8182
// Requests the current state of all flags for the given user from LaunchDarkly. Returns a Promise

src/Stream.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const messages = require('./messages');
2-
const { base64URLEncode, getLDHeaders, transformHeaders, objectHasOwnProperty } = require('./utils');
2+
const { appendUrlPath, base64URLEncode, objectHasOwnProperty } = require('./utils');
3+
const { getLDHeaders, transformHeaders } = require('./headers');
34

45
// The underlying event source implementation is abstracted via the platform object, which should
56
// have these three properties:
@@ -20,7 +21,7 @@ function Stream(platform, config, environment, diagnosticsAccumulator) {
2021
const baseUrl = config.streamUrl;
2122
const logger = config.logger;
2223
const stream = {};
23-
const evalUrlPrefix = baseUrl + '/eval/' + environment;
24+
const evalUrlPrefix = appendUrlPath(baseUrl, '/eval/' + environment);
2425
const useReport = config.useReport;
2526
const withReasons = config.evaluationReasons;
2627
const streamReconnectDelay = config.streamReconnectDelay;
@@ -98,7 +99,7 @@ function Stream(platform, config, environment, diagnosticsAccumulator) {
9899
options.body = JSON.stringify(user);
99100
} else {
100101
// if we can't do REPORT, fall back to the old ping-based stream
101-
url = baseUrl + '/ping/' + environment;
102+
url = appendUrlPath(baseUrl, '/ping/' + environment);
102103
query = '';
103104
}
104105
} else {

src/__tests__/Stream-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { DiagnosticsAccumulator } from '../diagnosticEvents';
22
import * as messages from '../messages';
33
import Stream from '../Stream';
4-
import { getLDHeaders } from '../utils';
4+
import { getLDHeaders } from '../headers';
55

66
import { sleepAsync } from 'launchdarkly-js-test-helpers';
77
import EventSource from './EventSource-mock';

src/__tests__/configuration-test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,43 @@ describe('configuration', () => {
214214
expect(config.extraFunctionOption).toBe(fn);
215215
await listener.expectError(messages.wrongOptionType('extraNumericOptionWithoutDefault', 'number', 'string'));
216216
});
217+
218+
it('handles a valid application id', async () => {
219+
const listener = errorListener();
220+
const configIn = { application: { id: 'test-application' } };
221+
expect(configuration.validate(configIn, listener.emitter, null, listener.logger).application.id).toEqual(
222+
'test-application'
223+
);
224+
});
225+
226+
it('logs a warning with an invalid application id', async () => {
227+
const listener = errorListener();
228+
const configIn = { application: { id: 'test #$#$#' } };
229+
expect(configuration.validate(configIn, listener.emitter, null, listener.logger).application.id).toBeUndefined();
230+
await listener.expectWarningOnly(messages.invalidTagValue('application.id'));
231+
});
232+
233+
it('handles a valid application version', async () => {
234+
const listener = errorListener();
235+
const configIn = { application: { version: 'test-version' } };
236+
expect(configuration.validate(configIn, listener.emitter, null, listener.logger).application.version).toEqual(
237+
'test-version'
238+
);
239+
});
240+
241+
it('logs a warning with an invalid application version', async () => {
242+
const listener = errorListener();
243+
const configIn = { application: { version: 'test #$#$#' } };
244+
expect(
245+
configuration.validate(configIn, listener.emitter, null, listener.logger).application.version
246+
).toBeUndefined();
247+
await listener.expectWarningOnly(messages.invalidTagValue('application.version'));
248+
});
249+
250+
it('includes application id and version in tags when present', async () => {
251+
expect(configuration.getTags({ application: { id: 'test-id', version: 'test-version' } })).toEqual({
252+
'application-id': ['test-id'],
253+
'application-version': ['test-version'],
254+
});
255+
});
217256
});

src/__tests__/headers-test.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { getLDHeaders, transformHeaders } from '../headers';
2+
import { getLDUserAgentString } from '../utils';
3+
import * as stubPlatform from './stubPlatform';
4+
5+
describe('getLDHeaders', () => {
6+
it('sends no headers unless sendLDHeaders is true', () => {
7+
const platform = stubPlatform.defaults();
8+
const headers = getLDHeaders(platform, {});
9+
expect(headers).toEqual({});
10+
});
11+
12+
it('adds user-agent header', () => {
13+
const platform = stubPlatform.defaults();
14+
const headers = getLDHeaders(platform, { sendLDHeaders: true });
15+
expect(headers).toMatchObject({ 'User-Agent': getLDUserAgentString(platform) });
16+
});
17+
18+
it('adds user-agent header with custom name', () => {
19+
const platform = stubPlatform.defaults();
20+
platform.userAgentHeaderName = 'X-Fake-User-Agent';
21+
const headers = getLDHeaders(platform, { sendLDHeaders: true });
22+
expect(headers).toMatchObject({ 'X-Fake-User-Agent': getLDUserAgentString(platform) });
23+
});
24+
25+
it('adds wrapper info if specified, without version', () => {
26+
const platform = stubPlatform.defaults();
27+
const headers = getLDHeaders(platform, { sendLDHeaders: true, wrapperName: 'FakeSDK' });
28+
expect(headers).toMatchObject({
29+
'User-Agent': getLDUserAgentString(platform),
30+
'X-LaunchDarkly-Wrapper': 'FakeSDK',
31+
});
32+
});
33+
34+
it('adds wrapper info if specified, with version', () => {
35+
const platform = stubPlatform.defaults();
36+
const headers = getLDHeaders(platform, { sendLDHeaders: true, wrapperName: 'FakeSDK', wrapperVersion: '9.9' });
37+
expect(headers).toMatchObject({
38+
'User-Agent': getLDUserAgentString(platform),
39+
'X-LaunchDarkly-Wrapper': 'FakeSDK/9.9',
40+
});
41+
});
42+
43+
it('sets the X-LaunchDarkly-Tags header with valid id and version.', () => {
44+
const platform = stubPlatform.defaults();
45+
const headers = getLDHeaders(platform, {
46+
sendLDHeaders: true,
47+
application: {
48+
id: 'test-application',
49+
version: 'test-version',
50+
},
51+
});
52+
expect(headers).toMatchObject({
53+
'User-Agent': getLDUserAgentString(platform),
54+
'x-launchdarkly-tags': 'application-id/test-application application-version/test-version',
55+
});
56+
});
57+
58+
it('sets the X-LaunchDarkly-Tags header with just application id', () => {
59+
const platform = stubPlatform.defaults();
60+
const headers = getLDHeaders(platform, {
61+
sendLDHeaders: true,
62+
application: {
63+
id: 'test-application',
64+
},
65+
});
66+
expect(headers).toMatchObject({
67+
'User-Agent': getLDUserAgentString(platform),
68+
'x-launchdarkly-tags': 'application-id/test-application',
69+
});
70+
});
71+
72+
it('sets the X-LaunchDarkly-Tags header with just application version.', () => {
73+
const platform = stubPlatform.defaults();
74+
const headers = getLDHeaders(platform, {
75+
sendLDHeaders: true,
76+
application: {
77+
version: 'test-version',
78+
},
79+
});
80+
expect(headers).toMatchObject({
81+
'User-Agent': getLDUserAgentString(platform),
82+
'x-launchdarkly-tags': 'application-version/test-version',
83+
});
84+
});
85+
});
86+
87+
describe('transformHeaders', () => {
88+
it('does not modify the headers if the option is not available', () => {
89+
const inputHeaders = { a: '1', b: '2' };
90+
const headers = transformHeaders(inputHeaders, {});
91+
expect(headers).toEqual(inputHeaders);
92+
});
93+
94+
it('modifies the headers if the option has a transform', () => {
95+
const inputHeaders = { c: '3', d: '4' };
96+
const outputHeaders = { c: '9', d: '4', e: '5' };
97+
const headerTransform = input => {
98+
const output = { ...input };
99+
output['c'] = '9';
100+
output['e'] = '5';
101+
return output;
102+
};
103+
const headers = transformHeaders(inputHeaders, { requestHeaderTransform: headerTransform });
104+
expect(headers).toEqual(outputHeaders);
105+
});
106+
107+
it('cannot mutate the input header object', () => {
108+
const inputHeaders = { f: '6' };
109+
const expectedInputHeaders = { f: '6' };
110+
const headerMutate = input => {
111+
input['f'] = '7'; // eslint-disable-line no-param-reassign
112+
return input;
113+
};
114+
transformHeaders(inputHeaders, { requestHeaderTransform: headerMutate });
115+
expect(inputHeaders).toEqual(expectedInputHeaders);
116+
});
117+
});

src/__tests__/utils-test.js

Lines changed: 8 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
2+
appendUrlPath,
23
base64URLEncode,
3-
getLDHeaders,
4-
transformHeaders,
54
getLDUserAgentString,
65
wrapPromiseCallback,
76
chunkUserEventsForUrl,
@@ -10,6 +9,13 @@ import {
109
import * as stubPlatform from './stubPlatform';
1110

1211
describe('utils', () => {
12+
it('appendUrlPath', () => {
13+
expect(appendUrlPath('http://base', '/path')).toEqual('http://base/path');
14+
expect(appendUrlPath('http://base', 'path')).toEqual('http://base/path');
15+
expect(appendUrlPath('http://base/', '/path')).toEqual('http://base/path');
16+
expect(appendUrlPath('http://base/', '/path')).toEqual('http://base/path');
17+
});
18+
1319
describe('wrapPromiseCallback', () => {
1420
it('should resolve to the value', done => {
1521
const promise = wrapPromiseCallback(Promise.resolve('woohoo'));
@@ -48,77 +54,6 @@ describe('utils', () => {
4854
});
4955
});
5056

51-
describe('getLDHeaders', () => {
52-
it('sends no headers unless sendLDHeaders is true', () => {
53-
const platform = stubPlatform.defaults();
54-
const headers = getLDHeaders(platform, {});
55-
expect(headers).toEqual({});
56-
});
57-
58-
it('adds user-agent header', () => {
59-
const platform = stubPlatform.defaults();
60-
const headers = getLDHeaders(platform, { sendLDHeaders: true });
61-
expect(headers).toMatchObject({ 'User-Agent': getLDUserAgentString(platform) });
62-
});
63-
64-
it('adds user-agent header with custom name', () => {
65-
const platform = stubPlatform.defaults();
66-
platform.userAgentHeaderName = 'X-Fake-User-Agent';
67-
const headers = getLDHeaders(platform, { sendLDHeaders: true });
68-
expect(headers).toMatchObject({ 'X-Fake-User-Agent': getLDUserAgentString(platform) });
69-
});
70-
71-
it('adds wrapper info if specified, without version', () => {
72-
const platform = stubPlatform.defaults();
73-
const headers = getLDHeaders(platform, { sendLDHeaders: true, wrapperName: 'FakeSDK' });
74-
expect(headers).toMatchObject({
75-
'User-Agent': getLDUserAgentString(platform),
76-
'X-LaunchDarkly-Wrapper': 'FakeSDK',
77-
});
78-
});
79-
80-
it('adds wrapper info if specified, with version', () => {
81-
const platform = stubPlatform.defaults();
82-
const headers = getLDHeaders(platform, { sendLDHeaders: true, wrapperName: 'FakeSDK', wrapperVersion: '9.9' });
83-
expect(headers).toMatchObject({
84-
'User-Agent': getLDUserAgentString(platform),
85-
'X-LaunchDarkly-Wrapper': 'FakeSDK/9.9',
86-
});
87-
});
88-
});
89-
90-
describe('transformHeaders', () => {
91-
it('does not modify the headers if the option is not available', () => {
92-
const inputHeaders = { a: '1', b: '2' };
93-
const headers = transformHeaders(inputHeaders, {});
94-
expect(headers).toEqual(inputHeaders);
95-
});
96-
97-
it('modifies the headers if the option has a transform', () => {
98-
const inputHeaders = { c: '3', d: '4' };
99-
const outputHeaders = { c: '9', d: '4', e: '5' };
100-
const headerTransform = input => {
101-
const output = { ...input };
102-
output['c'] = '9';
103-
output['e'] = '5';
104-
return output;
105-
};
106-
const headers = transformHeaders(inputHeaders, { requestHeaderTransform: headerTransform });
107-
expect(headers).toEqual(outputHeaders);
108-
});
109-
110-
it('cannot mutate the input header object', () => {
111-
const inputHeaders = { f: '6' };
112-
const expectedInputHeaders = { f: '6' };
113-
const headerMutate = input => {
114-
input['f'] = '7'; // eslint-disable-line no-param-reassign
115-
return input;
116-
};
117-
transformHeaders(inputHeaders, { requestHeaderTransform: headerMutate });
118-
expect(inputHeaders).toEqual(expectedInputHeaders);
119-
});
120-
});
121-
12257
describe('getLDUserAgentString', () => {
12358
it('uses platform user-agent and unknown version by default', () => {
12459
const platform = stubPlatform.defaults();

0 commit comments

Comments
 (0)