strapi/packages/plugins/graphql/tests/graphql-relations.test.e2e.js

703 lines
15 KiB
JavaScript
Raw Normal View History

'use strict';
// Helpers.
const _ = require('lodash');
2021-04-29 11:11:46 +02:00
const { createTestBuilder } = require('../../../../test/helpers/builder');
const { createStrapiInstance } = require('../../../../test/helpers/strapi');
const { createAuthRequest } = require('../../../../test/helpers/request');
const builder = createTestBuilder();
let strapi;
let rq;
let graphqlQuery;
// utils
const selectFields = doc => _.pick(doc, ['id', 'name', 'color']);
const rgbColorComponent = {
attributes: {
name: {
type: 'text',
},
red: {
type: 'integer',
},
green: {
type: 'integer',
},
blue: {
type: 'integer',
},
},
name: 'rgbColor',
};
const documentModel = {
2019-11-14 16:37:57 +01:00
attributes: {
name: {
type: 'richtext',
},
2019-11-14 16:37:57 +01:00
content: {
type: 'richtext',
},
2019-11-14 16:37:57 +01:00
},
name: 'document',
description: '',
collectionName: '',
};
const labelModel = {
2019-11-14 16:37:57 +01:00
attributes: {
name: {
type: 'richtext',
},
2019-11-14 16:37:57 +01:00
documents: {
2021-07-08 18:15:32 +02:00
type: 'relation',
relation: 'manyToMany',
2021-08-06 18:09:49 +02:00
target: 'api::document.document',
2019-11-14 16:37:57 +01:00
targetAttribute: 'labels',
},
color: {
type: 'component',
component: 'default.rgb-color',
repeatable: false,
},
2019-11-14 16:37:57 +01:00
},
name: 'label',
description: '',
collectionName: '',
};
const carModel = {
attributes: {
name: {
type: 'text',
},
},
name: 'car',
description: '',
collectionName: '',
};
const personModel = {
attributes: {
name: {
type: 'text',
},
privateName: {
type: 'text',
private: true,
},
privateCars: {
2021-07-08 18:15:32 +02:00
type: 'relation',
relation: 'oneToMany',
2021-08-06 18:09:49 +02:00
target: 'api::car.car',
targetAttribute: 'person',
private: true,
},
},
name: 'person',
description: '',
collectionName: '',
};
describe('Test Graphql Relations API End to End', () => {
beforeAll(async () => {
await builder
.addComponent(rgbColorComponent)
.addContentTypes([documentModel, labelModel, carModel, personModel])
.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', () => {
let data = {
labels: [],
documents: [],
people: [],
cars: [],
};
const labelsPayload = [
{ name: 'label 1', color: null },
{ name: 'label 2', color: null },
{ name: 'labelWithColor', color: { name: 'tomato', red: 255, green: 99, blue: 71 } },
];
2019-03-28 15:08:00 +01:00
const documentsPayload = [{ name: 'document 1' }, { name: 'document 2' }];
test.each(labelsPayload)('Create label %o', async label => {
const res = await graphqlQuery({
query: /* GraphQL */ `
mutation createLabel($input: createLabelInput) {
createLabel(input: $input) {
label {
name
color {
name
red
green
blue
}
}
}
}
`,
variables: {
input: {
data: label,
},
},
});
expect(res.statusCode).toBe(200);
expect(res.body).toEqual({
data: {
createLabel: {
label,
},
},
});
});
test('List labels', async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
{
labels {
id
name
color {
name
red
green
blue
}
}
}
`,
});
const { body } = res;
expect(res.statusCode).toBe(200);
expect(body).toMatchObject({
data: {
labels: labelsPayload,
},
});
// assign for later use
data.labels = data.labels.concat(res.body.data.labels);
});
test.each(documentsPayload)('Create document linked to every labels %o', async document => {
const res = await graphqlQuery({
query: /* GraphQL */ `
mutation createDocument($input: createDocumentInput) {
createDocument(input: $input) {
document {
name
labels {
id
name
color {
2019-04-09 18:35:49 +02:00
name
red
green
blue
2019-04-09 18:35:49 +02:00
}
}
}
}
}
`,
variables: {
input: {
data: {
...document,
labels: data.labels.map(t => t.id),
},
},
},
});
const { body } = res;
expect(res.statusCode).toBe(200);
expect(body).toMatchObject({
data: {
createDocument: {
document: {
...selectFields(document),
labels: expect.arrayContaining(data.labels.map(selectFields)),
},
},
},
});
});
test('List documents with labels', async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
{
documents {
id
2019-03-28 15:08:00 +01:00
name
labels {
id
name
color {
name
red
green
blue
}
}
}
}
`,
});
const { body } = res;
expect(res.statusCode).toBe(200);
expect(body).toMatchObject({
2019-04-09 18:35:49 +02:00
data: {
documents: expect.arrayContaining(
data.documents.map(document => ({
...selectFields(document),
labels: expect.arrayContaining(data.labels.map(selectFields)),
2019-05-06 15:33:25 +02:00
}))
2019-04-09 18:35:49 +02:00
),
},
});
// assign for later use
data.documents = res.body.data.documents;
});
test('List Labels with documents', async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
{
labels {
id
name
color {
name
red
green
blue
}
documents {
id
2019-03-28 15:08:00 +01:00
name
}
}
}
`,
});
const { body } = res;
expect(res.statusCode).toBe(200);
expect(body).toMatchObject({
data: {
2019-03-28 15:08:00 +01:00
labels: expect.arrayContaining(
data.labels.map(label => ({
2019-03-28 15:08:00 +01:00
...selectFields(label),
documents: expect.arrayContaining(data.documents.map(selectFields)),
2019-05-06 15:33:25 +02:00
}))
2019-03-28 15:08:00 +01:00
),
},
});
// assign for later use
data.labels = res.body.data.labels;
});
test('Deep query', async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
{
documents(where: { labels: { name_contains: "label 1" } }) {
id
2019-03-28 15:08:00 +01:00
name
labels {
id
name
color {
name
red
green
blue
}
}
}
}
`,
});
expect(res.statusCode).toBe(200);
expect(res.body).toMatchObject({
data: {
2019-03-28 15:08:00 +01:00
documents: expect.arrayContaining(data.documents),
},
});
});
test('Update Document relations removes correctly a relation', async () => {
// if I remove a label from an document is it working
const res = await graphqlQuery({
query: /* GraphQL */ `
mutation updateDocument($input: updateDocumentInput) {
updateDocument(input: $input) {
document {
id
2019-03-28 15:08:00 +01:00
name
labels {
id
name
color {
name
red
green
blue
}
}
}
}
}
`,
variables: {
input: {
where: {
id: data.documents[0].id,
},
data: {
labels: [data.labels[0].id],
},
},
},
});
expect(res.statusCode).toBe(200);
expect(res.body).toMatchObject({
data: {
updateDocument: {
document: {
...selectFields(data.documents[0]),
labels: [selectFields(data.labels[0])],
},
},
},
});
});
test('Delete Labels and test Documents relations', async () => {
for (let label of data.labels) {
const res = await graphqlQuery({
query: /* GraphQL */ `
mutation deleteLabel($input: deleteLabelInput) {
deleteLabel(input: $input) {
label {
2019-08-23 14:15:24 +02:00
id
name
color {
name
red
green
blue
}
}
}
}
`,
variables: {
input: {
where: {
id: label.id,
},
},
},
});
expect(res.statusCode).toBe(200);
2019-08-23 14:15:24 +02:00
expect(res.body).toMatchObject({
data: {
deleteLabel: {
label: {
id: label.id,
},
},
},
});
}
const res = await graphqlQuery({
query: /* GraphQL */ `
{
documents {
id
2019-03-28 15:08:00 +01:00
name
labels {
id
name
color {
name
red
green
blue
}
}
}
}
`,
});
const { body } = res;
expect(res.statusCode).toBe(200);
expect(body).toMatchObject({
data: {
2019-03-28 15:08:00 +01:00
documents: expect.arrayContaining(
data.documents.map(document => ({
...selectFields(document),
labels: [],
2019-05-06 15:33:25 +02:00
}))
2019-03-28 15:08:00 +01:00
),
},
});
});
test('Delete Documents', async () => {
for (let document of data.documents) {
const res = await graphqlQuery({
query: /* GraphQL */ `
mutation deleteDocument($input: deleteDocumentInput) {
deleteDocument(input: $input) {
document {
2019-08-23 14:15:24 +02:00
id
2019-03-28 15:08:00 +01:00
name
}
}
}
`,
variables: {
input: {
where: {
id: document.id,
},
},
},
});
expect(res.statusCode).toBe(200);
2019-08-23 14:15:24 +02:00
expect(res.body).toMatchObject({
data: {
deleteDocument: {
document: {
id: document.id,
},
},
},
});
}
});
test('Create person', async () => {
const person = {
name: 'Chuck Norris',
privateName: 'Jean-Eude',
};
const res = await graphqlQuery({
query: /* GraphQL */ `
mutation createPerson($input: createPersonInput) {
createPerson(input: $input) {
person {
id
name
}
}
}
`,
variables: {
input: {
data: person,
},
},
});
expect(res.statusCode).toBe(200);
expect(res.body).toEqual({
data: {
createPerson: {
person: {
id: expect.anything(),
name: person.name,
},
},
},
});
data.people.push(res.body.data.createPerson.person);
});
test("Can't list a private field", async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
{
people {
name
privateName
}
}
`,
});
expect(res.statusCode).toBe(400);
expect(res.body).toMatchObject({
errors: [
{
message: 'Cannot query field "privateName" on type "Person".',
},
],
});
});
test('Create a car linked to a person (oneToMany)', async () => {
const car = {
name: 'Peugeot 508',
person: data.people[0].id,
};
const res = await graphqlQuery({
query: /* GraphQL */ `
mutation createCar($input: createCarInput) {
createCar(input: $input) {
car {
id
name
person {
id
name
}
}
}
}
`,
variables: {
input: {
data: {
...car,
},
},
},
});
expect(res.statusCode).toBe(200);
expect(res.body).toMatchObject({
data: {
createCar: {
car: {
id: expect.anything(),
name: car.name,
person: data.people[0],
},
},
},
});
data.cars.push({ id: res.body.data.createCar.car.id });
});
test("Can't list a private oneToMany relation", async () => {
const res = await graphqlQuery({
query: /* GraphQL */ `
{
people {
name
privateCars
}
}
`,
});
expect(res.statusCode).toBe(400);
expect(res.body).toMatchObject({
errors: [
{
message: 'Cannot query field "privateCars" on type "Person".',
},
],
});
});
test('Edit person/cars relations removes correctly a car', async () => {
const newPerson = {
name: 'Check Norris Junior',
privateCars: [],
};
const mutationRes = await graphqlQuery({
query: /* GraphQL */ `
mutation updatePerson($input: updatePersonInput) {
updatePerson(input: $input) {
person {
id
}
}
}
`,
variables: {
input: {
where: {
id: data.people[0].id,
},
data: {
...newPerson,
},
},
},
});
expect(mutationRes.statusCode).toBe(200);
const queryRes = await graphqlQuery({
query: /* GraphQL */ `
query($id: ID!) {
car(id: $id) {
person {
id
}
}
}
`,
variables: {
id: data.cars[0].id,
},
});
expect(queryRes.statusCode).toBe(200);
expect(queryRes.body).toEqual({
data: {
car: {
person: null,
},
},
});
});
});
});