strapi/tests/api/plugins/graphql/dp-relations.test.api.js

437 lines
11 KiB
JavaScript

'use strict';
// Helpers.
const { pick } = require('lodash/fp');
const { createTestBuilder } = require('api-tests/builder');
const { createStrapiInstance } = require('api-tests/strapi');
const { createAuthRequest } = require('api-tests/request');
const builder = createTestBuilder();
let strapi;
let rq;
let graphqlQuery;
const articleModel = {
attributes: {
name: {
type: 'richtext',
},
},
draftAndPublish: true,
singularName: 'article',
pluralName: 'articles',
displayName: 'Article',
description: '',
collectionName: '',
};
const labelModel = {
attributes: {
name: {
type: 'richtext',
},
articles: {
type: 'relation',
relation: 'manyToMany',
target: 'api::article.article',
targetAttribute: 'labels',
},
one_to_many_articles: {
type: 'relation',
relation: 'oneToMany',
target: 'api::article.article',
targetAttribute: 'label',
},
dz: {
type: 'dynamiczone',
components: ['default.component-with-relation'],
},
},
draftAndPublish: true,
singularName: 'label',
pluralName: 'labels',
displayName: 'Label',
description: '',
collectionName: '',
};
const componentWithOneToManyRelation = {
displayName: 'component-with-relation',
attributes: {
name: {
type: 'string',
},
articles: {
type: 'relation',
relation: 'oneToMany',
target: 'api::article.article',
},
},
};
const labels = [
{ name: 'label 1', documentId: 'label-1', publishedAt: new Date() },
{ name: 'label 1', documentId: 'label-1', publishedAt: null },
{ name: 'label 2', documentId: 'label-2', publishedAt: new Date() },
{ name: 'label 2', documentId: 'label-2', publishedAt: null },
];
const articles = ({ label: labels }) => {
const labelIds = labels.map((label) => label.id);
return [
{
name: 'article 1',
documentId: 'article-1',
publishedAt: new Date(),
labels: labelIds,
label: labelIds[0],
},
{
name: 'article 1',
documentId: 'article-1',
publishedAt: null,
labels: labelIds,
label: labelIds[1],
},
{
name: 'article 2',
documentId: 'article-2',
publishedAt: new Date(),
labels: labelIds,
label: labelIds[0],
},
{
name: 'article 2',
documentId: 'article-2',
publishedAt: null,
labels: labelIds,
label: labelIds[1],
},
];
};
describe('Test Graphql Relations with Draft and Publish enabled', () => {
const data = {
labels: [],
articles: [],
};
beforeAll(async () => {
await builder
.addContentType(articleModel)
.addComponent(componentWithOneToManyRelation)
.addContentType(labelModel)
.addFixtures(labelModel.singularName, labels)
.addFixtures(articleModel.singularName, articles)
.build();
strapi = await createStrapiInstance();
rq = await createAuthRequest({ strapi });
// Add dynamic zones to test data
await strapi.documents('api::label.label').update({
documentId: 'label-1',
data: {
dz: [
{
__component: 'default.component-with-relation',
articles: ['article-1'],
name: 'TEST DZ',
},
],
},
});
await strapi.documents('api::label.label').update({
documentId: 'label-2',
data: {
dz: [
{
__component: 'default.component-with-relation',
articles: ['article-2'],
name: 'TEST DZ',
},
],
},
});
await strapi.documents('api::label.label').publish({
documentId: 'label-1',
});
await strapi.documents('api::label.label').publish({
documentId: 'label-2',
});
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_connection {
data {
documentId
attributes {
name
publishedAt
}
}
}
}
`,
});
const { body } = res;
expect(res.statusCode).toBe(200);
expect(body.data.labels_connection.data.length).toBe(2);
expect(body.data.labels_connection.data.every((label) => label.attributes.publishedAt)).toBe(
true
);
// assign for later use
data.labels = data.labels.concat(res.body.data.labels_connection.data);
});
test('List preview articles with labels', async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
{
articles_connection(status: DRAFT) {
data {
documentId
attributes {
name
labels {
data {
documentId
attributes {
name
publishedAt
}
}
}
}
}
}
}
`,
});
const { body } = res;
expect(res.statusCode).toBe(200);
expect(body.data.articles_connection.data.length).toBe(2);
expect(
body.data.articles_connection.data.every((article) => article.attributes.publishedAt)
).toBe(false);
// assign for later use
data.articles = res.body.data.articles_connection.data;
});
test('Publish article', async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
mutation publishArticle($documentId: ID!, $data: ArticleInput!) {
updateArticle(documentId: $documentId, data: $data, status: PUBLISHED) {
data {
documentId
attributes {
name
publishedAt
}
}
}
}
`,
variables: {
documentId: data.articles[0].documentId,
data: {},
},
});
const { body } = res;
expect(res.statusCode).toBe(200);
expect(body).toMatchObject({
data: {
updateArticle: {
data: {
documentId: data.articles[0].documentId,
attributes: {
name: data.articles[0].attributes.name,
publishedAt: expect.any(String),
},
},
},
},
});
});
test('List labels with published articles', async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
{
labels_connection {
data {
documentId
attributes {
name
dz {
... on ComponentDefaultComponentWithRelation {
articles_connection {
data {
documentId
attributes {
name
publishedAt
}
}
}
}
}
one_to_many_articles_connection {
data {
documentId
attributes {
publishedAt
}
}
}
articles_connection {
data {
documentId
attributes {
name
publishedAt
}
}
}
}
}
}
}
`,
});
const { body } = res;
expect(res.statusCode).toBe(200);
// Check the manyToMany response
expect(body.data.labels_connection.data[0].attributes.articles_connection.data.length).toBe(
2
);
expect(
body.data.labels_connection.data[0].attributes.articles_connection.data.every(
(article) => article.attributes.publishedAt
)
).toBe(true);
// Check the oneToMany response
expect(
body.data.labels_connection.data[0].attributes.one_to_many_articles_connection.data.length
).toBe(2);
expect(
body.data.labels_connection.data[0].attributes.one_to_many_articles_connection.data.every(
(article) => article.attributes.publishedAt
)
).toBe(true);
// Check dynamic zone with relations
expect(body.data.labels_connection.data[0].attributes.dz.length).toBe(1);
expect(
body.data.labels_connection.data[0].attributes.dz[0].articles_connection.data.every(
(article) => article.attributes.publishedAt
)
).toBe(true);
});
test('List labels with draft articles', async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
{
labels_connection(status: DRAFT) {
data {
documentId
publishedAt
attributes {
name
dz {
... on ComponentDefaultComponentWithRelation {
articles_connection {
data {
documentId
attributes {
name
publishedAt
}
}
}
}
}
one_to_many_articles_connection {
data {
documentId
attributes {
publishedAt
}
}
}
articles_connection {
data {
documentId
attributes {
name
publishedAt
}
}
}
}
}
}
}
`,
});
const { body } = res;
expect(res.statusCode).toBe(200);
// Check the manyToMany response
expect(body.data.labels_connection.data[0].attributes.articles_connection.data.length).toBe(
2
);
expect(
body.data.labels_connection.data[0].attributes.articles_connection.data.every(
(article) => article.attributes.publishedAt
)
).toBe(false);
// Check the oneToMany response
expect(
body.data.labels_connection.data[0].attributes.one_to_many_articles_connection.data.length
).toBe(2);
expect(
body.data.labels_connection.data[0].attributes.one_to_many_articles_connection.data.every(
(article) => article.attributes.publishedAt
)
).toBe(false);
// Check dynamic zone with relations
expect(body.data.labels_connection.data[0].attributes.dz.length).toBe(1);
expect(
body.data.labels_connection.data[0].attributes.dz[0].articles_connection.data.every(
(article) => article.attributes.publishedAt
)
).toBe(false);
});
});
});