Skip to content

Commit

Permalink
fix(validation): properly validate nullable items array (#1329)
Browse files Browse the repository at this point in the history
Co-authored-by: Michał Lytek <michal.wojciech.lytek@gmail.com>
  • Loading branch information
papermana and MichalLytek authored Aug 17, 2022
1 parent 82e056d commit 643087b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<!-- here goes all the unreleased changes descriptions -->
### Fixes
- support overwriting fields of extended types (#1109)
- properly execute args validation for nullable items array (#1328)

## v1.2.0-rc.1
### Features
Expand Down
13 changes: 10 additions & 3 deletions src/resolvers/validate-arg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import { TypeValue } from "../decorators/types";
import { ArgumentValidationError } from "../errors/ArgumentValidationError";
import { ValidateSettings } from "../schema/build-context";

const shouldArgBeValidated = (argValue: unknown): boolean =>
argValue !== null && typeof argValue === "object";

export async function validateArg<T extends object>(
argValue: T | undefined,
argType: TypeValue,
globalValidate: ValidateSettings,
argValidate: ValidateSettings | undefined,
): Promise<T | undefined> {
const validate = argValidate !== undefined ? argValidate : globalValidate;
if (validate === false || argValue == null || typeof argValue !== "object") {
if (validate === false || !shouldArgBeValidated(argValue)) {
return argValue;
}

Expand All @@ -32,9 +35,13 @@ export async function validateArg<T extends object>(
const { validateOrReject } = await import("class-validator");
try {
if (Array.isArray(argValue)) {
await Promise.all(argValue.map(argItem => validateOrReject(argItem, validatorOptions)));
await Promise.all(
argValue
.filter(shouldArgBeValidated)
.map(argItem => validateOrReject(argItem, validatorOptions)),
);
} else {
await validateOrReject(argValue, validatorOptions);
await validateOrReject(argValue as T, validatorOptions);
}
return argValue;
} catch (err) {
Expand Down
54 changes: 54 additions & 0 deletions tests/functional/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ describe("Validation", () => {
argInput = inputs;
return {};
}

@Mutation()
mutationWithOptionalInputsArray(
@Arg("inputs", type => [SampleInput], { nullable: "items" })
inputs: Array<SampleInput | null>,
): SampleObject {
argInput = inputs;
return {};
}
}
sampleResolver = SampleResolver;

Expand Down Expand Up @@ -230,6 +239,51 @@ describe("Validation", () => {
expect(validationError.validationErrors[0].property).toEqual("numberField");
});

it("should not throw error when one of optional items in the input array is null", async () => {
const mutation = `mutation {
mutationWithOptionalInputsArray(inputs: [
null,
{
stringField: "12345",
numberField: 5
},
]) {
field
}
}`;

const result = await graphql(schema, mutation);
expect(result.errors).toBeUndefined();
expect(result.data).toEqual({ mutationWithOptionalInputsArray: { field: null } });
});

it("should properly validate arg array when one of optional items in the input array is incorrect", async () => {
const mutation = `mutation {
mutationWithOptionalInputsArray(inputs: [
null,
{
stringField: "12345",
numberField: 5
},
{
stringField: "12345",
numberField: 15,
},
]) {
field
}
}`;

const result = await graphql(schema, mutation);
expect(result.data).toBeNull();
expect(result.errors).toHaveLength(1);

const validationError = result.errors![0].originalError! as ArgumentValidationError;
expect(validationError).toBeInstanceOf(ArgumentValidationError);
expect(validationError.validationErrors).toHaveLength(1);
expect(validationError.validationErrors[0].property).toEqual("numberField");
});

it("should throw validation error when optional input field is incorrect", async () => {
const mutation = `mutation {
sampleMutation(input: {
Expand Down

0 comments on commit 643087b

Please sign in to comment.