| 
									
										
										
										
											2023-02-11 21:59:58 +01:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Helpers.
 | 
					
						
							|  |  |  | const { pick } = require('lodash/fp'); | 
					
						
							| 
									
										
										
										
											2023-04-05 10:32:20 +02:00
										 |  |  | const { createTestBuilder } = require('api-tests/builder'); | 
					
						
							|  |  |  | const { createStrapiInstance } = require('api-tests/strapi'); | 
					
						
							|  |  |  | const { createAuthRequest } = require('api-tests/request'); | 
					
						
							| 
									
										
										
										
											2023-02-11 21:59:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | const builder = createTestBuilder(); | 
					
						
							|  |  |  | let strapi; | 
					
						
							|  |  |  | let rq; | 
					
						
							|  |  |  | let graphqlQuery; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Utils
 | 
					
						
							|  |  |  | const selectFields = pick(['name']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const documentModel = { | 
					
						
							|  |  |  |   attributes: { | 
					
						
							|  |  |  |     name: { | 
					
						
							|  |  |  |       type: 'richtext', | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   draftAndPublish: true, | 
					
						
							|  |  |  |   singularName: 'document', | 
					
						
							|  |  |  |   pluralName: 'documents', | 
					
						
							|  |  |  |   displayName: 'Document', | 
					
						
							|  |  |  |   description: '', | 
					
						
							|  |  |  |   collectionName: '', | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const labelModel = { | 
					
						
							|  |  |  |   attributes: { | 
					
						
							|  |  |  |     name: { | 
					
						
							|  |  |  |       type: 'richtext', | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     documents: { | 
					
						
							|  |  |  |       type: 'relation', | 
					
						
							|  |  |  |       relation: 'manyToMany', | 
					
						
							|  |  |  |       target: 'api::document.document', | 
					
						
							|  |  |  |       targetAttribute: 'labels', | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   singularName: 'label', | 
					
						
							|  |  |  |   pluralName: 'labels', | 
					
						
							|  |  |  |   displayName: 'Label', | 
					
						
							|  |  |  |   description: '', | 
					
						
							|  |  |  |   collectionName: '', | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const labels = [{ name: 'label 1' }, { name: 'label 2' }]; | 
					
						
							|  |  |  | const documents = ({ label: labels }) => { | 
					
						
							|  |  |  |   const labelIds = labels.map((label) => label.id); | 
					
						
							|  |  |  |   return [ | 
					
						
							|  |  |  |     { name: 'document 1', labels: labelIds }, | 
					
						
							|  |  |  |     { name: 'document 2', labels: labelIds }, | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('Test Graphql Relations with Draft and Publish enabled', () => { | 
					
						
							|  |  |  |   const data = { | 
					
						
							|  |  |  |     labels: [], | 
					
						
							|  |  |  |     documents: [], | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   beforeAll(async () => { | 
					
						
							|  |  |  |     await builder | 
					
						
							|  |  |  |       .addContentTypes([documentModel, labelModel]) | 
					
						
							|  |  |  |       .addFixtures(labelModel.singularName, labels) | 
					
						
							|  |  |  |       .addFixtures(documentModel.singularName, documents) | 
					
						
							|  |  |  |       .build(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     strapi = await createStrapiInstance(); | 
					
						
							|  |  |  |     rq = await createAuthRequest({ strapi }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     graphqlQuery = (body) => { | 
					
						
							|  |  |  |       return rq({ | 
					
						
							|  |  |  |         url: '/graphql', | 
					
						
							|  |  |  |         method: 'POST', | 
					
						
							|  |  |  |         body, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   afterAll(async () => { | 
					
						
							|  |  |  |     await strapi.destroy(); | 
					
						
							|  |  |  |     await builder.cleanup(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('Test relations features', () => { | 
					
						
							|  |  |  |     test('List labels', async () => { | 
					
						
							|  |  |  |       const res = await graphqlQuery({ | 
					
						
							|  |  |  |         query: /* GraphQL */ `
 | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             labels { | 
					
						
							|  |  |  |               data { | 
					
						
							|  |  |  |                 id | 
					
						
							|  |  |  |                 attributes { | 
					
						
							|  |  |  |                   name | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { body } = res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(res.statusCode).toBe(200); | 
					
						
							|  |  |  |       expect(body).toMatchObject({ | 
					
						
							|  |  |  |         data: { | 
					
						
							|  |  |  |           labels: { | 
					
						
							|  |  |  |             data: labels.map((label) => ({ id: expect.any(String), attributes: label })), | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // assign for later use
 | 
					
						
							|  |  |  |       data.labels = data.labels.concat(res.body.data.labels.data); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test('List preview documents with labels', async () => { | 
					
						
							|  |  |  |       const res = await graphqlQuery({ | 
					
						
							|  |  |  |         query: /* GraphQL */ `
 | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             documents(publicationState: PREVIEW) { | 
					
						
							|  |  |  |               data { | 
					
						
							|  |  |  |                 id | 
					
						
							|  |  |  |                 attributes { | 
					
						
							|  |  |  |                   name | 
					
						
							|  |  |  |                   labels { | 
					
						
							|  |  |  |                     data { | 
					
						
							|  |  |  |                       id | 
					
						
							|  |  |  |                       attributes { | 
					
						
							|  |  |  |                         name | 
					
						
							|  |  |  |                       } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { body } = res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(res.statusCode).toBe(200); | 
					
						
							|  |  |  |       expect(body).toMatchObject({ | 
					
						
							|  |  |  |         data: { | 
					
						
							|  |  |  |           documents: { | 
					
						
							|  |  |  |             data: expect.arrayContaining(data.documents), | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // assign for later use
 | 
					
						
							|  |  |  |       data.documents = res.body.data.documents.data; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test('Publish document', async () => { | 
					
						
							|  |  |  |       const res = await graphqlQuery({ | 
					
						
							|  |  |  |         query: /* GraphQL */ `
 | 
					
						
							|  |  |  |           mutation publishDocument($id: ID!, $data: DocumentInput!) { | 
					
						
							|  |  |  |             updateDocument(id: $id, data: $data) { | 
					
						
							|  |  |  |               data { | 
					
						
							|  |  |  |                 id | 
					
						
							|  |  |  |                 attributes { | 
					
						
							|  |  |  |                   name | 
					
						
							|  |  |  |                   publishedAt | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         variables: { | 
					
						
							|  |  |  |           id: data.documents[0].id, | 
					
						
							|  |  |  |           data: { | 
					
						
							|  |  |  |             publishedAt: new Date().toISOString(), | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { body } = res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(res.statusCode).toBe(200); | 
					
						
							|  |  |  |       expect(body).toMatchObject({ | 
					
						
							|  |  |  |         data: { | 
					
						
							|  |  |  |           updateDocument: { | 
					
						
							|  |  |  |             data: { | 
					
						
							|  |  |  |               id: data.documents[0].id, | 
					
						
							|  |  |  |               attributes: { | 
					
						
							|  |  |  |                 name: data.documents[0].attributes.name, | 
					
						
							|  |  |  |                 publishedAt: expect.any(String), | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test('List labels with live documents', async () => { | 
					
						
							|  |  |  |       const res = await graphqlQuery({ | 
					
						
							|  |  |  |         query: /* GraphQL */ `
 | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             labels { | 
					
						
							|  |  |  |               data { | 
					
						
							|  |  |  |                 id | 
					
						
							|  |  |  |                 attributes { | 
					
						
							|  |  |  |                   name | 
					
						
							|  |  |  |                   documents { | 
					
						
							|  |  |  |                     data { | 
					
						
							|  |  |  |                       id | 
					
						
							|  |  |  |                       attributes { | 
					
						
							|  |  |  |                         name | 
					
						
							|  |  |  |                         publishedAt | 
					
						
							|  |  |  |                       } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { body } = res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(res.statusCode).toBe(200); | 
					
						
							|  |  |  |       expect(body).toMatchObject({ | 
					
						
							|  |  |  |         data: { | 
					
						
							|  |  |  |           labels: { | 
					
						
							|  |  |  |             data: expect.arrayContaining( | 
					
						
							|  |  |  |               data.labels.map((label) => ({ | 
					
						
							|  |  |  |                 id: label.id, | 
					
						
							|  |  |  |                 attributes: { | 
					
						
							|  |  |  |                   ...label.attributes, | 
					
						
							|  |  |  |                   documents: { | 
					
						
							|  |  |  |                     data: expect.arrayContaining( | 
					
						
							|  |  |  |                       // Only the first document is published
 | 
					
						
							|  |  |  |                       data.documents.slice(0, 1).map((document) => ({ | 
					
						
							|  |  |  |                         id: document.id, | 
					
						
							|  |  |  |                         attributes: { | 
					
						
							|  |  |  |                           ...selectFields(document.attributes), | 
					
						
							|  |  |  |                           publishedAt: expect.any(String), | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                       })) | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                   }, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |               })) | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test('List labels with preview documents', async () => { | 
					
						
							|  |  |  |       const res = await graphqlQuery({ | 
					
						
							|  |  |  |         query: /* GraphQL */ `
 | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             labels { | 
					
						
							|  |  |  |               data { | 
					
						
							|  |  |  |                 id | 
					
						
							|  |  |  |                 attributes { | 
					
						
							|  |  |  |                   name | 
					
						
							|  |  |  |                   documents(publicationState: PREVIEW) { | 
					
						
							|  |  |  |                     data { | 
					
						
							|  |  |  |                       id | 
					
						
							|  |  |  |                       attributes { | 
					
						
							|  |  |  |                         name | 
					
						
							|  |  |  |                       } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { body } = res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(res.statusCode).toBe(200); | 
					
						
							|  |  |  |       expect(body).toMatchObject({ | 
					
						
							|  |  |  |         data: { | 
					
						
							|  |  |  |           labels: { | 
					
						
							|  |  |  |             data: expect.arrayContaining( | 
					
						
							|  |  |  |               data.labels.map((label) => ({ | 
					
						
							|  |  |  |                 id: label.id, | 
					
						
							|  |  |  |                 attributes: { | 
					
						
							|  |  |  |                   ...label.attributes, | 
					
						
							|  |  |  |                   documents: { | 
					
						
							|  |  |  |                     data: expect.arrayContaining( | 
					
						
							|  |  |  |                       // All documents should be returned, even if they are not published
 | 
					
						
							|  |  |  |                       data.documents.map((document) => ({ | 
					
						
							|  |  |  |                         id: document.id, | 
					
						
							|  |  |  |                         attributes: selectFields(document.attributes), | 
					
						
							|  |  |  |                       })) | 
					
						
							|  |  |  |                     ), | 
					
						
							|  |  |  |                   }, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |               })) | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); |