fix(testing): auto detect `Content-Type` when passing HTTP request body
MODIFY
packages/testing/src/testBed/http/http.testBed.request.spec.ts
packages/testing/src/testBed/http/http.testBed.request.spec.ts
@@ -6,7 +6,7 @@ describe('TestBed - HTTP request', () => {
// given
const port = 8080;
const host = '127.0.0.1';
- const defaultHeaders = { 'Content-Type': 'application/json' };
+ const defaultHeaders = { 'X-User-Id': '123' };
const req = createRequest(port, host, defaultHeaders);
// when
@@ -31,7 +31,47 @@ describe('TestBed - HTTP request', () => {
'Authorization': 'Bearer TOKEN',
'Content-Type': 'application/json',
'X-Testing-Request-Id': expect.any(String),
+ 'X-User-Id': '123',
},
});
});
+
+ test('doesn\'t detect "Content-Type" header if defined', () => {
+ // given
+ const port = 8080;
+ const host = '127.0.0.1';
+ const req = createRequest(port, host);
+
+ // when
+ const builtRequest = pipe(
+ req('POST'),
+ withPath('/test'),
+ withHeaders({ 'Content-Type': 'text/html' }),
+ withBody({ foo: 'bar' }),
+ );
+
+ expect(builtRequest.headers).toEqual({
+ 'Content-Type': 'text/html',
+ 'X-Testing-Request-Id': expect.any(String),
+ });
+ });
+
+ test('detects "Content-Type" header if not defined', () => {
+ // given
+ const port = 8080;
+ const host = '127.0.0.1';
+ const req = createRequest(port, host);
+
+ // when
+ const builtRequest = pipe(
+ req('POST'),
+ withPath('/test'),
+ withBody({ foo: 'bar' }),
+ );
+
+ expect(builtRequest.headers).toEqual({
+ 'Content-Type': 'application/json',
+ 'X-Testing-Request-Id': expect.any(String),
+ });
+ });
});

MODIFY
packages/testing/src/testBed/http/http.testBed.request.ts
packages/testing/src/testBed/http/http.testBed.request.ts
@@ -2,6 +2,7 @@ import { HttpMethod, HttpHeaders } from '@marblejs/core'
import * as O from 'fp-ts/lib/Option';
import * as A from 'fp-ts/lib/Array';
import { pipe } from 'fp-ts/lib/pipeable';
+import { getMimeType } from '@marblejs/core/dist/http/response/http.responseContentType.factory';
import { HttpTestBedRequest, WithBodyApplied } from './http.testBed.request.interface';
import { createTestingRequestHeader } from './http.testBed.util';
@@ -28,10 +29,16 @@ export const withHeaders = (headers: HttpHeaders) => <T extends HttpMethod>(req:
headers: { ...req.headers, ...headers },
});
-export const withBody = <T>(body: T) => <U extends 'POST' | 'PUT' | 'PATCH'>(req: HttpTestBedRequest<U>): HttpTestBedRequest<U> & WithBodyApplied<T> => ({
- ...req,
- body,
-});
+export const withBody = <T>(body: T) => <U extends 'POST' | 'PUT' | 'PATCH'>(req: HttpTestBedRequest<U>): HttpTestBedRequest<U> & WithBodyApplied<T> =>
+ pipe(
+ getHeader('Content-Type')(req),
+ O.map(() => ({ ...req, body })),
+ O.getOrElse(() => pipe(
+ getMimeType(body, req.path),
+ type => withHeaders({ 'Content-Type': type })(req),
+ req => ({ ...req, body }),
+ ))
+ );
export const getHeader = <T extends string = string>(key: string) => (req: HttpTestBedRequest<any>): O.Option<T> =>
pipe(

MODIFY
packages/testing/src/testBed/http/http.testBed.ts
packages/testing/src/testBed/http/http.testBed.ts
@@ -17,9 +17,9 @@ import { setTestingMetadata } from './http.testBed.util';
const sendRequest = async <T extends HttpMethod>(testBedRequest: HttpTestBedRequest<T>): Promise<HttpTestBedResponse> =>
new Promise((resolve, reject) => {
const clientRequest = request({
+ headers: testBedRequest.headers,
port: testBedRequest.port,
protocol: testBedRequest.protocol,
- headers: testBedRequest.headers,
method: testBedRequest.method,
host: testBedRequest.host,
path: testBedRequest.path,
@@ -45,9 +45,12 @@ const sendRequest = async <T extends HttpMethod>(testBedRequest: HttpTestBedRequ
return testBedRequest.body.pipe(clientRequest);
}
+ if (testBedRequest.body) {
const body = bodyFactory(testBedRequest.headers)(testBedRequest.body);
-
return clientRequest.end(body);
+ }
+
+ return clientRequest.end();
});
const getRequestMetadata = (request: HttpTestBedRequest<any>) => (ask: ContextProvider): TestingMetadata => {
@@ -64,6 +67,8 @@ const getRequestMetadata = (request: HttpTestBedRequest<any>) => (ask: ContextPr
export const createHttpTestBed = (config: HttpTestBedConfig): TestBedFactory<HttpTestBed> => async (dependencies = []) => {
const { listener } = config;
+ setTestingMetadata();
+
const app = await createServer({ listener, dependencies });
const server = await app();
const ask = lookup(app.context);
@@ -77,8 +82,6 @@ export const createHttpTestBed = (config: HttpTestBedConfig): TestBedFactory<Htt
return { ...response, metadata };
};
- setTestingMetadata();
-
return {
type: TestBedType.HTTP,
ask,

fix(testing): auto detect `Content-Type` when passing HTTP request body