From 59fa7abff6ef0e273fe4541b24d986d85e8e6273 Mon Sep 17 00:00:00 2001 From: Tim Leslie Date: Fri, 22 May 2020 12:21:18 +1000 Subject: [PATCH] Re-order tests --- CONTRIBUTING.md | 5 + README.md | 5 + .../nested-mutations/connect-singular.test.js | 258 +++++----- .../nested-mutations/create-singular.test.js | 446 +++++++++--------- docs/api/create-list.md | 1 - 5 files changed, 361 insertions(+), 354 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1f88f0fe68b..a7abbb6ec5e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -275,8 +275,11 @@ We also build commonjs builds to run in node (for testing with jest or etc.) and Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): + + + @@ -339,7 +342,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d

Jed Watson

💻
+ + This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! diff --git a/README.md b/README.md index 4a93cef015e..adf40ecfece 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,11 @@ We'd like to start by thanking all our wonderful contributors: ([emoji key](https://allcontributors.org/docs/en/emoji-key)): + + + @@ -141,7 +144,9 @@ We'd like to start by thanking all our wonderful contributors:

Jed Watson

💻
+ + ### Demo Projects diff --git a/api-tests/relationships/nested-mutations/connect-singular.test.js b/api-tests/relationships/nested-mutations/connect-singular.test.js index 1690f31a0a2..783401a44b8 100644 --- a/api-tests/relationships/nested-mutations/connect-singular.test.js +++ b/api-tests/relationships/nested-mutations/connect-singular.test.js @@ -210,62 +210,58 @@ multiAdapterRunners().map(({ runner, adapterName }) => }); describe('with access control', () => { - [{ name: 'GroupNoRead', func: 'read: () => false' }].forEach(group => { + [{ name: 'GroupNoRead', allowed: false, func: 'read: () => false' }].forEach(group => { describe(`${group.func} on related list`, () => { - test( - 'throws error when linking nested within create mutation', - runner(setupKeystone, async ({ app, create }) => { - const groupName = sampleOne(gen.alphaNumString.notEmpty()); - - // Create an item to link against - const { id } = await create(group.name, { name: groupName }); - - // Create an item that does the linking - const { errors } = await networkedGraphqlRequest({ - app, - query: ` + if (group.allowed) { + test( + 'does not throw error when linking nested within create mutation', + runner(setupKeystone, async ({ app, create }) => { + const groupName = sampleOne(gen.alphaNumString.notEmpty()); + + // Create an item to link against + // We can't use the graphQL query here (it's `create: () => false`) + const { id } = await create(group.name, { name: groupName }); + + // Create an item that does the linking + const { data, errors } = await networkedGraphqlRequest({ + app, + query: ` mutation { createEventTo${group.name}(data: { title: "A thing", group: { connect: { id: "${id}" } } }) { id + group { + id + } } } `, - }); - - expect(errors).toMatchObject([ - { - data: { - errors: expect.arrayContaining([ - expect.objectContaining({ - message: `Unable to connect a EventTo${group.name}.group<${group.name}>`, - }), - ]), - }, - }, - ]); - }) - ); - - test( - 'does not throw error when linking nested within update mutation', - runner(setupKeystone, async ({ app, create }) => { - const groupName = sampleOne(gen.alphaNumString.notEmpty()); - - // Create an item to link against - const groupModel = await create(group.name, { name: groupName }); - expect(groupModel.id).toBeTruthy(); - - // Create an item to update - const eventModel = await create(`EventTo${group.name}`, { title: 'A thing' }); - expect(eventModel.id).toBeTruthy(); - - // Update the item and link the relationship field - const { errors } = await networkedGraphqlRequest({ - app, - query: ` + }); + + expect(data).toMatchObject({ + [`createEventTo${group.name}`]: { id: expect.any(String), group: { id } }, + }); + expect(errors).toBe(undefined); + }) + ); + test( + 'does not throw error when linking nested within update mutation', + runner(setupKeystone, async ({ app, create, findOne, findById }) => { + const groupName = sampleOne(gen.alphaNumString.notEmpty()); + + // Create an item to link against + const groupModel = await create(group.name, { name: groupName }); + + // Create an item to update + const eventModel = await create(`EventTo${group.name}`, { title: 'A Thing' }); + expect(eventModel.id).toBeTruthy(); + + // Update the item and link the relationship field + const { data, errors } = await networkedGraphqlRequest({ + app, + query: ` mutation { updateEventTo${group.name}( id: "${eventModel.id}" @@ -275,79 +271,90 @@ multiAdapterRunners().map(({ runner, adapterName }) => } ) { id + group { + id + name + } } } `, - }); - - expect(errors).toMatchObject([ - { - data: { - errors: expect.arrayContaining([ - expect.objectContaining({ - message: `Unable to connect a EventTo${group.name}.group<${group.name}>`, - }), - ]), - }, - }, - ]); - }) - ); - }); - }); + }); - [{ name: 'GroupNoCreate', func: 'create: () => false' }].forEach(group => { - describe(`${group.func} on related list`, () => { - test( - 'does not throw error when linking nested within create mutation', - runner(setupKeystone, async ({ app, create }) => { - const groupName = sampleOne(gen.alphaNumString.notEmpty()); - - // Create an item to link against - // We can't use the graphQL query here (it's `create: () => false`) - const { id } = await create(group.name, { name: groupName }); - - // Create an item that does the linking - const { data, errors } = await networkedGraphqlRequest({ - app, - query: ` + expect(data).toMatchObject({ + [`updateEventTo${group.name}`]: { + id: expect.any(String), + group: { + id: expect.any(String), + name: groupName, + }, + }, + }); + expect(errors).toBe(undefined); + + // See that it actually stored the group ID on the Event record + const event = await findOne(`EventTo${group.name}`, { title: 'A thing' }); + expect(event).toBeTruthy(); + expect(event.group).toBeTruthy(); + + const _group = await findById(group.name, event.group); + expect(_group).toBeTruthy(); + expect(_group.name).toBe(groupName); + }) + ); + } else { + test( + 'throws error when linking nested within create mutation', + runner(setupKeystone, async ({ app, create }) => { + const groupName = sampleOne(gen.alphaNumString.notEmpty()); + + // Create an item to link against + const { id } = await create(group.name, { name: groupName }); + + // Create an item that does the linking + const { errors } = await networkedGraphqlRequest({ + app, + query: ` mutation { createEventTo${group.name}(data: { title: "A thing", group: { connect: { id: "${id}" } } }) { id - group { - id - } } } `, - }); - - expect(data).toMatchObject({ - [`createEventTo${group.name}`]: { id: expect.any(String), group: { id } }, - }); - expect(errors).toBe(undefined); - }) - ); - - test( - 'does not throw error when linking nested within update mutation', - runner(setupKeystone, async ({ app, create, findOne, findById }) => { - const groupName = sampleOne(gen.alphaNumString.notEmpty()); - - // Create an item to link against - // We can't use the graphQL query here (it's `create: () => false`) - const groupModel = await create(group.name, { name: groupName }); - - // Create an item to update - const eventModel = await create(`EventTo${group.name}`, { title: 'A Thing' }); - - // Update the item and link the relationship field - const { data, errors } = await networkedGraphqlRequest({ - app, - query: ` + }); + + expect(errors).toMatchObject([ + { + data: { + errors: expect.arrayContaining([ + expect.objectContaining({ + message: `Unable to connect a EventTo${group.name}.group<${group.name}>`, + }), + ]), + }, + }, + ]); + }) + ); + test( + 'throws error when linking nested within update mutation', + runner(setupKeystone, async ({ app, create }) => { + const groupName = sampleOne(gen.alphaNumString.notEmpty()); + + // Create an item to link against + const groupModel = await create(group.name, { name: groupName }); + expect(groupModel.id).toBeTruthy(); + + // Create an item to update + const eventModel = await create(`EventTo${group.name}`, { title: 'A thing' }); + expect(eventModel.id).toBeTruthy(); + + // Update the item and link the relationship field + const { errors } = await networkedGraphqlRequest({ + app, + query: ` mutation { updateEventTo${group.name}( id: "${eventModel.id}" @@ -357,36 +364,25 @@ multiAdapterRunners().map(({ runner, adapterName }) => } ) { id - group { - id - name - } } } `, - }); + }); - expect(data).toMatchObject({ - [`updateEventTo${group.name}`]: { - id: expect.any(String), - group: { - id: expect.any(String), - name: groupName, + expect(errors).toMatchObject([ + { + data: { + errors: expect.arrayContaining([ + expect.objectContaining({ + message: `Unable to connect a EventTo${group.name}.group<${group.name}>`, + }), + ]), + }, }, - }, - }); - expect(errors).toBe(undefined); - - // See that it actually stored the group ID on the Event record - const event = await findOne(`EventTo${group.name}`, { title: 'A thing' }); - expect(event).toBeTruthy(); - expect(event.group).toBeTruthy(); - - const _group = await findById(group.name, event.group); - expect(_group).toBeTruthy(); - expect(_group.name).toBe(groupName); - }) - ); + ]); + }) + ); + } }); }); }); diff --git a/api-tests/relationships/nested-mutations/create-singular.test.js b/api-tests/relationships/nested-mutations/create-singular.test.js index 27c67577677..c8874c245f2 100644 --- a/api-tests/relationships/nested-mutations/create-singular.test.js +++ b/api-tests/relationships/nested-mutations/create-singular.test.js @@ -72,19 +72,19 @@ multiAdapterRunners().map(({ runner, adapterName }) => const { data, errors } = await graphqlRequest({ keystone, query: ` - mutation { - createEvent(data: { - title: "A thing", - group: { create: { name: "${groupName}" } } - }) { - id - group { - id - name - } - } - } - `, + mutation { + createEvent(data: { + title: "A thing", + group: { create: { name: "${groupName}" } } + }) { + id + group { + id + name + } + } + } + `, }); expect(errors).toBe(undefined); @@ -103,13 +103,13 @@ multiAdapterRunners().map(({ runner, adapterName }) => } = await graphqlRequest({ keystone, query: ` - query { - Group(where: { id: "${data.createEvent.group.id}" }) { - id - name - } - } - `, + query { + Group(where: { id: "${data.createEvent.group.id}" }) { + id + name + } + } + `, }); expect(Group).toMatchObject({ @@ -131,22 +131,22 @@ multiAdapterRunners().map(({ runner, adapterName }) => const { data, errors } = await graphqlRequest({ keystone, query: ` - mutation { - updateEvent( - id: "${createEvent.id}" - data: { - title: "A thing", - group: { create: { name: "${groupName}" } } - } - ) { - id - group { - id - name - } - } - } - `, + mutation { + updateEvent( + id: "${createEvent.id}" + data: { + title: "A thing", + group: { create: { name: "${groupName}" } } + } + ) { + id + group { + id + name + } + } + } + `, }); expect(errors).toBe(undefined); @@ -165,13 +165,13 @@ multiAdapterRunners().map(({ runner, adapterName }) => } = await graphqlRequest({ keystone, query: ` - query { - Group(where: { id: "${data.updateEvent.group.id}" }) { - id - name - } - } - `, + query { + Group(where: { id: "${data.updateEvent.group.id}" }) { + id + name + } + } + `, }); expect(Group).toMatchObject({ @@ -183,17 +183,21 @@ multiAdapterRunners().map(({ runner, adapterName }) => }); describe('with access control', () => { - [{ name: 'GroupNoRead', func: 'read: () => false' }].forEach(group => { + [ + { name: 'GroupNoRead', allowed: true, func: 'read: () => false' }, + { name: 'GroupNoCreate', allowed: false, func: 'create: () => false' }, + ].forEach(group => { describe(`${group.func} on related list`, () => { - test( - 'does not throw error when creating nested within create mutation', - runner(setupKeystone, async ({ app, findOne, findById }) => { - const groupName = sampleOne(gen.alphaNumString.notEmpty()); - - // Create an item that does the nested create - const { data, errors } = await networkedGraphqlRequest({ - app, - query: ` + if (group.allowed) { + test( + 'does not throw error when creating nested within create mutation', + runner(setupKeystone, async ({ app, findOne, findById }) => { + const groupName = sampleOne(gen.alphaNumString.notEmpty()); + + // Create an item that does the nested create + const { data, errors } = await networkedGraphqlRequest({ + app, + query: ` mutation { createEventTo${group.name}(data: { title: "A thing", @@ -203,36 +207,36 @@ multiAdapterRunners().map(({ runner, adapterName }) => } } `, - }); - - expect(errors).toBe(undefined); - expect(data).toMatchObject({ - [`createEventTo${group.name}`]: { id: expect.any(String) }, - }); - - // See that it actually stored the group ID on the Event record - const event = await findOne(`EventTo${group.name}`, { title: 'A thing' }); - expect(event).toBeTruthy(); - expect(event.group).toBeTruthy(); - - const _group = await findById(group.name, event.group); - expect(_group).toBeTruthy(); - expect(_group.name).toBe(groupName); - }) - ); - - test( - 'does not throw error when creating nested within update mutation', - runner(setupKeystone, async ({ app, create, findOne, findById }) => { - const groupName = sampleOne(gen.alphaNumString.notEmpty()); - - // Create an item to update - const eventModel = await create(`EventTo${group.name}`, { title: 'A thing' }); - - // Update an item that does the nested create - const { data, errors } = await networkedGraphqlRequest({ - app, - query: ` + }); + + expect(errors).toBe(undefined); + expect(data).toMatchObject({ + [`createEventTo${group.name}`]: { id: expect.any(String) }, + }); + + // See that it actually stored the group ID on the Event record + const event = await findOne(`EventTo${group.name}`, { title: 'A thing' }); + expect(event).toBeTruthy(); + expect(event.group).toBeTruthy(); + + const _group = await findById(group.name, event.group); + expect(_group).toBeTruthy(); + expect(_group.name).toBe(groupName); + }) + ); + + test( + 'does not throw error when creating nested within update mutation', + runner(setupKeystone, async ({ app, create, findOne, findById }) => { + const groupName = sampleOne(gen.alphaNumString.notEmpty()); + + // Create an item to update + const eventModel = await create(`EventTo${group.name}`, { title: 'A thing' }); + + // Update an item that does the nested create + const { data, errors } = await networkedGraphqlRequest({ + app, + query: ` mutation { updateEventTo${group.name}( id: "${eventModel.id}" @@ -245,151 +249,149 @@ multiAdapterRunners().map(({ runner, adapterName }) => } } `, - }); - - expect(errors).toBe(undefined); - expect(data).toMatchObject({ - [`updateEventTo${group.name}`]: { id: expect.any(String) }, - }); - - // See that it actually stored the group ID on the Event record - const event = await findOne(`EventTo${group.name}`, { title: 'A thing' }); - expect(event).toBeTruthy(); - expect(event.group).toBeTruthy(); - - const _group = await findById(group.name, event.group); - expect(_group).toBeTruthy(); - expect(_group.name).toBe(groupName); - }) - ); - }); - }); - [{ name: 'GroupNoCreate', func: 'create: () => false' }].forEach(group => { - describe(`${group.func} on related list`, () => { - test( - 'throws error when creating nested within create mutation', - runner(setupKeystone, async ({ keystone, app }) => { - const alphaNumGenerator = gen.alphaNumString.notEmpty(); - const eventName = sampleOne(alphaNumGenerator); - const groupName = sampleOne(alphaNumGenerator); - - // Create an item that does the nested create - const { data, errors } = await networkedGraphqlRequest({ - app, - query: ` - mutation { - createEventTo${group.name}(data: { - title: "${eventName}", - group: { create: { name: "${groupName}" } } - }) { - id - } - } - `, - }); - - // Assert it throws an access denied error - expect(data[`createEventTo${group.name}`]).toBe(null); - expect(errors).toMatchObject([ - { - data: { - errors: expect.arrayContaining([ - expect.objectContaining({ - message: `Unable to create a EventTo${group.name}.group<${group.name}>`, - }), - ]), - }, - }, - ]); - - // Confirm it didn't insert either of the records anyway - const result = await graphqlRequest({ - keystone, - query: ` - query { - all${group.name}s(where: { name: "${groupName}" }) { - id - name - } - } - `, - }); - - expect(result.data[`all${group.name}s`]).toMatchObject([]); - - // Confirm it didn't insert either of the records anyway - const result2 = await graphqlRequest({ - keystone, - query: ` - query { - allEventTo${group.name}s(where: { title: "${eventName}" }) { - id - title - } - } - `, - }); - - expect(result2.data[`allEventTo${group.name}s`]).toMatchObject([]); - }) - ); - - test( - 'throws error when creating nested within update mutation', - runner(setupKeystone, async ({ keystone, app, create }) => { - const groupName = sampleOne(gen.alphaNumString.notEmpty()); - - // Create an item to update - const eventModel = await create(`EventTo${group.name}`, { title: 'A thing' }); + }); + + expect(errors).toBe(undefined); + expect(data).toMatchObject({ + [`updateEventTo${group.name}`]: { id: expect.any(String) }, + }); + + // See that it actually stored the group ID on the Event record + const event = await findOne(`EventTo${group.name}`, { title: 'A thing' }); + expect(event).toBeTruthy(); + expect(event.group).toBeTruthy(); + + const _group = await findById(group.name, event.group); + expect(_group).toBeTruthy(); + expect(_group.name).toBe(groupName); + }) + ); + } else { + test( + 'throws error when creating nested within create mutation', + runner(setupKeystone, async ({ keystone, app }) => { + const alphaNumGenerator = gen.alphaNumString.notEmpty(); + const eventName = sampleOne(alphaNumGenerator); + const groupName = sampleOne(alphaNumGenerator); + + // Create an item that does the nested create + const { data, errors } = await networkedGraphqlRequest({ + app, + query: ` + mutation { + createEventTo${group.name}(data: { + title: "${eventName}", + group: { create: { name: "${groupName}" } } + }) { + id + } + } + `, + }); - // Update an item that does the nested create - const { data, errors } = await networkedGraphqlRequest({ - app, - query: ` - mutation { - updateEventTo${group.name}( - id: "${eventModel.id}" + // Assert it throws an access denied error + expect(data[`createEventTo${group.name}`]).toBe(null); + expect(errors).toMatchObject([ + { data: { - title: "A thing", - group: { create: { name: "${groupName}" } } + errors: expect.arrayContaining([ + expect.objectContaining({ + message: `Unable to create a EventTo${group.name}.group<${group.name}>`, + }), + ]), + }, + }, + ]); + + // Confirm it didn't insert either of the records anyway + const result = await graphqlRequest({ + keystone, + query: ` + query { + all${group.name}s(where: { name: "${groupName}" }) { + id + name + } } - ) { - id - } - } - `, - }); + `, + }); + + expect(result.data[`all${group.name}s`]).toMatchObject([]); + + // Confirm it didn't insert either of the records anyway + const result2 = await graphqlRequest({ + keystone, + query: ` + query { + allEventTo${group.name}s(where: { title: "${eventName}" }) { + id + title + } + } + `, + }); + + expect(result2.data[`allEventTo${group.name}s`]).toMatchObject([]); + }) + ); + + test( + 'throws error when creating nested within update mutation', + runner(setupKeystone, async ({ keystone, app, create }) => { + const groupName = sampleOne(gen.alphaNumString.notEmpty()); + + // Create an item to update + const eventModel = await create(`EventTo${group.name}`, { title: 'A thing' }); + + // Update an item that does the nested create + const { data, errors } = await networkedGraphqlRequest({ + app, + query: ` + mutation { + updateEventTo${group.name}( + id: "${eventModel.id}" + data: { + title: "A thing", + group: { create: { name: "${groupName}" } } + } + ) { + id + } + } + `, + }); - // Assert it throws an access denied error - expect(data[`updateEventTo${group.name}`]).toBe(null); - expect(errors).toMatchObject([ - { - data: { - errors: expect.arrayContaining([ - expect.objectContaining({ - message: `Unable to create a EventTo${group.name}.group<${group.name}>`, - }), - ]), + // Assert it throws an access denied error + expect(data[`updateEventTo${group.name}`]).toBe(null); + expect(errors).toMatchObject([ + { + data: { + errors: expect.arrayContaining([ + expect.objectContaining({ + message: `Unable to create a EventTo${group.name}.group<${group.name}>`, + }), + ]), + }, }, - }, - ]); - - // Confirm it didn't insert the record anyway - const result = await graphqlRequest({ - keystone, - query: ` - query { - all${group.name}s(where: { name: "${groupName}" }) { - id - name - } - } - `, - }); + ]); + + // Confirm it didn't insert the record anyway + const result = await graphqlRequest({ + keystone, + query: ` + query { + all${group.name}s(where: { name: "${groupName}" }) { + id + name + } + } + `, + }); - expect(result.data[`all${group.name}s`]).toMatchObject([]); - }) - ); + expect(result.data[`all${group.name}s`]).toMatchObject([]); + }) + ); + } }); }); }); diff --git a/docs/api/create-list.md b/docs/api/create-list.md index 75e41c11901..c3d8b9e4004 100644 --- a/docs/api/create-list.md +++ b/docs/api/create-list.md @@ -288,7 +288,6 @@ Changes the path in the Admin UI. Updating `plural` and `singular` values will n An array of functions that modify config values. Plugin functions receive `(config, { listKey, keystone })`, where `config` is the a list config object, `listKey` is the name of the list, and `keystone` is the keystone object. They should return a valid list config. Plugin functions are executed in the order provided in the list, with the output config of one being passed as input to the next. The output of the final plugin is used to construct the `List` instance. - ```javascript const setupUserList = ({ fields, ...config }) => { return {