From 11719ed943fb2b7713c80d27d67e656cfa4bfc5c Mon Sep 17 00:00:00 2001 From: Amir Blum Date: Wed, 21 Jul 2021 17:44:08 +0300 Subject: [PATCH 1/3] style: use single quotes everywhere and add a rule to eslint (#2351) --- eslint.config.js | 1 + .../src/CollectorExporterNodeBase.ts | 2 +- .../src/CollectorMetricExporter.ts | 2 +- .../src/CollectorTraceExporter.ts | 2 +- .../test/helper.ts | 32 +++++++++---------- .../src/jaeger.ts | 2 +- .../test/jaeger.test.ts | 16 +++++----- .../test/common/autoLoader.test.ts | 2 +- .../test/registration.test.ts | 2 +- .../opentelemetry-sdk-node/test/sdk.test.ts | 12 +++---- .../src/shim.ts | 10 +++--- .../test/Shim.test.ts | 2 +- .../test/common/Tracer.test.ts | 6 ++-- .../test/registration.test.ts | 4 +-- 14 files changed, 48 insertions(+), 47 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index a1514132f95..c78e7b660da 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -10,6 +10,7 @@ module.exports = { "project": "./tsconfig.json" }, rules: { + "quotes": [2, "single", { "avoidEscape": true }], "@typescript-eslint/no-floating-promises": 2, "@typescript-eslint/no-this-alias": "off", "brace-style": ["error", "1tbs"], diff --git a/packages/opentelemetry-exporter-collector-grpc/src/CollectorExporterNodeBase.ts b/packages/opentelemetry-exporter-collector-grpc/src/CollectorExporterNodeBase.ts index 0c14f0063bc..1ddac9722d3 100644 --- a/packages/opentelemetry-exporter-collector-grpc/src/CollectorExporterNodeBase.ts +++ b/packages/opentelemetry-exporter-collector-grpc/src/CollectorExporterNodeBase.ts @@ -26,7 +26,7 @@ import { ServiceClientType, } from './types'; import { ServiceClient } from './types'; -import { getEnv, baggageUtils } from "@opentelemetry/core"; +import { getEnv, baggageUtils } from '@opentelemetry/core'; /** * Collector Metric Exporter abstract base class diff --git a/packages/opentelemetry-exporter-collector-grpc/src/CollectorMetricExporter.ts b/packages/opentelemetry-exporter-collector-grpc/src/CollectorMetricExporter.ts index c909241a73d..e1c84942cf7 100644 --- a/packages/opentelemetry-exporter-collector-grpc/src/CollectorMetricExporter.ts +++ b/packages/opentelemetry-exporter-collector-grpc/src/CollectorMetricExporter.ts @@ -23,7 +23,7 @@ import { CollectorExporterConfigNode, ServiceClientType } from './types'; import { CollectorExporterNodeBase } from './CollectorExporterNodeBase'; import { baggageUtils, getEnv } from '@opentelemetry/core'; import { validateAndNormalizeUrl } from './util'; -import { Metadata } from "@grpc/grpc-js"; +import { Metadata } from '@grpc/grpc-js'; const DEFAULT_COLLECTOR_URL = 'localhost:4317'; diff --git a/packages/opentelemetry-exporter-collector-grpc/src/CollectorTraceExporter.ts b/packages/opentelemetry-exporter-collector-grpc/src/CollectorTraceExporter.ts index f0b63cbb79e..cfb147fa39b 100644 --- a/packages/opentelemetry-exporter-collector-grpc/src/CollectorTraceExporter.ts +++ b/packages/opentelemetry-exporter-collector-grpc/src/CollectorTraceExporter.ts @@ -23,7 +23,7 @@ import { import { CollectorExporterConfigNode, ServiceClientType } from './types'; import { baggageUtils, getEnv } from '@opentelemetry/core'; import { validateAndNormalizeUrl } from './util'; -import { Metadata } from "@grpc/grpc-js"; +import { Metadata } from '@grpc/grpc-js'; const DEFAULT_COLLECTOR_URL = 'localhost:4317'; diff --git a/packages/opentelemetry-exporter-collector-grpc/test/helper.ts b/packages/opentelemetry-exporter-collector-grpc/test/helper.ts index 6e66e5a8661..b9346c92d04 100644 --- a/packages/opentelemetry-exporter-collector-grpc/test/helper.ts +++ b/packages/opentelemetry-exporter-collector-grpc/test/helper.ts @@ -410,31 +410,31 @@ export function ensureResourceIsCorrect( assert.deepStrictEqual(resource, { attributes: [ { - "key": "service.name", - "value": { - "stringValue": `unknown_service:${process.argv0}`, - "value": "stringValue" + 'key': 'service.name', + 'value': { + 'stringValue': `unknown_service:${process.argv0}`, + 'value': 'stringValue' } }, { - "key": "telemetry.sdk.language", - "value": { - "stringValue": "nodejs", - "value": "stringValue" + 'key': 'telemetry.sdk.language', + 'value': { + 'stringValue': 'nodejs', + 'value': 'stringValue' } }, { - "key": "telemetry.sdk.name", - "value": { - "stringValue": "opentelemetry", - "value": "stringValue" + 'key': 'telemetry.sdk.name', + 'value': { + 'stringValue': 'opentelemetry', + 'value': 'stringValue' } }, { - "key": "telemetry.sdk.version", - "value": { - "stringValue": VERSION, - "value": "stringValue" + 'key': 'telemetry.sdk.version', + 'value': { + 'stringValue': VERSION, + 'value': 'stringValue' } }, { diff --git a/packages/opentelemetry-exporter-jaeger/src/jaeger.ts b/packages/opentelemetry-exporter-jaeger/src/jaeger.ts index 335767366d6..f6514fadd7e 100644 --- a/packages/opentelemetry-exporter-jaeger/src/jaeger.ts +++ b/packages/opentelemetry-exporter-jaeger/src/jaeger.ts @@ -156,7 +156,7 @@ export class JaegerExporter implements SpanExporter { } const serviceNameTag = span.tags.find(t => t.key === ResourceAttributes.SERVICE_NAME) - const serviceName = serviceNameTag?.vStr || "unknown_service"; + const serviceName = serviceNameTag?.vStr || 'unknown_service'; sender.setProcess({ serviceName, diff --git a/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts b/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts index 0766e5a72a0..b18ea08d366 100644 --- a/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts +++ b/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts @@ -93,8 +93,8 @@ describe('JaegerExporter', () => { const process: ThriftProcess = exporter['_getSender']({ tags: [{ - key: "service.name", - vStr: "opentelemetry" + key: 'service.name', + vStr: 'opentelemetry' }] } as any)._process; assert.strictEqual(exporter['_sender']._host, 'remotehost'); @@ -109,8 +109,8 @@ describe('JaegerExporter', () => { const exporter = new JaegerExporter(); const sender = exporter['_getSender']({ tags: [{ - key: "service.name", - vStr: "opentelemetry" + key: 'service.name', + vStr: 'opentelemetry' }] } as any); assert.strictEqual(sender._host, 'localhost'); @@ -121,8 +121,8 @@ describe('JaegerExporter', () => { const exporter = new JaegerExporter(); const sender = exporter['_getSender']({ tags: [{ - key: "service.name", - vStr: "opentelemetry" + key: 'service.name', + vStr: 'opentelemetry' }] } as any); assert.strictEqual(sender._host, 'env-set-host'); @@ -135,8 +135,8 @@ describe('JaegerExporter', () => { }); const sender = exporter['_getSender']({ tags: [{ - key: "service.name", - vStr: "opentelemetry" + key: 'service.name', + vStr: 'opentelemetry' }] } as any); assert.strictEqual(sender._host, 'option-set-host'); diff --git a/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts b/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts index 181eb12c0ea..c378f83fe61 100644 --- a/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts +++ b/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts @@ -22,7 +22,7 @@ import { InstrumentationBase, registerInstrumentations } from '../../src'; class DummyTracerProvider implements TracerProvider { getTracer(name: string, version?: string): Tracer { - throw new Error("not implemented"); + throw new Error('not implemented'); } } class FooInstrumentation extends InstrumentationBase { diff --git a/packages/opentelemetry-node/test/registration.test.ts b/packages/opentelemetry-node/test/registration.test.ts index e199898a13b..4db2d334b4b 100644 --- a/packages/opentelemetry-node/test/registration.test.ts +++ b/packages/opentelemetry-node/test/registration.test.ts @@ -78,7 +78,7 @@ describe('API registration', () => { contextManager: null, }); - assert.strictEqual(context['_getContextManager'](), ctxManager, "context manager should not change"); + assert.strictEqual(context['_getContextManager'](), ctxManager, 'context manager should not change'); assert.ok( propagation['_getGlobalPropagator']() instanceof CompositePropagator diff --git a/packages/opentelemetry-sdk-node/test/sdk.test.ts b/packages/opentelemetry-sdk-node/test/sdk.test.ts index 3f80f61678c..931a6845d51 100644 --- a/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -113,9 +113,9 @@ describe('Node SDK', () => { await sdk.start(); - assert.strictEqual(context['_getContextManager'](), ctxManager, "context manager should not change"); - assert.strictEqual(propagation['_getGlobalPropagator'](), propagator, "propagator should not change"); - assert.strictEqual((trace.getTracerProvider() as ProxyTracerProvider).getDelegate(), delegate, "tracer provider should not have changed"); + assert.strictEqual(context['_getContextManager'](), ctxManager, 'context manager should not change'); + assert.strictEqual(propagation['_getGlobalPropagator'](), propagator, 'propagator should not change'); + assert.strictEqual((trace.getTracerProvider() as ProxyTracerProvider).getDelegate(), delegate, 'tracer provider should not have changed'); assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); }); @@ -173,9 +173,9 @@ describe('Node SDK', () => { await sdk.start(); - assert.strictEqual(context['_getContextManager'](), ctxManager, "context manager should not change"); - assert.strictEqual(propagation['_getGlobalPropagator'](), propagator, "propagator should not change"); - assert.strictEqual((trace.getTracerProvider() as ProxyTracerProvider).getDelegate(), delegate, "tracer provider should not have changed"); + assert.strictEqual(context['_getContextManager'](), ctxManager, 'context manager should not change'); + assert.strictEqual(propagation['_getGlobalPropagator'](), propagator, 'propagator should not change'); + assert.strictEqual((trace.getTracerProvider() as ProxyTracerProvider).getDelegate(), delegate, 'tracer provider should not have changed'); assert.ok(metrics.getMeterProvider() instanceof MeterProvider); }); diff --git a/packages/opentelemetry-shim-opentracing/src/shim.ts b/packages/opentelemetry-shim-opentracing/src/shim.ts index 482fe9c56ca..e1423d7e881 100644 --- a/packages/opentelemetry-shim-opentracing/src/shim.ts +++ b/packages/opentelemetry-shim-opentracing/src/shim.ts @@ -17,7 +17,7 @@ import * as api from '@opentelemetry/api'; import { SpanAttributes, SpanAttributeValue, SpanStatusCode, TextMapPropagator } from '@opentelemetry/api'; import * as opentracing from 'opentracing'; -import { SemanticAttributes } from "@opentelemetry/semantic-conventions"; +import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; function translateReferences(references: opentracing.Reference[]): api.Link[] { const links: api.Link[] = []; @@ -301,7 +301,7 @@ export class SpanShim extends opentracing.Span { const entries = Object.entries(attributes); const errorEntry = entries.find(([key]) => key === 'error.object'); const error = errorEntry?.[1]; - if (typeof error === "string") { + if (typeof error === 'string') { this._span.recordException(error, timestamp); return; } @@ -309,15 +309,15 @@ export class SpanShim extends opentracing.Span { const mappedAttributes: api.SpanAttributes = {}; for (const [k, v] of entries) { switch (k) { - case "error.kind": { + case 'error.kind': { mappedAttributes[SemanticAttributes.EXCEPTION_TYPE] = v; break; } - case "message": { + case 'message': { mappedAttributes[SemanticAttributes.EXCEPTION_MESSAGE] = v; break; } - case "stack": { + case 'stack': { mappedAttributes[SemanticAttributes.EXCEPTION_STACKTRACE] = v; break; } diff --git a/packages/opentelemetry-shim-opentracing/test/Shim.test.ts b/packages/opentelemetry-shim-opentracing/test/Shim.test.ts index 882ebe3ca1c..321f25359ce 100644 --- a/packages/opentelemetry-shim-opentracing/test/Shim.test.ts +++ b/packages/opentelemetry-shim-opentracing/test/Shim.test.ts @@ -36,7 +36,7 @@ import { import { performance } from 'perf_hooks'; import { B3Propagator } from '@opentelemetry/propagator-b3'; import { JaegerPropagator } from '@opentelemetry/propagator-jaeger'; -import { SemanticAttributes } from "@opentelemetry/semantic-conventions"; +import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; describe('OpenTracing Shim', () => { const compositePropagator = new CompositePropagator({ diff --git a/packages/opentelemetry-tracing/test/common/Tracer.test.ts b/packages/opentelemetry-tracing/test/common/Tracer.test.ts index 30180ef4688..b0e56c21613 100644 --- a/packages/opentelemetry-tracing/test/common/Tracer.test.ts +++ b/packages/opentelemetry-tracing/test/common/Tracer.test.ts @@ -238,7 +238,7 @@ describe('Tracer', () => { tracerProvider ); - const spy = sinon.spy(tracer, "startSpan"); + const spy = sinon.spy(tracer, 'startSpan'); assert.strictEqual(tracer.startActiveSpan('my-span', span => { try { @@ -259,7 +259,7 @@ describe('Tracer', () => { tracerProvider ); - const spy = sinon.spy(tracer, "startSpan"); + const spy = sinon.spy(tracer, 'startSpan'); assert.strictEqual(tracer.startActiveSpan('my-span', {attributes: {foo: 'bar'}}, span => { try { @@ -283,7 +283,7 @@ describe('Tracer', () => { const ctx = context.active().setValue(ctxKey, 'bar') - const spy = sinon.spy(tracer, "startSpan"); + const spy = sinon.spy(tracer, 'startSpan'); assert.strictEqual(tracer.startActiveSpan('my-span', {attributes: {foo: 'bar'}}, ctx, span => { try { diff --git a/packages/opentelemetry-web/test/registration.test.ts b/packages/opentelemetry-web/test/registration.test.ts index baab6a4d777..e2c497883cd 100644 --- a/packages/opentelemetry-web/test/registration.test.ts +++ b/packages/opentelemetry-web/test/registration.test.ts @@ -68,7 +68,7 @@ describe('API registration', () => { contextManager: null, }); - assert.strictEqual(context['_getContextManager'](), ctxManager, "context manager should not change"); + assert.strictEqual(context['_getContextManager'](), ctxManager, 'context manager should not change'); assert.ok( propagation['_getGlobalPropagator']() instanceof CompositePropagator @@ -84,7 +84,7 @@ describe('API registration', () => { propagator: null, }); - assert.strictEqual(propagation["_getGlobalPropagator"](), propagator, "propagator should not change") + assert.strictEqual(propagation['_getGlobalPropagator'](), propagator, 'propagator should not change') assert.ok(context['_getContextManager']() instanceof StackContextManager); const apiTracerProvider = trace.getTracerProvider() as ProxyTracerProvider; From c55142f88a1bca6999e9ac3d3463f312f1525b42 Mon Sep 17 00:00:00 2001 From: Liz Fong-Jones Date: Wed, 21 Jul 2021 11:40:48 -0400 Subject: [PATCH 2/3] fix(@opentelemetry/exporter-collector-grpc) regression from #2130 when host specified without protocol (#2322) * fix regression from #2130 when host specified without protocol * Update util.test.ts * Apply suggestions from code review Co-authored-by: Naseem * revert package.json changes * Update util.ts * add tests as per @msnev request * Update packages/opentelemetry-exporter-collector-grpc/src/util.ts Co-authored-by: Naseem Co-authored-by: Naseem --- .../src/util.ts | 6 +- .../test/util.test.ts | 81 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 packages/opentelemetry-exporter-collector-grpc/test/util.test.ts diff --git a/packages/opentelemetry-exporter-collector-grpc/src/util.ts b/packages/opentelemetry-exporter-collector-grpc/src/util.ts index 39330afc3bb..299a6e7e819 100644 --- a/packages/opentelemetry-exporter-collector-grpc/src/util.ts +++ b/packages/opentelemetry-exporter-collector-grpc/src/util.ts @@ -108,8 +108,12 @@ export function send( } export function validateAndNormalizeUrl(url: string): string { + const hasProtocol = url.match(/^([\w]{1,8}):\/\//); + if (!hasProtocol) { + url = `https://${url}`; + } const target = new URL(url); - if (target.pathname !== '/') { + if (target.pathname && target.pathname !== '/') { diag.warn( 'URL path should not be set when using grpc, the path part of the URL will be ignored.' ); diff --git a/packages/opentelemetry-exporter-collector-grpc/test/util.test.ts b/packages/opentelemetry-exporter-collector-grpc/test/util.test.ts new file mode 100644 index 00000000000..ba08009cd55 --- /dev/null +++ b/packages/opentelemetry-exporter-collector-grpc/test/util.test.ts @@ -0,0 +1,81 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as sinon from 'sinon'; +import * as assert from 'assert'; + +import { diag } from '@opentelemetry/api'; +import { validateAndNormalizeUrl } from '../src/util'; + +// Tests added to detect breakage released in #2130 +describe('validateAndNormalizeUrl()', () => { + const tests = [ + { + name: 'bare hostname should return same value', + input: 'api.datacat.io', + expected: 'api.datacat.io', + }, + { + name: 'host:port should return same value', + input: 'api.datacat.io:1234', + expected: 'api.datacat.io:1234', + }, + { + name: 'grpc://host:port should trim off protocol', + input: 'grpc://api.datacat.io:1234', + expected: 'api.datacat.io:1234', + }, + { + name: 'bad protocol should warn but return host:port', + input: 'badproto://api.datacat.io:1234', + expected: 'api.datacat.io:1234', + warn: 'URL protocol should be http(s):// or grpc(s)://. Using grpc://.', + }, + { + name: 'path on end of url should warn but return host:port', + input: 'grpc://api.datacat.io:1234/a/b/c', + expected: 'api.datacat.io:1234', + warn: 'URL path should not be set when using grpc, the path part of the URL will be ignored.', + }, + { + name: ':// in path should not be used for protocol even if protocol not specified', + input: 'api.datacat.io/a/b://c', + expected: 'api.datacat.io', + warn: 'URL path should not be set when using grpc, the path part of the URL will be ignored.', + }, + { + name: ':// in path is valid when a protocol is specified', + input: 'grpc://api.datacat.io/a/b://c', + expected: 'api.datacat.io', + warn: 'URL path should not be set when using grpc, the path part of the URL will be ignored.', + }, + ]; + tests.forEach(test => { + it(test.name, () => { + const diagWarn = sinon.stub(diag, 'warn'); + try { + assert.strictEqual(validateAndNormalizeUrl(test.input), (test.expected)); + if (test.warn) { + sinon.assert.calledWith(diagWarn, test.warn); + } else { + sinon.assert.notCalled(diagWarn); + } + } finally { + diagWarn.restore(); + } + }); + }); +}); From cb06b788b27ff080326b74bf4c3d08f419a06529 Mon Sep 17 00:00:00 2001 From: Niko Achilles Kokkinos Date: Wed, 21 Jul 2021 18:57:23 +0300 Subject: [PATCH 3/3] fix: headers are appended to existing one (open-telemetry#2335) (#2357) * fix: headers are appended to existing one (open-telemetry#2335) * test(browser-util): added 2 more test-cases refactored desc, it wording * test: split tests review * fix: review headers are appended to existing one (open-telemetry#2335) * test: review DRY * fix: review lint Co-authored-by: Valentin Marchaud Co-authored-by: Daniel Dyla --- .../src/platform/browser/util.ts | 13 +- .../test/browser/util.test.ts | 128 ++++++++++++++++++ 2 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 packages/opentelemetry-exporter-collector/test/browser/util.test.ts diff --git a/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts b/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts index a695ee6944d..5c57517235b 100644 --- a/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts +++ b/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts @@ -55,9 +55,16 @@ export function sendWithXhr( ) { const xhr = new XMLHttpRequest(); xhr.open('POST', url); - xhr.setRequestHeader('Accept', 'application/json'); - xhr.setRequestHeader('Content-Type', 'application/json'); - Object.entries(headers).forEach(([k, v]) => { + + const defaultHeaders = { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }; + + Object.entries({ + ...defaultHeaders, + ...headers, + }).forEach(([k, v]) => { xhr.setRequestHeader(k, v); }); diff --git a/packages/opentelemetry-exporter-collector/test/browser/util.test.ts b/packages/opentelemetry-exporter-collector/test/browser/util.test.ts new file mode 100644 index 00000000000..ecb6c4c8019 --- /dev/null +++ b/packages/opentelemetry-exporter-collector/test/browser/util.test.ts @@ -0,0 +1,128 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as sinon from 'sinon'; +import { sendWithXhr } from '../../src/platform/browser/util'; +import { ensureHeadersContain } from '../helper'; + +describe('util - browser', () => { + let server: any; + const body = ''; + const url = ''; + + let onSuccessStub: sinon.SinonStub; + let onErrorStub: sinon.SinonStub; + + beforeEach(() => { + onSuccessStub = sinon.stub(); + onErrorStub = sinon.stub(); + server = sinon.fakeServer.create(); + }); + + afterEach(() => { + server.restore(); + sinon.restore(); + }); + + describe('when XMLHTTPRequest is used', () => { + let expectedHeaders: Record; + beforeEach(()=>{ + expectedHeaders = { + // ;charset=utf-8 is applied by sinon.fakeServer + 'Content-Type': 'application/json;charset=utf-8', + 'Accept': 'application/json', + } + }); + describe('and Content-Type header is set', () => { + beforeEach(()=>{ + const explicitContentType = { + 'Content-Type': 'application/json', + }; + sendWithXhr(body, url, explicitContentType, onSuccessStub, onErrorStub); + }); + it('Request Headers should contain "Content-Type" header', done => { + + setTimeout(() => { + const { requestHeaders } = server.requests[0]; + ensureHeadersContain(requestHeaders, expectedHeaders); + done(); + }); + }); + it('Request Headers should contain "Accept" header', done => { + + setTimeout(() => { + const { requestHeaders } = server.requests[0]; + ensureHeadersContain(requestHeaders, expectedHeaders); + done(); + }); + }); + }); + + describe('and empty headers are set', () => { + beforeEach(()=>{ + const emptyHeaders = {}; + sendWithXhr(body, url, emptyHeaders, onSuccessStub, onErrorStub); + }); + it('Request Headers should contain "Content-Type" header', done => { + + setTimeout(() => { + const { requestHeaders } = server.requests[0]; + ensureHeadersContain(requestHeaders, expectedHeaders); + done(); + }); + }); + it('Request Headers should contain "Accept" header', done => { + + setTimeout(() => { + const { requestHeaders } = server.requests[0]; + ensureHeadersContain(requestHeaders, expectedHeaders); + done(); + }); + }); + }); + describe('and custom headers are set', () => { + let customHeaders: Record; + beforeEach(()=>{ + customHeaders = { aHeader: 'aValue', bHeader: 'bValue' }; + sendWithXhr(body, url, customHeaders, onSuccessStub, onErrorStub); + }); + it('Request Headers should contain "Content-Type" header', done => { + + setTimeout(() => { + const { requestHeaders } = server.requests[0]; + ensureHeadersContain(requestHeaders, expectedHeaders); + done(); + }); + }); + it('Request Headers should contain "Accept" header', done => { + + setTimeout(() => { + const { requestHeaders } = server.requests[0]; + ensureHeadersContain(requestHeaders, expectedHeaders); + done(); + }); + }); + it('Request Headers should contain custom headers', done => { + + setTimeout(() => { + const { requestHeaders } = server.requests[0]; + ensureHeadersContain(requestHeaders, customHeaders); + done(); + }); + }); + }); + }); +});