From 199012ff3765acd666d9a0e9962d69b8bced20c5 Mon Sep 17 00:00:00 2001 From: Miles Douglas Date: Thu, 24 Sep 2020 17:06:23 -0400 Subject: [PATCH] Update include introspection logic --- packages/ra-data-graphql/src/introspection.js | 39 +++++++----- .../ra-data-graphql/src/introspection.test.js | 61 ++++++++++++------- 2 files changed, 61 insertions(+), 39 deletions(-) diff --git a/packages/ra-data-graphql/src/introspection.js b/packages/ra-data-graphql/src/introspection.js index 261c2883a78..6ba789cd618 100644 --- a/packages/ra-data-graphql/src/introspection.js +++ b/packages/ra-data-graphql/src/introspection.js @@ -4,24 +4,28 @@ import { GET_LIST, GET_ONE } from 'ra-core'; import { ALL_TYPES } from './constants'; -export const filterTypesByIncludeExclude = ({ include, exclude }) => { +export const isResourceIncluded = ({ include, type }) => { if (Array.isArray(include)) { - return type => include.includes(type.name); + return include.includes(type.name); } if (typeof include === 'function') { - return type => include(type); + return include(type); } + return false; +}; + +export const isResourceExcluded = ({ exclude, type }) => { if (Array.isArray(exclude)) { - return type => !exclude.includes(type.name); + return exclude.includes(type.name); } if (typeof exclude === 'function') { - return type => !exclude(type); + return exclude(type); } - return () => true; + return false; }; /** @@ -56,13 +60,19 @@ export default async (client, options) => { type.name !== (schema.mutationType && schema.mutationType.name) ); - const isResource = type => - queries.some( - query => query.name === options.operationNames[GET_LIST](type) - ) && - queries.some( - query => query.name === options.operationNames[GET_ONE](type) + const isResource = type => { + if (isResourceIncluded({ type, ...options })) return true; + if (isResourceExcluded({ type, ...options })) return false; + + return ( + queries.some( + query => query.name === options.operationNames[GET_LIST](type) + ) && + queries.some( + query => query.name === options.operationNames[GET_ONE](type) + ) ); + }; const buildResource = type => ALL_TYPES.reduce( @@ -78,10 +88,7 @@ export default async (client, options) => { { type } ); - const potentialResources = types.filter(isResource); - const filteredResources = potentialResources.filter( - filterTypesByIncludeExclude(options) - ); + const filteredResources = types.filter(isResource); const resources = filteredResources.map(buildResource); return { diff --git a/packages/ra-data-graphql/src/introspection.test.js b/packages/ra-data-graphql/src/introspection.test.js index ff253e6b61c..867a1a358b1 100644 --- a/packages/ra-data-graphql/src/introspection.test.js +++ b/packages/ra-data-graphql/src/introspection.test.js @@ -1,5 +1,6 @@ import resolveIntrospection, { - filterTypesByIncludeExclude, + isResourceExcluded, + isResourceIncluded, } from './introspection'; import { GET_LIST, @@ -12,64 +13,78 @@ import { } from 'ra-core'; describe('introspection', () => { - describe('filterTypesByIncludeExclude', () => { + describe('isResourceIncluded', () => { it('return false with an include option containing an array and tested type is not in it', () => { expect( - filterTypesByIncludeExclude({ include: ['Post', 'Comment'] })({ - name: 'NotMe', + isResourceIncluded({ + include: ['Post', 'Comment'], + type: { + name: 'NotMe', + }, }) ).toBe(false); }); it('return true with an include option containing an array and tested type is in it', () => { expect( - filterTypesByIncludeExclude({ include: ['Post', 'Comment'] })({ - name: 'Post', + isResourceIncluded({ + include: ['Post', 'Comment'], + type: { + name: 'Post', + }, }) ).toBe(true); }); - it('return false with an exclude option containing an array and tested type is in it', () => { + it('return false with an include option containing an array and tested type is not in it', () => { expect( - filterTypesByIncludeExclude({ exclude: ['NotMe'] })({ - name: 'NotMe', + isResourceIncluded({ + include: ['NotMe'], + type: { + name: 'Post', + }, }) ).toBe(false); }); - it('return true with an include option containing an array and tested type is not in it', () => { - expect( - filterTypesByIncludeExclude({ exclude: ['NotMe'] })({ - name: 'Post', - }) - ).toBe(true); - }); - it('return true with an include option being a function returning true', () => { const include = jest.fn(() => true); const type = { name: 'Post' }; - expect(filterTypesByIncludeExclude({ include })(type)).toBe(true); + expect(isResourceIncluded({ include, type })).toBe(true); expect(include).toHaveBeenCalledWith(type); }); it('return false with an include option being a function returning false', () => { const include = jest.fn(() => false); const type = { name: 'Post' }; - expect(filterTypesByIncludeExclude({ include })(type)).toBe(false); + expect(isResourceIncluded({ include, type })).toBe(false); expect(include).toHaveBeenCalledWith(type); }); + }); + + describe('isResourceExcluded', () => { + it('return true with an exclude option containing an array and tested type is in it', () => { + expect( + isResourceExcluded({ + exclude: ['NotMe'], + type: { + name: 'NotMe', + }, + }) + ).toBe(true); + }); - it('return false with an exclude option being a function returning true', () => { + it('return true with an exclude option being a function returning true', () => { const exclude = jest.fn(() => true); const type = { name: 'Post' }; - expect(filterTypesByIncludeExclude({ exclude })(type)).toBe(false); + expect(isResourceExcluded({ exclude, type })).toBe(true); expect(exclude).toHaveBeenCalledWith(type); }); - it('return true with an exclude option being a function returning false', () => { + it('return false with an exclude option being a function returning false', () => { const exclude = jest.fn(() => false); const type = { name: 'Post' }; - expect(filterTypesByIncludeExclude({ exclude })(type)).toBe(true); + expect(isResourceExcluded({ exclude, type })).toBe(false); expect(exclude).toHaveBeenCalledWith(type); }); });