Skip to content

Commit f913bbf

Browse files
Support for saving members attribute upon group create (and similar cases) (limosa-io#100)
1 parent d634f0f commit f913bbf

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

src/Attribute/MutableCollection.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,28 @@ public function replace($value, Model &$object, ?Path $path = null)
4646

4747
// Check if objects exist
4848
$existingObjects = $object
49-
->{$this->attribute}()
50-
->getRelated()
51-
::findMany($values)
49+
->{$this->attribute}()
50+
->getRelated()
51+
::findMany($values);
52+
$existingObjectIds = $existingObjects
5253
->map(fn ($o) => $o->getKey());
5354

54-
if (($diff = collect($values)->diff($existingObjects))->count() > 0) {
55+
if (($diff = collect($values)->diff($existingObjectIds))->count() > 0) {
5556
throw new SCIMException(
5657
sprintf('One or more %s are unknown: %s', $this->attribute, implode(',', $diff->all())),
5758
500
5859
);
5960
}
6061

61-
$object->{$this->attribute}()->sync($existingObjects->all());
62+
// Act like the relation is already saved. This allows running validations, if needed.
63+
$object->setRelation($this->attribute, $existingObjects);
64+
65+
$object->saved(function (Model $model) use ($object, $existingObjectIds) {
66+
// Save relationships only after the model is saved. Essential if the model is new.
67+
// Intentionlly `$object` is used instead of `$model`, to avoid accidentially updating the wrong model.
68+
$object->{$this->attribute}()->sync($existingObjectIds->all());
69+
});
70+
6271
}
6372

6473
public function patch($operation, $value, Model &$object, ?Path $path = null)

tests/GroupsTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace ArieTimmerman\Laravel\SCIMServer\Tests;
44

55
use ArieTimmerman\Laravel\SCIMServer\Tests\Model\Group;
6+
use ArieTimmerman\Laravel\SCIMServer\Tests\Model\User;
67
use Illuminate\Database\Schema\Blueprint;
78
use Illuminate\Support\Facades\Schema;
89

@@ -69,6 +70,37 @@ public function testCreate(){
6970

7071
}
7172

73+
public function testCreateWithMembers(){
74+
$response = $this->post('/scim/v2/Groups', [
75+
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:Group'], // Required
76+
'urn:ietf:params:scim:schemas:core:2.0:Group' => [
77+
'displayName' => 'TestGroup',
78+
'members' => [
79+
[
80+
'value' => User::first()->id,
81+
]
82+
]
83+
]
84+
]);
85+
86+
$response->assertJsonStructure([
87+
'id',
88+
'urn:ietf:params:scim:schemas:core:2.0:Group' => [
89+
'displayName',
90+
'members' => [
91+
0 => [
92+
'value',
93+
'display'
94+
]
95+
]
96+
]
97+
]);
98+
99+
$this->assertEquals(User::first()->id, $response->json(['urn:ietf:params:scim:schemas:core:2.0:Group'])['members'][0]['value']);
100+
$this->assertNotNull(Group::find($response->json('id')));
101+
$this->assertNotNull(Group::where('displayName', 'TestGroup')->first());
102+
}
103+
72104
public function testBulk(){
73105
$response = $this->post('/scim/v2/Bulk', [
74106
'schemas' => ['urn:ietf:params:scim:api:messages:2.0:BulkRequest'], // Required

0 commit comments

Comments
 (0)