diff --git a/packages/fetchye-core/__tests__/defaultFetcher.spec.js b/packages/fetchye-core/__tests__/defaultFetcher.spec.js index c37c09e..54f9642 100644 --- a/packages/fetchye-core/__tests__/defaultFetcher.spec.js +++ b/packages/fetchye-core/__tests__/defaultFetcher.spec.js @@ -40,7 +40,6 @@ describe('defaultFetcher', () => { 'Content-Type': 'application/json', }), })); - // write a mock for jsonToGraphQLQuery jsonToGraphQLQuery.mockImplementationOnce(() => 'jsonToGraphQLQueryMock'); trimQueryBody.mockImplementationOnce(() => 'trimQueryBodyMock'); const data = await defaultFetcher(fetchClient, 'http://example.com', { @@ -75,7 +74,6 @@ describe('defaultFetcher', () => { 'Content-Type': 'application/json', }), })); - // write a mock for jsonToGraphQLQuery jsonToGraphQLQuery.mockImplementationOnce(() => 'jsonToGraphQLQueryMock'); trimQueryBody.mockImplementationOnce(() => 'trimQueryBodyMock'); const data = await defaultFetcher(fetchClient, 'http://example.com', { @@ -97,7 +95,6 @@ describe('defaultFetcher', () => { }, } `); - expect(jsonToGraphQLQuery).toHaveBeenCalledWith(undefined, { pretty: true }); }); it('should handle graphql query with existing query', async () => { const fetchClient = jest.fn(async () => ({ @@ -108,7 +105,6 @@ describe('defaultFetcher', () => { 'Content-Type': 'application/json', }), })); - // write a mock for jsonToGraphQLQuery jsonToGraphQLQuery.mockImplementationOnce(() => 'jsonToGraphQLQueryMock'); trimQueryBody.mockImplementationOnce(() => 'trimQueryBodyMock'); const data = await defaultFetcher(fetchClient, 'http://example.com', { @@ -146,7 +142,6 @@ describe('defaultFetcher', () => { 'Content-Type': 'application/json', }), })); - // write a mock for jsonToGraphQLQuery jsonToGraphQLQuery.mockImplementationOnce(() => 'jsonToGraphQLQueryMock'); trimQueryBody.mockImplementationOnce(() => 'trimQueryBodyMock'); const data = await defaultFetcher(fetchClient, 'http://example.com', { @@ -169,8 +164,6 @@ describe('defaultFetcher', () => { }, } `); - expect(jsonToGraphQLQuery).toHaveBeenCalledWith('trimQueryBodyMock', { pretty: true }); - expect(trimQueryBody).toHaveBeenCalledWith(undefined, 'existingQueryMock'); }); it('should return payload and undefined error when status 200', async () => { diff --git a/packages/fetchye-core/__tests__/trimOptions.spec.js b/packages/fetchye-core/__tests__/trimOptions.spec.js new file mode 100644 index 0000000..f666e44 --- /dev/null +++ b/packages/fetchye-core/__tests__/trimOptions.spec.js @@ -0,0 +1,38 @@ +import { jsonToGraphQLQuery } from 'json-to-graphql-query'; +import { trimOptions } from '../src/trimOptions'; +import { trimQueryBody } from '../src/trimQueryBody'; + +jest.mock('json-to-graphql-query', () => ({ + jsonToGraphQLQuery: jest.fn(), +})); +jest.mock('../src/trimQueryBody', () => ({ + trimQueryBody: jest.fn(), +})); + +describe('trimOptions', () => { + it('should return options if isGraphQL is false', () => { + const options = { isGraphQL: false }; + expect(trimOptions(options)).toEqual(options); + }); + it('should return options if isGraphQL is true and existingQuery is not provided', () => { + const options = { isGraphQL: true, body: { query: 'query' } }; + jsonToGraphQLQuery.mockImplementation((value) => value); + const expectedBody = JSON.stringify({ + query: 'query', + }); + expect(trimOptions(options)).toEqual({ ...options, body: expectedBody }); + }); + it('should return options with trimmed query if isGraphQL is true and existingQuery is provided', () => { + const options = { isGraphQL: true, existingQuery: 'existingQuery', body: { query: 'query' } }; + const trimmedQuery = 'trimmedQuery'; + trimQueryBody.mockReturnValue(trimmedQuery); + jsonToGraphQLQuery.mockImplementation((value) => value); + const expectedBody = JSON.stringify({ + query: 'trimmedQuery', + }); + expect(trimOptions(options)).toEqual({ ...options, body: expectedBody }); + }); + it('should handle if options is not provided', () => { + expect(trimOptions()).toEqual(undefined); + }); +}); diff --git a/packages/fetchye-core/__tests__/trimQueryBody.spec.js b/packages/fetchye-core/__tests__/trimQueryBody.spec.js index ad2811c..7503371 100644 --- a/packages/fetchye-core/__tests__/trimQueryBody.spec.js +++ b/packages/fetchye-core/__tests__/trimQueryBody.spec.js @@ -7,28 +7,6 @@ describe('trimQueryBody', () => { beforeEach(() => { jest.resetAllMocks(); }); - it('should return empty object if __args are different', () => { - deepEqual.mockImplementationOnce(() => false); - const newQuery = { - __args: { a: 1 }, - }; - const existingQuery = { - __args: { a: 2 }, - }; - const result = trimQueryBody(newQuery, existingQuery); - expect(result).toEqual({}); - }); - it('should return empty object if __name are different', () => { - deepEqual.mockImplementationOnce(() => false); - const newQuery = { - __name: 'a', - }; - const existingQuery = { - __name: 'b', - }; - const result = trimQueryBody(newQuery, existingQuery); - expect(result).toEqual({}); - }); it('should return empty object if key is not in existingQuery', () => { deepEqual.mockImplementationOnce(() => true); const newQuery = { @@ -180,6 +158,7 @@ describe('trimQueryBody', () => { const newQuery = { a: { b: { + c: 1, }, }, }; diff --git a/packages/fetchye-core/src/defaultFetcher.js b/packages/fetchye-core/src/defaultFetcher.js index 85b8e65..27f20f6 100644 --- a/packages/fetchye-core/src/defaultFetcher.js +++ b/packages/fetchye-core/src/defaultFetcher.js @@ -14,8 +14,7 @@ * permissions and limitations under the License. */ -import { jsonToGraphQLQuery } from 'json-to-graphql-query'; -import { trimQueryBody } from './trimQueryBody'; +import { trimOptions } from './trimOptions'; // Object.fromEntries is not compatible with Node v10 // provide our own lightweight solution @@ -24,48 +23,13 @@ export const headersToObject = (headers = []) => [...headers] acc[key] = value; return acc; }, {}); -export const defaultFetcher = async (fetchClient, key, options) => { - let trimmedOptions; +export const defaultFetcher = async (fetchClient, key, initialOptions) => { let res; let payload; let error; - const { existingQuery, isGraphQL } = options || {}; - - if (existingQuery && isGraphQL) { - const { - body, - ...restOfOptions - } = options; - const { - query, - ...restOfBody - } = body || {}; - trimmedOptions = { - ...restOfOptions, - body: JSON.stringify({ - query: jsonToGraphQLQuery(trimQueryBody(query, existingQuery), { pretty: true }), - ...restOfBody, - }), - }; - } else if (isGraphQL) { - const { - body, - ...restOfOptions - } = options; - const { - query, - ...restOfBody - } = body || {}; - trimmedOptions = { - ...restOfOptions, - body: JSON.stringify({ - query: jsonToGraphQLQuery(query, { pretty: true }), - ...restOfBody, - }), - }; - } + const options = trimOptions(initialOptions); try { - res = await fetchClient(key, trimmedOptions || options); + res = await fetchClient(key, options); let body = await res.text(); try { body = JSON.parse(body); diff --git a/packages/fetchye-core/src/trimOptions.js b/packages/fetchye-core/src/trimOptions.js new file mode 100644 index 0000000..8d28450 --- /dev/null +++ b/packages/fetchye-core/src/trimOptions.js @@ -0,0 +1,34 @@ +import { jsonToGraphQLQuery } from 'json-to-graphql-query'; +import { trimQueryBody } from './trimQueryBody'; + +export const trimOptions = (options) => { + const { existingQuery, isGraphQL } = options || {}; + const { + body: requestBody, + ...restOfOptions + } = options || {}; + const { + query, + ...restOfBody + } = requestBody || {}; + + if (isGraphQL && query && existingQuery) { + return { + ...restOfOptions, + body: JSON.stringify({ + query: jsonToGraphQLQuery(trimQueryBody(query, existingQuery), { pretty: true }), + ...restOfBody, + }), + }; + } + if (isGraphQL && query) { + return { + ...restOfOptions, + body: JSON.stringify({ + query: jsonToGraphQLQuery(query, { pretty: true }), + ...restOfBody, + }), + }; + } + return options; +}; diff --git a/packages/fetchye-core/src/trimQueryBody.js b/packages/fetchye-core/src/trimQueryBody.js index 159c539..38fb68c 100644 --- a/packages/fetchye-core/src/trimQueryBody.js +++ b/packages/fetchye-core/src/trimQueryBody.js @@ -1,23 +1,13 @@ -import deepEqual from 'deep-equal'; +const graphQLTerms = ['__args', '__name', '__aliasFor', '__variables', '__directives', '__all_on', '__on', '__typeName', 'mutation']; export const trimQueryBody = (newQuery, existingQuery) => { const trimmedQuery = {}; - // eslint-disable-next-line dot-notation -- __args and __name are special keys - if (newQuery['__args'] && existingQuery['__args'] && !deepEqual(newQuery['__args'], existingQuery['__args'])) { - return trimmedQuery; - } - // eslint-disable-next-line dot-notation -- __args and __name are special keys - if (newQuery['__name'] && existingQuery['__name'] && !deepEqual(newQuery['__name'], existingQuery['__name'])) { - return trimmedQuery; - } Object.keys(newQuery).forEach((key) => { if (newQuery[key] && !existingQuery[key]) { trimmedQuery[key] = newQuery[key]; - } - if (key === '__args' || key === '__name') { + } else if (graphQLTerms.indexOf(key) > -1) { trimmedQuery[key] = newQuery[key]; - } - if (typeof newQuery[key] === 'object' && !Array.isArray(newQuery[key]) && newQuery[key] !== null) { + } else if (typeof newQuery[key] === 'object' && !Array.isArray(newQuery[key]) && newQuery[key] !== null) { const cutQueryObject = trimQueryBody(newQuery[key], existingQuery[key]); const { __args, __name, ...rest diff --git a/packages/fetchye/src/getGraphQLArgs.js b/packages/fetchye/src/getGraphQLArgs.js index 1daa7bb..a9bbf4a 100644 --- a/packages/fetchye/src/getGraphQLArgs.js +++ b/packages/fetchye/src/getGraphQLArgs.js @@ -1,7 +1,9 @@ +const graphQLTerms = ['__args', '__name', '__aliasFor', '__variables', '__directives', '__all_on', '__on', '__typeName', 'mutation']; + export const getGraphQLArgs = (query, args = []) => { let argsList = [...args]; Object.keys(query).forEach((key) => { - if (key === '__args' || key === '__name') { + if (graphQLTerms.indexOf(key) > -1) { argsList.push({ [key]: query[key] }); } if (typeof query[key] === 'object' && !Array.isArray(query[key]) && query[key] !== null) {