mirror of
https://github.com/strapi/strapi.git
synced 2025-09-25 08:19:07 +00:00
fix(content-manager): detect non existant relation on entity update
This commit is contained in:
parent
a2b035600d
commit
f6be2e2b66
@ -31,7 +31,7 @@ const LogoContainer = styled(Box)`
|
||||
`;
|
||||
|
||||
const HomePage = () => {
|
||||
// // Temporary until we develop the menu API
|
||||
// Temporary until we develop the menu API
|
||||
const { collectionTypes, singleTypes, isLoading: isLoadingForModels } = useModels();
|
||||
const { guidedTourState, isGuidedTourVisible, isSkipped } = useGuidedTour();
|
||||
|
||||
|
@ -186,4 +186,133 @@ describe('Entity service', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update', () => {
|
||||
describe('assign default values', () => {
|
||||
let instance;
|
||||
|
||||
const entityUID = 'api::entity.entity';
|
||||
const relationUID = 'api::relation.relation';
|
||||
const fakeEntities = {
|
||||
0: {
|
||||
id: 0,
|
||||
Name: 'TestEntity',
|
||||
createdAt: '2022-09-28T15:11:22.995Z',
|
||||
updatedAt: '2022-09-29T09:01:02.949Z',
|
||||
publishedAt: null,
|
||||
},
|
||||
1: {
|
||||
id: 1,
|
||||
Name: 'TestRelation',
|
||||
createdAt: '2022-09-28T15:11:22.995Z',
|
||||
updatedAt: '2022-09-29T09:01:02.949Z',
|
||||
publishedAt: null,
|
||||
},
|
||||
2: null,
|
||||
};
|
||||
beforeAll(() => {
|
||||
const fakeModel = {
|
||||
kind: 'collectionType',
|
||||
modelName: 'entity',
|
||||
collectionName: 'entity',
|
||||
uid: entityUID,
|
||||
privateAttributes: [],
|
||||
options: {},
|
||||
info: {
|
||||
singularName: 'entity',
|
||||
pluralName: 'entities',
|
||||
displayName: 'ENTITY',
|
||||
},
|
||||
attributes: {
|
||||
Name: {
|
||||
type: 'string',
|
||||
},
|
||||
addresses: {
|
||||
type: 'relation',
|
||||
relation: 'oneToMany',
|
||||
target: relationUID,
|
||||
mappedBy: 'entity',
|
||||
},
|
||||
updatedBy: {
|
||||
type: 'relation',
|
||||
relation: 'oneToOne',
|
||||
target: 'admin::user',
|
||||
configurable: false,
|
||||
writable: false,
|
||||
visible: false,
|
||||
useJoinTable: false,
|
||||
private: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const fakeQuery = {
|
||||
findOne: jest.fn(({ where }) => fakeEntities[where.id]),
|
||||
update: jest.fn(({ where }) => ({
|
||||
...fakeEntities[where.id],
|
||||
addresses: {
|
||||
count: 1,
|
||||
},
|
||||
})),
|
||||
};
|
||||
|
||||
const fakeDB = {
|
||||
query: jest.fn(() => fakeQuery),
|
||||
};
|
||||
|
||||
const fakeStrapi = {
|
||||
getModel: jest.fn(() => fakeModel),
|
||||
};
|
||||
|
||||
instance = createEntityService({
|
||||
strapi: fakeStrapi,
|
||||
db: fakeDB,
|
||||
eventHub: null, // bypass event emission for update tests
|
||||
entityValidator,
|
||||
});
|
||||
});
|
||||
|
||||
test(`should fail if the entity doesn't exist`, async () => {
|
||||
expect(
|
||||
await instance.update(entityUID, Math.random() * (10000 - 100) + 100, {})
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
test('should successfully update with an existing relation', async () => {
|
||||
const data = {
|
||||
Name: 'TestEntry',
|
||||
addresses: {
|
||||
connect: [
|
||||
{
|
||||
id: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
updatedBy: 1,
|
||||
};
|
||||
expect(await instance.update(entityUID, 0, { data })).toMatchObject({
|
||||
...fakeEntities[0],
|
||||
addresses: {
|
||||
count: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('should throw an error when trying to associate a relation that does not exist', async () => {
|
||||
const data = {
|
||||
Name: 'TestEntry',
|
||||
addresses: {
|
||||
connect: [
|
||||
{
|
||||
id: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
updatedBy: 1,
|
||||
};
|
||||
|
||||
await expect(instance.update(entityUID, 0, { data })).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -9,7 +9,7 @@ const {
|
||||
contentTypes: contentTypesUtils,
|
||||
sanitize,
|
||||
} = require('@strapi/utils');
|
||||
const { ValidationError } = require('@strapi/utils').errors;
|
||||
const { ValidationError, ApplicationError } = require('@strapi/utils').errors;
|
||||
const { transformParamsToQuery } = require('@strapi/utils').convertQueryParams;
|
||||
const uploadFiles = require('../utils/upload-files');
|
||||
|
||||
@ -47,6 +47,7 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
||||
},
|
||||
|
||||
async emitEvent(uid, event, entity) {
|
||||
if (!eventHub) return;
|
||||
const model = strapi.getModel(uid);
|
||||
const sanitizedEntity = await sanitize.sanitizers.defaultSanitizeOutput(model, entity);
|
||||
|
||||
@ -168,6 +169,38 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
||||
entityToUpdate
|
||||
);
|
||||
|
||||
// Create an array of the relations we are attempting to associate with this
|
||||
// entity.
|
||||
const relationChecks = [];
|
||||
Object.keys(data).forEach((key) => {
|
||||
const attribute = model.attributes[key];
|
||||
if (attribute?.type !== 'relation') {
|
||||
return;
|
||||
}
|
||||
if (!data[key]?.connect) {
|
||||
return;
|
||||
}
|
||||
relationChecks.push({ uid: attribute.target, data: data[key].connect });
|
||||
});
|
||||
|
||||
// Confirm that these relations exists in the DB before performing the query.
|
||||
await Promise.all(
|
||||
relationChecks.map(async (check) => {
|
||||
await Promise.all(
|
||||
check.data.map(async (d) => {
|
||||
const relationEntity = await db.query(check.uid).findOne({ where: { id: d.id } });
|
||||
if (relationEntity) {
|
||||
return;
|
||||
}
|
||||
// Trying to associate a relation with this entity that does not exist
|
||||
throw new ApplicationError(
|
||||
`Relation of type ${check.uid} with id ${d.id} does not exist`
|
||||
);
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
const query = transformParamsToQuery(uid, pickSelectionParams(wrappedParams));
|
||||
|
||||
// TODO: wrap in transaction
|
||||
|
@ -209,6 +209,7 @@ describe('File', () => {
|
||||
data.files[1] = file;
|
||||
});
|
||||
});
|
||||
|
||||
describe('Move a file from root level to a folder', () => {
|
||||
test('when replacing the file', async () => {
|
||||
const res = await rq({
|
||||
|
Loading…
x
Reference in New Issue
Block a user