Skip to content

Commit f20ee1b

Browse files
authored
Merge pull request #8285 from pmattmann/feature/content-nodes-endpoints-require-filter
Add ContentNodeCollectionProvider to all ContentNode-Entities
2 parents 7f9370d + 8b4453d commit f20ee1b

26 files changed

+906
-124
lines changed

api/src/Entity/ContentNode/ChecklistNode.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use App\Entity\ContentNode;
1414
use App\Repository\ChecklistNodeRepository;
1515
use App\State\ContentNode\ChecklistNodePersistProcessor;
16+
use App\State\ContentNodeCollectionProvider;
1617
use App\Util\EntityMap;
1718
use App\Validator\ChecklistItem\AssertBelongsToSameCamp;
1819
use Doctrine\Common\Collections\ArrayCollection;
@@ -36,7 +37,8 @@
3637
security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null'
3738
),
3839
new GetCollection(
39-
security: 'is_authenticated()'
40+
security: 'is_authenticated()',
41+
provider: ContentNodeCollectionProvider::class
4042
),
4143
new Post(
4244
processor: ChecklistNodePersistProcessor::class,

api/src/Entity/ContentNode/ColumnLayout.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use App\Entity\SupportsContentNodeChildren;
1414
use App\Repository\ColumnLayoutRepository;
1515
use App\State\ContentNode\ContentNodePersistProcessor;
16+
use App\State\ContentNodeCollectionProvider;
1617
use App\Validator\AssertJsonSchema;
1718
use App\Validator\ColumnLayout\AssertColumWidthsSumTo12;
1819
use App\Validator\ColumnLayout\AssertNoOrphanChildren;
@@ -38,7 +39,8 @@
3839
security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null'
3940
),
4041
new GetCollection(
41-
security: 'is_authenticated()'
42+
security: 'is_authenticated()',
43+
provider: ContentNodeCollectionProvider::class
4244
),
4345
new Post(
4446
processor: ContentNodePersistProcessor::class,

api/src/Entity/ContentNode/MaterialNode.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use App\Entity\MaterialItem;
1414
use App\Repository\MaterialNodeRepository;
1515
use App\State\ContentNode\ContentNodePersistProcessor;
16+
use App\State\ContentNodeCollectionProvider;
1617
use App\Util\EntityMap;
1718
use Doctrine\Common\Collections\ArrayCollection;
1819
use Doctrine\Common\Collections\Collection;
@@ -36,7 +37,8 @@
3637
security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null'
3738
),
3839
new GetCollection(
39-
security: 'is_authenticated()'
40+
security: 'is_authenticated()',
41+
provider: ContentNodeCollectionProvider::class
4042
),
4143
new Post(
4244
processor: ContentNodePersistProcessor::class,

api/src/Entity/ContentNode/MultiSelect.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use App\Repository\MultiSelectRepository;
1414
use App\State\ContentNode\ContentNodePersistProcessor;
1515
use App\State\ContentNode\MultiSelectCreateProcessor;
16+
use App\State\ContentNodeCollectionProvider;
1617
use App\Validator\AssertJsonSchema;
1718
use Doctrine\ORM\Mapping as ORM;
1819
use Symfony\Component\Serializer\Annotation\Groups;
@@ -34,7 +35,8 @@
3435
security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null' // disallow delete when contentNode is a root node
3536
),
3637
new GetCollection(
37-
security: 'is_authenticated()'
38+
security: 'is_authenticated()',
39+
provider: ContentNodeCollectionProvider::class
3840
),
3941
new Post(
4042
processor: MultiSelectCreateProcessor::class,

api/src/Entity/ContentNode/ResponsiveLayout.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use App\Entity\SupportsContentNodeChildren;
1414
use App\Repository\ResponsiveLayoutRepository;
1515
use App\State\ContentNode\ContentNodePersistProcessor;
16+
use App\State\ContentNodeCollectionProvider;
1617
use App\Validator\AssertJsonSchema;
1718
use App\Validator\ColumnLayout\AssertNoOrphanChildren;
1819
use Doctrine\Common\Collections\ArrayCollection;
@@ -37,7 +38,8 @@
3738
security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null'
3839
),
3940
new GetCollection(
40-
security: 'is_authenticated()'
41+
security: 'is_authenticated()',
42+
provider: ContentNodeCollectionProvider::class
4143
),
4244
new Post(
4345
processor: ContentNodePersistProcessor::class,

api/src/Entity/ContentNode/SingleText.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use App\Entity\ContentNode;
1313
use App\Repository\SingleTextRepository;
1414
use App\State\ContentNode\SingleTextPersistProcessor;
15+
use App\State\ContentNodeCollectionProvider;
1516
use App\Validator\AssertJsonSchema;
1617
use Doctrine\ORM\Mapping as ORM;
1718
use Symfony\Component\Serializer\Annotation\Groups;
@@ -33,7 +34,8 @@
3334
security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null'
3435
),
3536
new GetCollection(
36-
security: 'is_authenticated()'
37+
security: 'is_authenticated()',
38+
provider: ContentNodeCollectionProvider::class
3739
),
3840
new Post(
3941
processor: SingleTextPersistProcessor::class,

api/src/Entity/ContentNode/Storyboard.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use App\Entity\ContentNode;
1313
use App\Repository\StoryboardRepository;
1414
use App\State\ContentNode\StoryboardPersistProcessor;
15+
use App\State\ContentNodeCollectionProvider;
1516
use App\Validator\AssertJsonSchema;
1617
use Doctrine\ORM\Mapping as ORM;
1718
use Symfony\Component\Serializer\Annotation\Groups;
@@ -33,7 +34,8 @@
3334
security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null'
3435
),
3536
new GetCollection(
36-
security: 'is_authenticated()'
37+
security: 'is_authenticated()',
38+
provider: ContentNodeCollectionProvider::class
3739
),
3840
new Post(
3941
processor: StoryboardPersistProcessor::class,

api/tests/Api/ContentNodes/ChecklistNode/ListChecklistNodeTest.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,22 @@ class ListChecklistNodeTest extends ListContentNodeTestCase {
1111
public function setUp(): void {
1212
parent::setUp();
1313

14-
$this->endpoint = '/content_node/checklist_nodes';
14+
$this->endpointBase = '/content_node/checklist_nodes';
1515

16-
$this->contentNodesCamp1and2 = [
16+
$this->contentNodesCamp1 = [
1717
$this->getIriFor('checklistNode1'),
1818
$this->getIriFor('checklistNode3'),
1919
];
20-
20+
$this->contentNodesCamp2 = [
21+
// none
22+
];
2123
$this->contentNodesCampUnrelated = [
2224
$this->getIriFor('checklistNodeCampUnrelated'),
2325
];
24-
25-
$this->contentNodesPublicCamps = [
26+
$this->contentNodesCampPrototype = [
2627
$this->getIriFor('checklistNodeCampPrototype'),
28+
];
29+
$this->contentNodesCampShared = [
2730
$this->getIriFor('checklistNodeCampShared'),
2831
];
2932
}

api/tests/Api/ContentNodes/ColumnLayout/ListColumnLayoutTest.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,27 @@ class ListColumnLayoutTest extends ListContentNodeTestCase {
1111
public function setUp(): void {
1212
parent::setUp();
1313

14-
$this->endpoint = '/content_node/column_layouts';
14+
$this->endpointBase = '/content_node/column_layouts';
1515

16-
$this->contentNodesCamp1and2 = [
16+
$this->contentNodesCamp1 = [
1717
$this->getIriFor('columnLayout1'),
18-
$this->getIriFor('columnLayout2'),
1918
$this->getIriFor('columnLayoutChild1'),
20-
$this->getIriFor('columnLayout2Child1'),
2119
$this->getIriFor('columnLayout3'),
22-
$this->getIriFor('columnLayout4'),
23-
$this->getIriFor('columnLayout5'),
20+
];
21+
$this->contentNodesCamp2 = [
2422
$this->getIriFor('columnLayout1camp2'),
25-
$this->getIriFor('columnLayout2camp2'),
2623
];
2724

2825
$this->contentNodesCampUnrelated = [
2926
$this->getIriFor('columnLayout1campUnrelated'),
30-
$this->getIriFor('columnLayout2campUnrelated'),
3127
];
3228

33-
$this->contentNodesPublicCamps = [
29+
$this->contentNodesCampPrototype = [
3430
$this->getIriFor('columnLayout1campPrototype'),
35-
$this->getIriFor('columnLayout2campPrototype'),
3631
$this->getIriFor('columnLayout3campPrototype'),
32+
];
33+
$this->contentNodesCampShared = [
3734
$this->getIriFor('columnLayout1campShared'),
38-
$this->getIriFor('columnLayout2campShared'),
3935
$this->getIriFor('columnLayout3campShared'),
4036
];
4137
}

api/tests/Api/ContentNodes/ListContentNodeTestCase.php

Lines changed: 114 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,25 @@
1313
* @internal
1414
*/
1515
abstract class ListContentNodeTestCase extends ECampApiTestCase {
16+
protected string $endpointBase = '';
17+
1618
// content nodes visible for user 1, 2, 3
17-
protected array $contentNodesCamp1and2 = [];
19+
protected array $contentNodesCamp1 = [];
20+
protected array $contentNodesCamp2 = [];
1821

1922
// content nodes visislb for user 4
2023
protected array $contentNodesCampUnrelated = [];
2124

2225
// content nodes visible for everyone
23-
protected array $contentNodesPublicCamps = [];
26+
protected array $contentNodesCampPrototype = [];
27+
protected array $contentNodesCampShared = [];
2428

2529
public function setUp(): void {
2630
parent::setUp();
2731
}
2832

2933
public function testListForAnonymousUser() {
34+
$this->endpoint = $this->endpointBase;
3035
static::createBasicClient()->request('GET', $this->endpoint);
3136
$this->assertResponseStatusCodeSame(401);
3237
$this->assertJsonContains([
@@ -36,38 +41,139 @@ public function testListForAnonymousUser() {
3641
}
3742

3843
public function testListForInvitedCollaborator() {
44+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campPrototype');
45+
$response = $this->list(user: static::$fixtures['user6invited']);
46+
$this->assertResponseStatusCodeSame(200);
47+
$this->assertJsonContainsItems($response, $this->contentNodesCampPrototype);
48+
49+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campShared');
3950
$response = $this->list(user: static::$fixtures['user6invited']);
4051
$this->assertResponseStatusCodeSame(200);
41-
$this->assertJsonContainsItems($response, $this->contentNodesPublicCamps);
52+
$this->assertJsonContainsItems($response, $this->contentNodesCampShared);
53+
54+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated');
55+
$response = $this->list(user: static::$fixtures['user6invited']);
56+
$this->assertResponseStatusCodeSame(400);
57+
$this->assertJsonContains(['status' => 400]);
4258
}
4359

4460
public function testListForInactiveCollaborator() {
61+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campPrototype');
4562
$response = $this->list(user: static::$fixtures['user5inactive']);
4663
$this->assertResponseStatusCodeSame(200);
47-
$this->assertJsonContainsItems($response, $this->contentNodesPublicCamps);
64+
$this->assertJsonContainsItems($response, $this->contentNodesCampPrototype);
65+
66+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campShared');
67+
$response = $this->list(user: static::$fixtures['user5inactive']);
68+
$this->assertResponseStatusCodeSame(200);
69+
$this->assertJsonContainsItems($response, $this->contentNodesCampShared);
70+
71+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated');
72+
$response = $this->list(user: static::$fixtures['user5inactive']);
73+
$this->assertResponseStatusCodeSame(400);
74+
$this->assertJsonContains(['status' => 400]);
4875
}
4976

5077
public function testListForUnrelatedUser() {
78+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated');
79+
$response = $this->list(user: static::$fixtures['user4unrelated']);
80+
$this->assertResponseStatusCodeSame(200);
81+
$this->assertJsonContainsItems($response, $this->contentNodesCampUnrelated);
82+
83+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campPrototype');
84+
$response = $this->list(user: static::$fixtures['user4unrelated']);
85+
$this->assertResponseStatusCodeSame(200);
86+
$this->assertJsonContainsItems($response, $this->contentNodesCampPrototype);
87+
88+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campShared');
5189
$response = $this->list(user: static::$fixtures['user4unrelated']);
5290
$this->assertResponseStatusCodeSame(200);
53-
$this->assertJsonContainsItems($response, array_merge($this->contentNodesCampUnrelated, $this->contentNodesPublicCamps));
91+
$this->assertJsonContainsItems($response, $this->contentNodesCampShared);
92+
93+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('camp1');
94+
$response = $this->list(user: static::$fixtures['user4unrelated']);
95+
$this->assertResponseStatusCodeSame(400);
96+
$this->assertJsonContains(['status' => 400]);
5497
}
5598

5699
public function testListForGuest() {
100+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('camp1');
101+
$response = $this->list(user: static::$fixtures['user3guest']);
102+
$this->assertResponseStatusCodeSame(200);
103+
$this->assertJsonContainsItems($response, $this->contentNodesCamp1);
104+
105+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('camp2');
106+
$response = $this->list(user: static::$fixtures['user3guest']);
107+
$this->assertResponseStatusCodeSame(200);
108+
$this->assertJsonContainsItems($response, $this->contentNodesCamp2);
109+
110+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campPrototype');
111+
$response = $this->list(user: static::$fixtures['user3guest']);
112+
$this->assertResponseStatusCodeSame(200);
113+
$this->assertJsonContainsItems($response, $this->contentNodesCampPrototype);
114+
115+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campShared');
57116
$response = $this->list(user: static::$fixtures['user3guest']);
58117
$this->assertResponseStatusCodeSame(200);
59-
$this->assertJsonContainsItems($response, array_merge($this->contentNodesCamp1and2, $this->contentNodesPublicCamps));
118+
$this->assertJsonContainsItems($response, $this->contentNodesCampShared);
119+
120+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated');
121+
$response = $this->list(user: static::$fixtures['user3guest']);
122+
$this->assertResponseStatusCodeSame(400);
123+
$this->assertJsonContains(['status' => 400]);
60124
}
61125

62126
public function testListForMember() {
127+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('camp1');
128+
$response = $this->list(user: static::$fixtures['user2member']);
129+
$this->assertResponseStatusCodeSame(200);
130+
$this->assertJsonContainsItems($response, $this->contentNodesCamp1);
131+
132+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('camp2');
133+
$response = $this->list(user: static::$fixtures['user2member']);
134+
$this->assertResponseStatusCodeSame(200);
135+
$this->assertJsonContainsItems($response, $this->contentNodesCamp2);
136+
137+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campPrototype');
138+
$response = $this->list(user: static::$fixtures['user2member']);
139+
$this->assertResponseStatusCodeSame(200);
140+
$this->assertJsonContainsItems($response, $this->contentNodesCampPrototype);
141+
142+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campShared');
63143
$response = $this->list(user: static::$fixtures['user2member']);
64144
$this->assertResponseStatusCodeSame(200);
65-
$this->assertJsonContainsItems($response, array_merge($this->contentNodesCamp1and2, $this->contentNodesPublicCamps));
145+
$this->assertJsonContainsItems($response, $this->contentNodesCampShared);
146+
147+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated');
148+
$response = $this->list(user: static::$fixtures['user2member']);
149+
$this->assertResponseStatusCodeSame(400);
150+
$this->assertJsonContains(['status' => 400]);
66151
}
67152

68153
public function testListForManager() {
154+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('camp1');
69155
$response = $this->list(user: static::$fixtures['user1manager']);
70156
$this->assertResponseStatusCodeSame(200);
71-
$this->assertJsonContainsItems($response, array_merge($this->contentNodesCamp1and2, $this->contentNodesPublicCamps));
157+
$this->assertJsonContainsItems($response, $this->contentNodesCamp1);
158+
159+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('camp2');
160+
$response = $this->list(user: static::$fixtures['user1manager']);
161+
$this->assertResponseStatusCodeSame(200);
162+
$this->assertJsonContainsItems($response, $this->contentNodesCamp2);
163+
164+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campPrototype');
165+
$response = $this->list(user: static::$fixtures['user1manager']);
166+
$this->assertResponseStatusCodeSame(200);
167+
$this->assertJsonContainsItems($response, $this->contentNodesCampPrototype);
168+
169+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campShared');
170+
$response = $this->list(user: static::$fixtures['user1manager']);
171+
$this->assertResponseStatusCodeSame(200);
172+
$this->assertJsonContainsItems($response, $this->contentNodesCampShared);
173+
174+
$this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated');
175+
$response = $this->list(user: static::$fixtures['user1manager']);
176+
$this->assertResponseStatusCodeSame(400);
177+
$this->assertJsonContains(['status' => 400]);
72178
}
73179
}

0 commit comments

Comments
 (0)