mirror of
https://github.com/strapi/strapi.git
synced 2025-06-27 00:41:25 +00:00
215 lines
5.7 KiB
JavaScript
215 lines
5.7 KiB
JavaScript
'use strict';
|
|
|
|
const { prop, difference, map, uniq } = require('lodash/fp');
|
|
const { createAuthRequest } = require('api-tests/request');
|
|
const { createStrapiInstance } = require('api-tests/strapi');
|
|
const { createTestBuilder } = require('api-tests/builder');
|
|
|
|
const toIds = (arr) => uniq(map(prop('id'))(arr));
|
|
|
|
let strapi;
|
|
let rq;
|
|
const builder = createTestBuilder();
|
|
|
|
const data = {
|
|
product: [],
|
|
category: [],
|
|
shop: [],
|
|
};
|
|
|
|
const productModel = {
|
|
attributes: {
|
|
name: {
|
|
type: 'string',
|
|
unique: true,
|
|
},
|
|
categories: {
|
|
type: 'relation',
|
|
relation: 'oneToMany',
|
|
target: 'api::category.category',
|
|
targetAttribute: 'product',
|
|
},
|
|
shops: {
|
|
type: 'relation',
|
|
relation: 'oneToMany',
|
|
target: 'api::shop.shop',
|
|
},
|
|
},
|
|
displayName: 'Product',
|
|
singularName: 'product',
|
|
pluralName: 'products',
|
|
};
|
|
|
|
const categoryModel = {
|
|
attributes: {
|
|
name: {
|
|
type: 'string',
|
|
unique: true,
|
|
},
|
|
},
|
|
displayName: 'Category',
|
|
singularName: 'category',
|
|
pluralName: 'categories',
|
|
};
|
|
|
|
const shopModel = {
|
|
attributes: {
|
|
name: {
|
|
type: 'string',
|
|
unique: true,
|
|
},
|
|
metadata: {
|
|
type: 'string',
|
|
},
|
|
},
|
|
displayName: 'Shop',
|
|
singularName: 'shop',
|
|
pluralName: 'shops',
|
|
};
|
|
|
|
const PRODUCT_SHOP_COUNT = 12;
|
|
const PRODUCT_CATEGORY_COUNT = 5;
|
|
const fixtures = {
|
|
shop: [
|
|
{ name: 'SH.A', metadata: 'foobar' },
|
|
{ name: 'SH.B', metadata: 'foobar' },
|
|
{ name: 'SH.C', metadata: 'foobar' },
|
|
{ name: 'SH.D', metadata: 'foobar' },
|
|
{ name: 'SH.E', metadata: 'foobar' },
|
|
{ name: 'SH.F', metadata: 'foobar' },
|
|
{ name: 'SH.G', metadata: 'foobar' },
|
|
{ name: 'SH.H', metadata: 'foobar' },
|
|
{ name: 'SH.I', metadata: 'foobar' },
|
|
{ name: 'SH.J', metadata: 'foobar' },
|
|
{ name: 'SH.K', metadata: 'foobar' },
|
|
{ name: 'SH.L', metadata: 'foobar' },
|
|
],
|
|
category: [
|
|
{ name: 'CT.A' },
|
|
{ name: 'CT.B' },
|
|
{ name: 'CT.C' },
|
|
{ name: 'CT.D' },
|
|
{ name: 'CT.E' },
|
|
{ name: 'CT.F' },
|
|
{ name: 'CT.G' },
|
|
{ name: 'CT.H' },
|
|
{ name: 'CT.I' },
|
|
{ name: 'CT.J' },
|
|
{ name: 'CT.K' },
|
|
{ name: 'CT.L' },
|
|
],
|
|
product: ({ shop, category }) => [
|
|
{
|
|
name: 'PD.A',
|
|
categories: category.slice(0, PRODUCT_CATEGORY_COUNT).map(prop('id')),
|
|
shops: shop.slice(0, PRODUCT_SHOP_COUNT).map(prop('id')),
|
|
},
|
|
],
|
|
};
|
|
|
|
const getUID = (modelName) => `api::${modelName}.${modelName}`;
|
|
const getCMPrefixUrl = (modelName) => `/content-manager/relations/${getUID(modelName)}`;
|
|
|
|
describe('x-to-many RF Preview', () => {
|
|
const cmProductUrl = getCMPrefixUrl(productModel.singularName);
|
|
|
|
beforeAll(async () => {
|
|
await builder
|
|
.addContentTypes([shopModel, categoryModel, productModel])
|
|
.addFixtures(shopModel.singularName, fixtures.shop)
|
|
.addFixtures(categoryModel.singularName, fixtures.category)
|
|
.addFixtures(productModel.singularName, fixtures.product)
|
|
.build();
|
|
|
|
strapi = await createStrapiInstance();
|
|
rq = await createAuthRequest({ strapi });
|
|
|
|
Object.assign(data, await builder.sanitizedFixtures(strapi));
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await strapi.destroy();
|
|
await builder.cleanup();
|
|
});
|
|
|
|
describe('Entity Misc', () => {
|
|
test.each(['foobar', 'name'])(`Throws if the targeted field is invalid (%s)`, async (field) => {
|
|
const product = data.product[0];
|
|
const { body, statusCode } = await rq.get(`${cmProductUrl}/${product.id}/${field}`);
|
|
|
|
expect(statusCode).toBe(400);
|
|
expect(body).toMatchObject({
|
|
data: null,
|
|
error: {
|
|
status: 400,
|
|
name: 'BadRequestError',
|
|
message: "This relational field doesn't exist",
|
|
details: {},
|
|
},
|
|
});
|
|
});
|
|
|
|
test('Throws if the entity does not exist', async () => {
|
|
const { body, statusCode } = await rq.get(`${cmProductUrl}/${data.shop[11].id}/categories`);
|
|
|
|
expect(statusCode).toBe(404);
|
|
expect(body).toMatchObject({
|
|
data: null,
|
|
error: {
|
|
status: 404,
|
|
name: 'NotFoundError',
|
|
message: 'Not Found',
|
|
details: {},
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Default Behavior', () => {
|
|
test('Should return a preview for the shops field', async () => {
|
|
const product = data.product[0];
|
|
|
|
const { body, statusCode } = await rq.get(`${cmProductUrl}/${product.id}/shops`);
|
|
expect(statusCode).toBe(200);
|
|
expect(body.results).toHaveLength(10);
|
|
expect(body.pagination).toMatchObject({ page: 1, pageSize: 10, pageCount: 2, total: 12 });
|
|
expect(difference(toIds(body.results), toIds(data.shop))).toHaveLength(0);
|
|
});
|
|
|
|
test('Should return a preview for the categories field', async () => {
|
|
const product = data.product[0];
|
|
|
|
const { body, statusCode } = await rq.get(`${cmProductUrl}/${product.id}/categories`);
|
|
|
|
expect(statusCode).toBe(200);
|
|
expect(body.results).toHaveLength(5);
|
|
expect(body.pagination).toMatchObject({ page: 1, pageSize: 10, pageCount: 1, total: 5 });
|
|
expect(difference(toIds(body.results), toIds(data.category))).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe('Pagination', () => {
|
|
test.each([
|
|
[1, 10],
|
|
[2, 10],
|
|
[5, 1],
|
|
[4, 2],
|
|
[1, 100],
|
|
])('Custom pagination (%s, %s)', async (page, pageSize) => {
|
|
const product = data.product[0];
|
|
|
|
const { body, statusCode } = await rq.get(
|
|
`${cmProductUrl}/${product.id}/shops?page=${page}&pageSize=${pageSize}`
|
|
);
|
|
|
|
expect(statusCode).toBe(200);
|
|
|
|
const { pagination, results } = body;
|
|
|
|
expect(pagination.page).toBe(page);
|
|
expect(pagination.pageSize).toBe(pageSize);
|
|
expect(results).toHaveLength(Math.min(pageSize, PRODUCT_SHOP_COUNT - pageSize * (page - 1)));
|
|
});
|
|
});
|
|
});
|