Skip to content

Commit e6d59be

Browse files
committed
fix: correctly handle body requests that are falsy
1 parent 8e17f14 commit e6d59be

File tree

2 files changed

+107
-2
lines changed

2 files changed

+107
-2
lines changed

packages/http/src/validator/__tests__/index.spec.ts

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,111 @@ describe('HttpValidator', () => {
7777
});
7878
});
7979

80+
describe('falsey primitive body values', () => {
81+
afterAll(() => {
82+
// Re-setup the mocks that were defined in the outer beforeAll
83+
jest.spyOn(validators, 'validateQuery').mockReturnValue(E.left([mockError]));
84+
jest.spyOn(validators, 'validateBody').mockReturnValue(E.left([mockError]));
85+
jest.spyOn(validators, 'validateHeaders').mockReturnValue(E.left([mockError]));
86+
jest.spyOn(validators, 'validatePath').mockReturnValue(E.left([mockError]));
87+
});
88+
89+
beforeEach(() => jest.restoreAllMocks());
90+
91+
it('accepts 0 as a valid integer body', () => {
92+
const result = validator.validateInput({
93+
resource: {
94+
method: 'post',
95+
path: '/',
96+
id: '1',
97+
request: {
98+
body: {
99+
id: faker.random.word(),
100+
required: true,
101+
contents: [
102+
{
103+
id: faker.random.word(),
104+
mediaType: 'application/json',
105+
schema: { type: 'integer' },
106+
},
107+
],
108+
},
109+
},
110+
responses: [{ id: faker.random.word(), code: '200' }],
111+
},
112+
element: {
113+
method: 'post',
114+
url: { path: '/', query: {} },
115+
body: 0,
116+
headers: { 'content-type': 'application/json', 'content-length': '1' },
117+
},
118+
});
119+
assertRight(result);
120+
});
121+
122+
it('accepts false as a valid boolean body', () => {
123+
const result = validator.validateInput({
124+
resource: {
125+
method: 'post',
126+
path: '/',
127+
id: '1',
128+
request: {
129+
body: {
130+
id: faker.random.word(),
131+
required: true,
132+
contents: [
133+
{
134+
id: faker.random.word(),
135+
mediaType: 'application/json',
136+
schema: { type: 'boolean' },
137+
},
138+
],
139+
},
140+
},
141+
responses: [{ id: faker.random.word(), code: '200' }],
142+
},
143+
element: {
144+
method: 'post',
145+
url: { path: '/', query: {} },
146+
body: false,
147+
headers: { 'content-type': 'application/json', 'content-length': '5' },
148+
},
149+
});
150+
assertRight(result);
151+
});
152+
153+
it('accepts empty string as a valid string body', () => {
154+
const result = validator.validateInput({
155+
resource: {
156+
method: 'post',
157+
path: '/',
158+
id: '1',
159+
request: {
160+
body: {
161+
id: faker.random.word(),
162+
required: true,
163+
contents: [
164+
{
165+
id: faker.random.word(),
166+
mediaType: 'application/json',
167+
schema: { type: 'string' },
168+
},
169+
],
170+
},
171+
},
172+
responses: [{ id: faker.random.word(), code: '200' }],
173+
},
174+
element: {
175+
method: 'post',
176+
url: { path: '/', query: {} },
177+
body: '',
178+
headers: { 'content-type': 'application/json', 'content-length': '2' },
179+
},
180+
});
181+
assertRight(result);
182+
});
183+
});
184+
80185
describe('headers validation in enabled', () => {
81186
describe('request is not set', () => {
82187
it('does not validate headers', validate(undefined, undefined, 0));

packages/http/src/validator/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ const checkRequiredBodyIsProvided = (requestBody: O.Option<IHttpOperationRequest
3030
pipe(
3131
requestBody,
3232
E.fromPredicate<O.Option<IHttpOperationRequestBody>, NonEmptyArray<IPrismDiagnostic>>(
33-
requestBody => O.isNone(requestBody) || !(!!requestBody.value.required && !body),
33+
requestBody => O.isNone(requestBody) || !(!!requestBody.value.required && body === undefined),
3434
() => [{ code: 'required', message: 'Body parameter is required', severity: DiagnosticSeverity.Error }]
3535
),
36-
E.map(requestBody => [requestBody, O.fromNullable(body)] as const)
36+
E.map(requestBody => [requestBody, body === undefined ? O.none : O.some(body)] as const)
3737
);
3838

3939
const isMediaTypeSupportedInContents = (mediaType?: string, contents?: IMediaTypeContent[]): boolean =>

0 commit comments

Comments
 (0)