Skip to content
This repository was archived by the owner on Oct 2, 2024. It is now read-only.

Commit e9aca6f

Browse files
author
michiel
committed
feat(core): delete support in persistCascade for 1-to-1 relations #42
1 parent 30325dc commit e9aca6f

File tree

4 files changed

+118
-27
lines changed

4 files changed

+118
-27
lines changed

packages/core/__tests__/Resource/Change/ChangeSet.persistCascadeResource.test.js

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ describe('The cascaded persist of a resource', () => {
2626

2727
const productResource = Resource.create(1, 'product', { price: 2300 });
2828
const image = Resource.create(null, 'image', { src: 'some/image.png' });
29+
const thumb = Resource.create('2', 'image', { src: 'some/image2.png' });
30+
const author = Resource.create(2, 'person', { name: 'A great author' });
2931

3032
const coverStory = Resource.create(null, 'text', {
3133
text: 'A tale of mystery and wonder.',
@@ -41,6 +43,8 @@ describe('The cascaded persist of a resource', () => {
4143
const book = Resource.create(1, 'book', {
4244
title: 'A great book',
4345
product: productResource,
46+
thumb,
47+
author,
4448
}, {
4549
product: {
4650
resource: 'product',
@@ -52,6 +56,16 @@ describe('The cascaded persist of a resource', () => {
5256
cardinality: 'one-to-one',
5357
many: false,
5458
},
59+
thumb: {
60+
cardinality: 'one-to-one',
61+
many: false,
62+
resource: 'image',
63+
},
64+
author: {
65+
cardinality: 'many-to-one',
66+
many: false,
67+
resource: 'person',
68+
},
5569
});
5670

5771
book.data = {
@@ -66,11 +80,11 @@ describe('The cascaded persist of a resource', () => {
6680

6781
set.persistCascadeResource(book);
6882

69-
expect(set.tasks).toHaveLength(6);
83+
expect(set.tasks).toHaveLength(9);
7084

7185
expect(set.tasks[0].payload).toBe(book);
7286
expect(set.tasks[0].type).toEqual('update');
73-
expect(set.tasks[0].related).toHaveLength(1);
87+
expect(set.tasks[0].related).toHaveLength(3);
7488
expect(set.tasks[0].dependencies).toHaveLength(1);
7589
expect(set.tasks[0].dependencies[0].type).toEqual('create');
7690
expect(set.tasks[0].dependencies[0].payload).toEqual(coverStory);
@@ -85,33 +99,52 @@ describe('The cascaded persist of a resource', () => {
8599
expect(set.tasks[1].dependencies[0].type).toEqual('create');
86100
expect(set.tasks[1].dependencies[0].payload).toEqual(coverStory);
87101

88-
expect(set.tasks[2].payload).toBe(productResource);
89-
expect(set.tasks[2].type).toEqual('update');
90-
expect(set.tasks[2].related).toHaveLength(0);
102+
expect(set.tasks[2].context).toBe(book);
103+
expect(set.tasks[2].type).toEqual('relation');
91104
expect(set.tasks[2].dependencies).toHaveLength(0);
105+
expect(set.tasks[2].related).toHaveLength(0);
106+
expect(set.tasks[2].payload.relation).toEqual('thumb');
107+
expect(set.tasks[2].payload.resources).toHaveLength(0);
108+
109+
expect(set.tasks[3].context).toBe(book);
110+
expect(set.tasks[3].type).toEqual('relation');
111+
expect(set.tasks[3].dependencies).toHaveLength(0);
112+
expect(set.tasks[3].related).toHaveLength(0);
113+
expect(set.tasks[3].payload.relation).toEqual('author');
114+
expect(set.tasks[3].payload.resources).toHaveLength(0);
92115

93-
expect(set.tasks[3].payload).toBe(coverStory);
94-
expect(set.tasks[3].type).toEqual('create');
95-
expect(set.tasks[3].related).toHaveLength(1);
96-
expect(set.tasks[3].related[0].type).toEqual('relation');
97-
expect(set.tasks[3].related[0].payload.relation).toEqual('image');
98-
expect(set.tasks[3].related[0].payload.resources[0]).toBe(image);
99-
expect(set.tasks[3].dependencies).toHaveLength(1);
100-
expect(set.tasks[3].dependencies[0].type).toEqual('create');
101-
expect(set.tasks[3].dependencies[0].payload).toEqual(image);
102-
103-
expect(set.tasks[4].context).toBe(coverStory);
104-
expect(set.tasks[4].type).toEqual('relation');
105-
expect(set.tasks[4].dependencies).toHaveLength(2);
106-
expect(set.tasks[4].dependencies[0].type).toEqual('create');
107-
expect(set.tasks[4].dependencies[0].payload).toEqual(coverStory);
108-
expect(set.tasks[4].dependencies[1].type).toEqual('create');
109-
expect(set.tasks[4].dependencies[1].payload).toEqual(image);
116+
expect(set.tasks[4].payload).toBe(productResource);
117+
expect(set.tasks[4].type).toEqual('update');
110118
expect(set.tasks[4].related).toHaveLength(0);
119+
expect(set.tasks[4].dependencies).toHaveLength(0);
111120

112-
expect(set.tasks[5].payload).toBe(image);
121+
expect(set.tasks[5].payload).toBe(coverStory);
113122
expect(set.tasks[5].type).toEqual('create');
114-
expect(set.tasks[5].related).toHaveLength(0);
115-
expect(set.tasks[5].dependencies).toHaveLength(0);
123+
expect(set.tasks[5].related).toHaveLength(1);
124+
expect(set.tasks[5].related[0].type).toEqual('relation');
125+
expect(set.tasks[5].related[0].payload.relation).toEqual('image');
126+
expect(set.tasks[5].related[0].payload.resources[0]).toBe(image);
127+
expect(set.tasks[5].dependencies).toHaveLength(1);
128+
expect(set.tasks[5].dependencies[0].type).toEqual('create');
129+
expect(set.tasks[5].dependencies[0].payload).toEqual(image);
130+
131+
expect(set.tasks[6].context).toBe(coverStory);
132+
expect(set.tasks[6].type).toEqual('relation');
133+
expect(set.tasks[6].dependencies).toHaveLength(2);
134+
expect(set.tasks[6].dependencies[0].type).toEqual('create');
135+
expect(set.tasks[6].dependencies[0].payload).toEqual(coverStory);
136+
expect(set.tasks[6].dependencies[1].type).toEqual('create');
137+
expect(set.tasks[6].dependencies[1].payload).toEqual(image);
138+
expect(set.tasks[6].related).toHaveLength(0);
139+
140+
expect(set.tasks[7].payload).toBe(image);
141+
expect(set.tasks[7].type).toEqual('create');
142+
expect(set.tasks[7].related).toHaveLength(0);
143+
expect(set.tasks[7].dependencies).toHaveLength(0);
144+
145+
expect(set.tasks[8].payload).toBe(thumb);
146+
expect(set.tasks[8].type).toEqual('delete');
147+
expect(set.tasks[8].related).toHaveLength(0);
148+
expect(set.tasks[8].dependencies).toHaveLength(0);
116149
});
117150
});

packages/core/__tests__/Resource/Change/Relation.test.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Resource from '../../../src/Resource/Resource';
22
import {
33
getChangedResourceRelations,
4-
getAllRelatedResources,
4+
getAllRelatedResources, getDeletedOneToOneRelatedResources,
55
} from '../../../src/Resource/Change/Relation/Relation';
66
import { resourceHasChanged } from '../../../src/Resource/Change/Inspection';
77

@@ -94,10 +94,42 @@ describe('Relation tests', () => {
9494
});
9595

9696
author.data = {
97-
name: 'An even greated author',
97+
name: 'An even greater author',
9898
};
9999

100100
const changedRelations = getChangedResourceRelations(resource);
101101
expect(changedRelations).toHaveLength(0);
102102
});
103+
104+
test('that a correct list of deleted one-to-one resources is returned', () => {
105+
const author = Resource.create(2, 'author', { name: 'A great author' });
106+
const thumb = Resource.create('2', 'image', { src: 'some/image2.png' });
107+
const resource = Resource.create(1, 'book', {
108+
title: 'A great book',
109+
author,
110+
thumb,
111+
}, {
112+
author: {
113+
resource: 'author',
114+
cardinality: 'many-to-one',
115+
},
116+
thumb: {
117+
resource: 'image',
118+
cardinality: 'one-to-one',
119+
},
120+
coverStory: {
121+
resource: 'cover-story',
122+
cardinality: 'one-to-one',
123+
},
124+
});
125+
126+
resource.data = {
127+
title: 'A great book',
128+
};
129+
130+
const deletedResources = getDeletedOneToOneRelatedResources(resource);
131+
132+
expect(deletedResources).toHaveLength(1);
133+
expect(deletedResources[0]).toBe(thumb);
134+
});
103135
});

packages/core/src/Resource/Change/Relation/Relation.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,26 @@ export function getChangedResourceRelations(resource) {
6464
),
6565
));
6666
}
67+
68+
/**
69+
* @param {HyralResource} resource
70+
*
71+
* @returns {HyralResource[]}
72+
*/
73+
export function getDeletedOneToOneRelatedResources(resource) {
74+
if (!resource.relationships) {
75+
return [];
76+
}
77+
78+
if (resourceIsNew(resource) || previousState(resource.stateStack) === null) {
79+
return [];
80+
}
81+
82+
return Object.keys(resource.relationships)
83+
.filter(relation => resource.relationships[relation].cardinality === 'one-to-one')
84+
.filter(relation => getRelatedResources(resource, relation).length === 0)
85+
.filter(
86+
relation => getRelatedResources(previousState(resource.stateStack), relation).length !== 0,
87+
)
88+
.map(relation => getRelatedResources(previousState(resource.stateStack), relation)[0]);
89+
}

packages/core/src/Resource/Change/Task/TaskGenerator.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Task from './Task';
44
import {
55
getAllRelatedResources,
66
getChangedResourceRelations,
7+
getDeletedOneToOneRelatedResources,
78
getRelatedResources,
89
} from '../Relation/Relation';
910
import setTaskDependencies from './Helpers/setTaskDependencies';
@@ -59,6 +60,8 @@ export default function TaskGenerator(tasks, repositoryManager) {
5960
relatedResource => this.persistCascadeResource(relatedResource),
6061
);
6162

63+
getDeletedOneToOneRelatedResources(resource).map(this.deleteResource);
64+
6265
setTaskDependencies(tasks);
6366
},
6467
/**

0 commit comments

Comments
 (0)