Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(common)!: when transforming optional boolean parameters on ValidationPipe #10953

Merged
merged 2 commits into from Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/common/pipes/validation.pipe.ts
Expand Up @@ -18,7 +18,7 @@ import {
HttpErrorByCode,
} from '../utils/http-error-by-code.util';
import { loadPackage } from '../utils/load-package.util';
import { isNil } from '../utils/shared.utils';
import { isNil, isUndefined } from '../utils/shared.utils';

export interface ValidationPipeOptions extends ValidatorOptions {
transform?: boolean;
Expand Down Expand Up @@ -179,6 +179,13 @@ export class ValidationPipe implements PipeTransform<any> {
return value;
}
if (metatype === Boolean) {
if (isUndefined(value)) {
// This is an workaround to deal with optional boolean values since
// optional booleans shouldn't be parsed to a valid boolean when
// they were not defined
return undefined;
}
// Any fasly value but `undefined` will be parsed to `false`
return value === true || value === 'true';
}
if (metatype === Number) {
Expand Down
76 changes: 74 additions & 2 deletions packages/common/test/pipes/validation.pipe.spec.ts
Expand Up @@ -221,7 +221,7 @@ describe('ValidationPipe', () => {
});
});
describe('when input is a query parameter (boolean)', () => {
it('should parse to boolean', async () => {
it('should parse the string "true" to the boolean true', async () => {
target = new ValidationPipe({ transform: true });
const value = 'true';

Expand All @@ -233,9 +233,45 @@ describe('ValidationPipe', () => {
}),
).to.be.true;
});
it('should parse the string "false" to the boolean false', async () => {
target = new ValidationPipe({ transform: true });
const value = 'false';

expect(
await target.transform(value, {
metatype: Boolean,
data: 'test',
type: 'query',
}),
).to.be.false;
});
it('should parse an empty string to false', async () => {
target = new ValidationPipe({ transform: true });
const value = '';

expect(
await target.transform(value, {
metatype: Boolean,
data: 'test',
type: 'query',
}),
).to.be.false;
});
it('should parse undefined to undefined', async () => {
target = new ValidationPipe({ transform: true });
const value = undefined;

expect(
await target.transform(value, {
metatype: Boolean,
data: 'test',
type: 'query',
}),
).to.be.undefined;
});
});
describe('when input is a path parameter (boolean)', () => {
it('should parse to boolean', async () => {
it('should parse the string "true" to boolean true', async () => {
target = new ValidationPipe({ transform: true });
const value = 'true';

Expand All @@ -247,6 +283,42 @@ describe('ValidationPipe', () => {
}),
).to.be.true;
});
it('should parse the string "false" to boolean false', async () => {
target = new ValidationPipe({ transform: true });
const value = 'false';

expect(
await target.transform(value, {
metatype: Boolean,
data: 'test',
type: 'param',
}),
).to.be.false;
});
it('should parse an empty string to false', async () => {
target = new ValidationPipe({ transform: true });
const value = '';

expect(
await target.transform(value, {
metatype: Boolean,
data: 'test',
type: 'param',
}),
).to.be.false;
});
it('should parse undefined to undefined', async () => {
target = new ValidationPipe({ transform: true });
const value = undefined;

expect(
await target.transform(value, {
metatype: Boolean,
data: 'test',
type: 'param',
}),
).to.be.undefined;
});
});
describe('when validation strips', () => {
it('should return a TestModel without extra properties', async () => {
Expand Down