Merge pull request #14599 from strapi/relations-main-view/validation-test-findExisting-findAvailable

add validation tests on findAvailable and findExisting relations
This commit is contained in:
Pierre Noël 2022-10-24 09:52:24 +02:00 committed by GitHub
commit 987987e2df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 328 additions and 83 deletions

View File

@ -65,6 +65,15 @@ module.exports = {
return ctx.forbidden();
}
}
} else {
// eslint-disable-next-line no-lonely-if
if (entityId) {
const entity = await strapi.entityService.findOne(model, entityId);
if (!entity) {
return ctx.notFound();
}
}
}
const targetedModel = strapi.getModel(attribute.target);
@ -161,6 +170,12 @@ module.exports = {
if (permissionChecker.cannot.read(entity, targetField)) {
return ctx.forbidden();
}
} else {
const entity = await strapi.entityService.findOne(model, id);
if (!entity) {
return ctx.notFound();
}
}
const targetedModel = strapi.getModel(attribute.target);

View File

@ -171,6 +171,124 @@ describe.each([[false], [true]])('Relations, with d&p: %p', (withDraftAndPublish
});
describe('findAvailable', () => {
describe('On a content-type', () => {
test('Fail when entity is not found', async () => {
const res = await rq({
method: 'GET',
url: '/content-manager/relations/api::shop.shop/products_ow',
qs: {
entityId: 99999,
},
});
expect(res.status).toBe(404);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: 'Not Found',
name: 'NotFoundError',
status: 404,
},
});
});
test("Fail when the field doesn't exist", async () => {
const res = await rq({
method: 'GET',
url: '/content-manager/relations/api::shop.shop/unkown',
});
expect(res.status).toBe(400);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: "This relational field doesn't exist",
name: 'BadRequestError',
status: 400,
},
});
});
test('Fail when the field exists but is not a relational field', async () => {
const res = await rq({
method: 'GET',
url: '/content-manager/relations/api::shop.shop/name',
});
expect(res.status).toBe(400);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: "This relational field doesn't exist",
name: 'BadRequestError',
status: 400,
},
});
});
});
describe('On a component', () => {
test('Fail when the component is not found', async () => {
const res = await rq({
method: 'GET',
url: '/content-manager/relations/default.compo/compo_products_ow',
qs: {
entityId: 99999,
},
});
expect(res.status).toBe(404);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: 'Not Found',
name: 'NotFoundError',
status: 404,
},
});
});
test("Fail when the field doesn't exist", async () => {
const res = await rq({
method: 'GET',
url: '/content-manager/relations/default.compo/unknown',
});
expect(res.status).toBe(400);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: "This relational field doesn't exist",
name: 'BadRequestError',
status: 400,
},
});
});
test('Fail when the field exists but is not a relational field', async () => {
const res = await rq({
method: 'GET',
url: '/content-manager/relations/default.compo/name',
});
expect(res.status).toBe(400);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: "This relational field doesn't exist",
name: 'BadRequestError',
status: 400,
},
});
});
});
describe.each([
['products_ow', false],
['products_oo', false],

View File

@ -173,117 +173,229 @@ describe.each([false, true])('Relations, with d&p: %s', (withDraftAndPublish) =>
await builder.cleanup();
});
describe('findExisting', () => {
describe.each([
['products_ow', false],
['products_oo', false],
['products_mo', false],
['products_om', true],
['products_mm', true],
['products_mw', true],
])('Relation not in a component (%s)', (fieldName, isManyRelation) => {
test('Can retrieve the relation(s) for an entity that have some relations', async () => {
describe('On a content-type', () => {
test('Fail when entity is not found', async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/api::shop.shop/${data.shops[0].id}/${fieldName}`,
url: `/content-manager/relations/api::shop.shop/999999/products_ow`,
});
expect(res.status).toBe(200);
if (isManyRelation) {
expect(res.body.results).toMatchObject([
{
id: expect.any(Number),
name: 'Candle',
...addPublishedAtCheck(null),
},
{
id: expect.any(Number),
name: 'Skate',
...addPublishedAtCheck(expect.any(String)),
},
]);
} else {
expect(res.body.data).toMatchObject({
id: expect.any(Number),
name: 'Skate',
...addPublishedAtCheck(expect.any(String)),
});
}
expect(res.status).toBe(404);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: 'Not Found',
name: 'NotFoundError',
status: 404,
},
});
});
test("Can retrieve the relation(s) for an entity that don't have relations yet", async () => {
test("Fail when the field doesn't exist", async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/api::shop.shop/${data.shops[1].id}/${fieldName}`,
url: `/content-manager/relations/api::shop.shop/${data.shops[0].id}/unkown`,
});
expect(res.status).toBe(200);
if (isManyRelation) {
expect(res.body.results).toHaveLength(0);
} else {
expect(res.body.data).toBe(null);
}
expect(res.status).toBe(400);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: "This relational field doesn't exist",
name: 'BadRequestError',
status: 400,
},
});
});
if (isManyRelation) {
test("Can search ''", async () => {
test('Fail when the field exists but is not a relational field', async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/api::shop.shop/${data.shops[0].id}/name`,
});
expect(res.status).toBe(400);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: "This relational field doesn't exist",
name: 'BadRequestError',
status: 400,
},
});
});
describe.each([
['one-way', 'products_ow', false],
['one-one', 'products_oo', false],
['many-to-one', 'products_mo', false],
['one-to-many', 'products_om', true],
['many-many', 'products_mm', true],
['many-way', 'products_mw', true],
])('%s relation (%s)', (relationType, fieldName, isManyRelation) => {
test('Can retrieve the relation(s) for an entity that have some relations', async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/api::shop.shop/${data.shops[0].id}/${fieldName}`,
qs: {
_q: '',
},
});
expect(res.status).toBe(200);
expect(res.body.results).toMatchObject([
{
id: expect.any(Number),
name: 'Candle',
...addPublishedAtCheck(null),
},
{
if (isManyRelation) {
expect(res.body.results).toMatchObject([
{
id: expect.any(Number),
name: 'Candle',
...addPublishedAtCheck(null),
},
{
id: expect.any(Number),
name: 'Skate',
...addPublishedAtCheck(expect.any(String)),
},
]);
} else {
expect(res.body.data).toMatchObject({
id: expect.any(Number),
name: 'Skate',
...addPublishedAtCheck(expect.any(String)),
},
]);
});
}
});
describe.each([
['compo_products_ow', false],
['compo_products_mw', true],
])('Relation in a component (%s)', (fieldName, isManyRelation) => {
test('Can retrieve the relation(s)', async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/default.compo/${data.shops[0].myCompo.id}/${fieldName}`,
});
}
});
expect(res.status).toBe(200);
test("Can retrieve the relation(s) for an entity that don't have relations yet", async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/api::shop.shop/${data.shops[1].id}/${fieldName}`,
});
expect(res.status).toBe(200);
if (isManyRelation) {
expect(res.body.results).toHaveLength(0);
} else {
expect(res.body.data).toBe(null);
}
});
if (isManyRelation) {
expect(res.body.results).toMatchObject([
{
id: expect.any(Number),
name: 'Candle',
...addPublishedAtCheck(null),
},
{
test("Can search ''", async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/api::shop.shop/${data.shops[0].id}/${fieldName}`,
qs: {
_q: '',
},
});
expect(res.status).toBe(200);
expect(res.body.results).toMatchObject([
{
id: expect.any(Number),
name: 'Candle',
...addPublishedAtCheck(null),
},
{
id: expect.any(Number),
name: 'Skate',
...addPublishedAtCheck(expect.any(String)),
},
]);
});
}
});
});
describe('On a component', () => {
test('Fail when the component is not found', async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/default.compo/999999/compo_products_ow`,
});
expect(res.status).toBe(404);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: 'Not Found',
name: 'NotFoundError',
status: 404,
},
});
});
test("Fail when the field doesn't exist", async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/default.compo/${data.shops[0].myCompo.id}/unknown`,
});
expect(res.status).toBe(400);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: "This relational field doesn't exist",
name: 'BadRequestError',
status: 400,
},
});
});
test('Fail when the field exists but is not a relational field', async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/default.compo/${data.shops[0].myCompo.id}/name`,
});
expect(res.status).toBe(400);
expect(res.body).toMatchObject({
data: null,
error: {
details: {},
message: "This relational field doesn't exist",
name: 'BadRequestError',
status: 400,
},
});
});
describe.each([
['one-way', 'compo_products_ow', false],
['many-way', 'compo_products_mw', true],
])('%s relation (%s)', (relationType, fieldName, isManyRelation) => {
test('Can retrieve the relation(s)', async () => {
const res = await rq({
method: 'GET',
url: `/content-manager/relations/default.compo/${data.shops[0].myCompo.id}/${fieldName}`,
});
expect(res.status).toBe(200);
if (isManyRelation) {
expect(res.body.results).toMatchObject([
{
id: expect.any(Number),
name: 'Candle',
...addPublishedAtCheck(null),
},
{
id: expect.any(Number),
name: 'Skate',
...addPublishedAtCheck(expect.any(String)),
},
]);
} else {
expect(res.body.data).toMatchObject({
id: expect.any(Number),
name: 'Skate',
...addPublishedAtCheck(expect.any(String)),
},
]);
} else {
expect(res.body.data).toMatchObject({
id: expect.any(Number),
name: 'Skate',
...addPublishedAtCheck(expect.any(String)),
});
}
});
}
});
});
});
});