Skip to content

Commit

Permalink
TEST For query and mutation input and output validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Devorein committed Jul 24, 2020
1 parent e2d1b88 commit f05da44
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 6 deletions.
11 changes: 7 additions & 4 deletions src/generateQueryTypedefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,14 @@ module.exports = function (Schema) {
auths.forEach((auth) => {
const parts = Object.keys(query[range][auth]).filter((part) => query[range][auth][part] !== false);
parts.forEach((part) => {
let output = `[${S.capitalize(auth)}${cr}Type!]!`;
if (range === 'paginated' && part === 'nameandid') output = '[NameAndId!]!';
else if (range === 'filtered' && part === 'nameandid') output = '[NameAndId!]!';
else if (range === 'id' && part === 'nameandid') output = 'NameAndId!';
let output = `${S.capitalize(auth)}${cr}Type!`;
output = range !== 'id' ? `[${output}]!` : output;
if (part === 'nameandid') {
if (range.match(/(paginated|filtered|all)/)) output = '[NameAndId!]!';
else if (range === 'id') output = 'NameAndId!';
}
if (part === 'count') output = 'NonNegativeInt!';

node.fields.push({
name: `get${S.capitalize(range)}${S.capitalize(auth)}${cpr}${S.capitalize(part)}`,
type: output,
Expand Down
16 changes: 15 additions & 1 deletion tests/unit/mongql.mutation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@ const Mongql = require('../../src/MonGql');

const { setNestedProps, mixObjectProp, flattenObject, matchFlattenedObjProps } = require('../../utils/objManip');
const { mutation: { options: MutationOptions, fields: MutationFields } } = require('../../utils/generateOptions');
const { argumentsToString, outputToString } = require('../../utils/AST/transformASTToString');

const mutationOpts = [];

const MutationMap = {
createUser: [ 'data:UserInput!', 'SelfUserType!' ],
createUsers: [ 'data:[UserInput!]!', '[SelfUserType!]!' ],
updateUser: [ 'data:UserInput!,id:ID!', 'SelfUserType!' ],
updateUsers: [ 'data:[UserInput!]!,ids:[ID!]!', '[SelfUserType!]!' ],
deleteUser: [ 'id:ID!', 'SelfUserType!' ],
deleteUsers: [ 'ids:[ID!]!', '[SelfUserType!]!' ]
};

Array.prototype.diff = function (a) {
return this.filter((i) => a.indexOf(i) < 0);
};
Expand All @@ -33,7 +43,11 @@ function MutationChecker (target, { field, excludedMutation }, type) {
fields.forEach((field) => {
const [ action, part ] = field.split('.');
const typename = `${action}${part === 'multi' ? 'Users' : 'User'}`;
expect(type === 'typedef' ? target.hasField(typename) : Boolean(target[typename])).toBe(against);
if (type === 'typedef') {
expect(target.hasField(typename)).toBe(against);
if (against) expect(MutationMap[typename][0]).toBe(argumentsToString(target.getField(typename).node.arguments));
if (against) expect(MutationMap[typename][1]).toBe(outputToString(target.getField(typename).node.type));
} else expect(Boolean(target[typename])).toBe(against);
});
}
if (field === 'mutation' && type === 'typedef') expect(documentApi().addSDL(target).hasExt('Mutation')).toBe(false);
Expand Down
42 changes: 41 additions & 1 deletion tests/unit/mongql.query.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,43 @@ const Mongql = require('../../src/MonGql');

const { setNestedProps, mixObjectProp, flattenObject, matchFlattenedObjProps } = require('../../utils/objManip');
const { query: { options: QueryOptions, fields: QueryFields } } = require('../../utils/generateOptions');
const { argumentsToString, outputToString } = require('../../utils/AST/transformASTToString');

const queryOpts = [];

const QueryArgs = {
getAllSelfUsersWhole: [ '', '[SelfUserType!]!' ],
getAllSelfUsersNameandid: [ '', '[NameAndId!]!' ],
getAllSelfUsersCount: [ '', 'NonNegativeInt!' ],
getAllOthersUsersWhole: [ '', '[OthersUserType!]!' ],
getAllOthersUsersNameandid: [ '', '[NameAndId!]!' ],
getAllOthersUsersCount: [ '', 'NonNegativeInt!' ],
getAllMixedUsersWhole: [ '', '[MixedUserType!]!' ],
getAllMixedUsersNameandid: [ '', '[NameAndId!]!' ],
getAllMixedUsersCount: [ '', 'NonNegativeInt!' ],
getPaginatedSelfUsersWhole: [ 'pagination:PaginationInput!', '[SelfUserType!]!' ],
getPaginatedSelfUsersNameandid: [ 'pagination:PaginationInput!', '[NameAndId!]!' ],
getPaginatedOthersUsersWhole: [ 'pagination:PaginationInput!', '[OthersUserType!]!' ],
getPaginatedOthersUsersNameandid: [ 'pagination:PaginationInput!', '[NameAndId!]!' ],
getPaginatedMixedUsersWhole: [ 'pagination:PaginationInput!', '[MixedUserType!]!' ],
getPaginatedMixedUsersNameandid: [ 'pagination:PaginationInput!', '[NameAndId!]!' ],
getFilteredSelfUsersWhole: [ 'filter:JSON', '[SelfUserType!]!' ],
getFilteredSelfUsersNameandid: [ 'filter:JSON', '[NameAndId!]!' ],
getFilteredSelfUsersCount: [ 'filter:JSON', 'NonNegativeInt!' ],
getFilteredOthersUsersWhole: [ 'filter:JSON', '[OthersUserType!]!' ],
getFilteredOthersUsersNameandid: [ 'filter:JSON', '[NameAndId!]!' ],
getFilteredOthersUsersCount: [ 'filter:JSON', 'NonNegativeInt!' ],
getFilteredMixedUsersWhole: [ 'filter:JSON', '[MixedUserType!]!' ],
getFilteredMixedUsersNameandid: [ 'filter:JSON', '[NameAndId!]!' ],
getFilteredMixedUsersCount: [ 'filter:JSON', 'NonNegativeInt!' ],
getIdSelfUsersWhole: [ 'id:ID!', 'SelfUserType!' ],
getIdSelfUsersNameandid: [ 'id:ID!', 'NameAndId!' ],
getIdOthersUsersWhole: [ 'id:ID!', 'OthersUserType!' ],
getIdOthersUsersNameandid: [ 'id:ID!', 'NameAndId!' ],
getIdMixedUsersWhole: [ 'id:ID!', 'MixedUserType!' ],
getIdMixedUsersNameandid: [ 'id:ID!', 'NameAndId!' ]
};

Array.prototype.diff = function (a) {
return this.filter((i) => a.indexOf(i) < 0);
};
Expand All @@ -34,7 +68,13 @@ function QueryChecker (target, { field, excludedQuery }, type) {
fields.forEach((field) => {
const [ range, auth, part ] = field.split('.');
const typename = `get${S.capitalize(range)}${S.capitalize(auth)}Users${S.capitalize(part)}`;
expect(type === 'typedef' ? target.hasField(typename) : Boolean(target[typename])).toBe(against);
if (type === 'typedef') {
expect(target.hasField(typename)).toBe(against);
if (against) {
expect(QueryArgs[typename][0]).toBe(argumentsToString(target.getField(typename).node.arguments));
expect(QueryArgs[typename][1]).toBe(outputToString(target.getField(typename).node.type));
}
} else expect(Boolean(target[typename])).toBe(against);
});
}
if (field === 'query' && type === 'typedef') expect(documentApi().addSDL(target).hasExt('Query')).toBe(false);
Expand Down
42 changes: 42 additions & 0 deletions utils/AST/transformASTToString.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const { isPOJO } = require('../objManip');

function traverseType (type) {
const types = [];
function _wrapper (ast) {
if (ast !== undefined) {
const { type, kind, name } = ast;
if (kind !== 'NamedType') types.push(_wrapper(type));
return { type, kind, name };
} else return undefined;
}
types.push(_wrapper(type));
return types;
}

function convertToString (args) {
const name = args[0].name.value;
let res = name;
for (let i = 1; i < args.length; i++) {
const arg = args[i];
if (arg.kind === 'NonNullType') res = `${res}!`;
else if (arg.kind === 'ListType') res = `[${res}]`;
}
return res;
}

module.exports = {
argumentsToString (argAst) {
const args = [];
if (argAst)
argAst.forEach((arg) => {
let name = arg.name.value;
name = isPOJO(name) ? name.name : name;
const argStr = convertToString(traverseType(arg.type));
args.push(`${name}:${argStr}`);
});
return args.join(',');
},
outputToString (outputAst) {
return convertToString(traverseType(outputAst));
}
};

0 comments on commit f05da44

Please sign in to comment.