scimaenaga 0.6.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -0
  3. data/app/controllers/concerns/scim_rails/exception_handler.rb +74 -22
  4. data/app/controllers/scim_rails/scim_groups_controller.rb +14 -3
  5. data/app/controllers/scim_rails/scim_schemas_controller.rb +42 -0
  6. data/app/controllers/scim_rails/scim_users_controller.rb +22 -4
  7. data/app/libraries/scim_patch.rb +15 -9
  8. data/app/libraries/scim_patch_operation.rb +50 -71
  9. data/app/libraries/scim_patch_operation_converter.rb +90 -0
  10. data/app/libraries/scim_patch_operation_group.rb +100 -0
  11. data/app/libraries/scim_patch_operation_user.rb +53 -0
  12. data/config/routes.rb +14 -11
  13. data/lib/generators/scim_rails/templates/initializer.rb +106 -0
  14. data/lib/scim_rails/config.rb +8 -5
  15. data/lib/scim_rails/version.rb +1 -1
  16. data/spec/controllers/scim_rails/scim_groups_controller_spec.rb +25 -7
  17. data/spec/controllers/scim_rails/scim_schemas_controller_spec.rb +238 -0
  18. data/spec/controllers/scim_rails/scim_schemas_request_spec.rb +39 -0
  19. data/spec/controllers/scim_rails/scim_users_controller_spec.rb +361 -220
  20. data/spec/dummy/app/models/user.rb +9 -0
  21. data/spec/dummy/config/initializers/scim_rails_config.rb +27 -24
  22. data/spec/dummy/db/migrate/20220131090107_add_deletable_to_users.rb +5 -0
  23. data/spec/dummy/db/schema.rb +2 -1
  24. data/spec/dummy/db/seeds.rb +10 -1
  25. data/spec/factories/user.rb +2 -0
  26. data/spec/libraries/scim_patch_operation_group_spec.rb +165 -0
  27. data/spec/libraries/scim_patch_operation_user_spec.rb +101 -0
  28. data/spec/libraries/scim_patch_spec.rb +135 -53
  29. metadata +80 -80
  30. data/spec/dummy/db/development.sqlite3 +0 -0
  31. data/spec/dummy/db/test.sqlite3 +0 -0
  32. data/spec/dummy/log/development.log +0 -0
  33. data/spec/dummy/log/test.log +0 -377
  34. data/spec/dummy/put_group.http +0 -5
  35. data/spec/dummy/tmp/restart.txt +0 -0
  36. data/spec/libraries/scim_patch_operation_spec.rb +0 -96
@@ -3,6 +3,8 @@ class User < ApplicationRecord
3
3
  has_many :group_users
4
4
  has_many :groups, through: :group_users
5
5
 
6
+ before_destroy :check_deletable
7
+
6
8
  validates \
7
9
  :first_name,
8
10
  :last_name,
@@ -48,4 +50,11 @@ class User < ApplicationRecord
48
50
  write_attribute(:archived_at, nil)
49
51
  save!
50
52
  end
53
+
54
+ def check_deletable
55
+ return if deletable
56
+
57
+ errors.add(:base, 'The specified user could not be deleted.')
58
+ throw :abort
59
+ end
51
60
  end
@@ -1,7 +1,7 @@
1
1
  ScimRails.configure do |config|
2
- config.basic_auth_model = "Company"
3
- config.scim_users_model = "User"
4
- config.scim_groups_model = "Group"
2
+ config.basic_auth_model = 'Company'
3
+ config.scim_users_model = 'User'
4
+ config.scim_groups_model = 'Group'
5
5
 
6
6
  config.basic_auth_model_searchable_attribute = :subdomain
7
7
  config.basic_auth_model_authenticatable_attribute = :api_token
@@ -9,54 +9,57 @@ ScimRails.configure do |config|
9
9
  config.scim_users_list_order = :id
10
10
  config.scim_groups_scope = :groups
11
11
 
12
- config.signing_algorithm = "HS256"
13
- config.signing_secret = "2d6806dd11c2fece2e81b8ca76dcb0062f5b08e28e3264e8ba1c44bbd3578b70"
12
+ config.signing_algorithm = 'HS256'
13
+ config.signing_secret = '2d6806dd11c2fece2e81b8ca76dcb0062f5b08e28e3264e8ba1c44bbd3578b70'
14
14
 
15
- config.mutable_user_attributes = [
16
- :first_name,
17
- :last_name,
18
- :email,
19
- :active
15
+ config.user_destroy_method = :destroy!
16
+ config.group_destroy_method = :destroy!
17
+
18
+ config.mutable_user_attributes = %i[
19
+ first_name
20
+ last_name
21
+ email
22
+ active
20
23
  ]
21
24
 
22
25
  config.queryable_user_attributes = {
23
26
  userName: :email,
24
27
  givenName: :first_name,
25
28
  familyName: :last_name,
26
- email: :email
29
+ email: :email,
27
30
  }
28
31
 
29
32
  config.mutable_user_attributes_schema = {
30
33
  name: {
31
34
  givenName: :first_name,
32
- familyName: :last_name
35
+ familyName: :last_name,
33
36
  },
34
37
  emails: [
35
38
  {
36
- value: :email
39
+ value: :email,
37
40
  }
38
41
  ],
39
- active: :active
42
+ active: :active,
40
43
  }
41
44
 
42
45
  config.user_schema = {
43
- schemas: ["urn:ietf:params:scim:schemas:core:2.0:User"],
46
+ schemas: ['urn:ietf:params:scim:schemas:core:2.0:User'],
44
47
  id: :id,
45
48
  userName: :email,
46
49
  name: {
47
50
  givenName: :first_name,
48
- familyName: :last_name
51
+ familyName: :last_name,
49
52
  },
50
53
  emails: [
51
54
  {
52
- value: :email
53
- },
55
+ value: :email,
56
+ }
54
57
  ],
55
- active: :unarchived?
58
+ active: :unarchived?,
56
59
  }
57
60
 
58
61
  config.queryable_group_attributes = {
59
- displayName: :name
62
+ displayName: :name,
60
63
  }
61
64
 
62
65
  config.mutable_group_attributes = [
@@ -64,21 +67,21 @@ ScimRails.configure do |config|
64
67
  ]
65
68
 
66
69
  config.mutable_group_attributes_schema = {
67
- displayName: :name
70
+ displayName: :name,
68
71
  }
69
72
 
70
73
  config.group_member_relation_attribute = :user_ids
71
74
  config.group_member_relation_schema = { value: :user_ids }
72
75
 
73
76
  config.group_schema = {
74
- schemas: ["urn:ietf:params:scim:schemas:core:2.0:Group"],
77
+ schemas: ['urn:ietf:params:scim:schemas:core:2.0:Group'],
75
78
  id: :id,
76
79
  displayName: :name,
77
- members: :users
80
+ members: :users,
78
81
  }
79
82
 
80
83
  config.group_abbreviated_schema = {
81
84
  value: :id,
82
- display: :name
85
+ display: :name,
83
86
  }
84
87
  end
@@ -0,0 +1,5 @@
1
+ class AddDeletableToUsers < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :users, :deletable, :boolean
4
+ end
5
+ end
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 2022_01_17_095407) do
13
+ ActiveRecord::Schema.define(version: 2022_01_31_090107) do
14
14
 
15
15
  create_table "companies", force: :cascade do |t|
16
16
  t.string "name", null: false
@@ -46,6 +46,7 @@ ActiveRecord::Schema.define(version: 2022_01_17_095407) do
46
46
  t.datetime "created_at", null: false
47
47
  t.datetime "updated_at", null: false
48
48
  t.string "country"
49
+ t.boolean "deletable"
49
50
  end
50
51
 
51
52
  add_foreign_key "group_users", "groups"
@@ -9,11 +9,20 @@ group = Group.create(
9
9
  name: 'Test Group'
10
10
  )
11
11
 
12
+ User.create(
13
+ company: company,
14
+ first_name: 'scim',
15
+ last_name: 'owner',
16
+ email: 'owner@example.com',
17
+ deletable: false
18
+ )
19
+
12
20
  1.upto(1000) do |n|
13
21
  User.create(
14
22
  company: company,
15
23
  first_name: "Test#{n}",
16
24
  last_name: "User#{n}",
17
- email: "#{n}@example.com"
25
+ email: "#{n}@example.com",
26
+ deletable: true
18
27
  )
19
28
  end
@@ -5,5 +5,7 @@ FactoryBot.define do
5
5
  first_name { "Test" }
6
6
  last_name { "User" }
7
7
  sequence(:email) { |n| "#{n}@example.com" }
8
+
9
+ deletable { true }
8
10
  end
9
11
  end
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ScimPatchOperationGroup do
6
+ let(:op) { 'replace' }
7
+ let(:path) { 'displayName' }
8
+ let(:value) { 'groupA' }
9
+ let(:mutable_attributes_schema) { { displayName: :name } }
10
+ let(:group_member_relation_attribute) { :user_ids }
11
+
12
+ let(:user1) { create(:user) }
13
+ let(:user2) { create(:user) }
14
+ let(:user3) { create(:user) }
15
+ let(:user4) { create(:user) }
16
+ let(:group) { create(:group, users: [user1, user2]) }
17
+
18
+ let(:operation) do
19
+ described_class.new(
20
+ op,
21
+ path,
22
+ value
23
+ )
24
+ end
25
+ context 'replace displayName' do
26
+ it {
27
+ allow(ScimRails.config).to(
28
+ receive(:mutable_group_attributes_schema).and_return(mutable_attributes_schema)
29
+ )
30
+ allow(ScimRails.config).to(
31
+ receive(:group_member_relation_attribute).and_return(group_member_relation_attribute)
32
+ )
33
+ expect(operation.op).to eq 'replace'
34
+ expect(operation.path_scim).to eq(attribute: path, rest_path: [])
35
+ expect(operation.path_sp).to eq :name
36
+ expect(operation.value).to eq value
37
+
38
+ operation.save(group)
39
+ expect(group.name).to eq value
40
+ }
41
+ end
42
+
43
+ context 'add displayName' do
44
+ let(:op) { 'add' }
45
+ it {
46
+ allow(ScimRails.config).to(
47
+ receive(:mutable_group_attributes_schema).and_return(mutable_attributes_schema)
48
+ )
49
+ allow(ScimRails.config).to(
50
+ receive(:group_member_relation_attribute).and_return(group_member_relation_attribute)
51
+ )
52
+ expect(operation.op).to eq 'add'
53
+ expect(operation.path_scim).to eq(attribute: path, rest_path: [])
54
+ expect(operation.path_sp).to eq :name
55
+ expect(operation.value).to eq value
56
+
57
+ operation.save(group)
58
+ expect(group.name).to eq value
59
+ }
60
+ end
61
+
62
+ context 'remove displayName' do
63
+ let(:op) { 'remove' }
64
+ it {
65
+ allow(ScimRails.config).to(
66
+ receive(:mutable_group_attributes_schema).and_return(mutable_attributes_schema)
67
+ )
68
+ allow(ScimRails.config).to(
69
+ receive(:group_member_relation_attribute).and_return(group_member_relation_attribute)
70
+ )
71
+ expect(operation.op).to eq 'remove'
72
+ expect(operation.path_scim).to eq(attribute: path, rest_path: [])
73
+ expect(operation.path_sp).to eq :name
74
+ expect(operation.value).to eq value
75
+
76
+ operation.save(group)
77
+ expect(group.name).to eq nil
78
+ }
79
+ end
80
+
81
+ context 'add member' do
82
+ let(:op) { 'add' }
83
+ let(:path) { 'members' }
84
+ let(:value) { [{ 'value' => user3.id.to_s }, { 'value' => user4.id.to_s }] }
85
+ it {
86
+ allow(ScimRails.config).to(
87
+ receive(:mutable_group_attributes_schema).and_return(mutable_attributes_schema)
88
+ )
89
+ allow(ScimRails.config).to(
90
+ receive(:group_member_relation_attribute).and_return(group_member_relation_attribute)
91
+ )
92
+ expect(operation.op).to eq 'add'
93
+ expect(operation.path_scim).to eq(attribute: 'members', rest_path: [])
94
+ expect(operation.path_sp).to eq :user_ids
95
+ expect(operation.value).to eq value
96
+
97
+ operation.save(group)
98
+ expect(group.users).to eq [user1, user2, user3, user4]
99
+ }
100
+ end
101
+
102
+ context 'replace member' do
103
+ let(:op) { 'replace' }
104
+ let(:path) { 'members' }
105
+ let(:value) { [{ 'value' => user3.id.to_s }, { 'value' => user4.id.to_s }] }
106
+ it {
107
+ allow(ScimRails.config).to(
108
+ receive(:mutable_group_attributes_schema).and_return(mutable_attributes_schema)
109
+ )
110
+ allow(ScimRails.config).to(
111
+ receive(:group_member_relation_attribute).and_return(group_member_relation_attribute)
112
+ )
113
+ expect(operation.op).to eq 'replace'
114
+ expect(operation.path_scim).to eq(attribute: 'members', rest_path: [])
115
+ expect(operation.path_sp).to eq :user_ids
116
+ expect(operation.value).to eq value
117
+
118
+ operation.save(group)
119
+ expect(group.users).to eq [user3, user4]
120
+ }
121
+ end
122
+
123
+ context 'remove user ids' do
124
+ let(:op) { 'remove' }
125
+ let(:path) { 'members' }
126
+ let(:value) { [{ 'value' => user1.id.to_s }, { 'value' => user2.id.to_s }] }
127
+ it {
128
+ allow(ScimRails.config).to(
129
+ receive(:mutable_group_attributes_schema).and_return(mutable_attributes_schema)
130
+ )
131
+ allow(ScimRails.config).to(
132
+ receive(:group_member_relation_attribute).and_return(group_member_relation_attribute)
133
+ )
134
+ expect(operation.op).to eq 'remove'
135
+ expect(operation.path_scim).to eq(attribute: 'members', rest_path: [])
136
+ expect(operation.path_sp).to eq :user_ids
137
+ expect(operation.value).to eq value
138
+
139
+ operation.save(group)
140
+ expect(group.users).to eq []
141
+ }
142
+ end
143
+
144
+ context 'remove user id (with filter)' do
145
+ let(:op) { 'remove' }
146
+ let(:path) { "members[value eq \"#{user1.id}\"]" }
147
+ let(:value) { nil }
148
+ it {
149
+ allow(ScimRails.config).to(
150
+ receive(:mutable_group_attributes_schema).and_return(mutable_attributes_schema)
151
+ )
152
+ allow(ScimRails.config).to(
153
+ receive(:group_member_relation_attribute).and_return(group_member_relation_attribute)
154
+ )
155
+ expect(operation.op).to eq 'remove'
156
+ expect(operation.path_scim).to eq(attribute: 'members',
157
+ filter: { attribute: 'value', operator: 'eq', parameter: user1.id.to_s }, rest_path: [])
158
+ expect(operation.path_sp).to eq :user_ids
159
+ expect(operation.value).to eq nil
160
+
161
+ operation.save(group)
162
+ expect(group.users).to eq [user2]
163
+ }
164
+ end
165
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ScimPatchOperationUser do
6
+ let(:op) { 'replace' }
7
+ let(:path) { 'userName' }
8
+ let(:value) { 'taro.suzuki' }
9
+ let(:mutable_attributes_schema) do
10
+ {
11
+ userName: :name,
12
+ displayName: :display_name,
13
+ emails: [
14
+ {
15
+ value: :email,
16
+ }
17
+ ],
18
+ name: {
19
+ familyName: :family_name,
20
+ givenName: :given_name,
21
+ },
22
+ active: :active,
23
+ }
24
+ end
25
+
26
+ let(:operation) do
27
+ described_class.new(
28
+ op,
29
+ path,
30
+ value
31
+ )
32
+ end
33
+ describe '#initialize' do
34
+ context 'replace single attribute' do
35
+ it {
36
+ allow(ScimRails.config).to(
37
+ receive(:mutable_user_attributes_schema).and_return(mutable_attributes_schema)
38
+ )
39
+ expect(operation.op).to eq 'replace'
40
+ expect(operation.path_scim).to eq(attribute: path, rest_path: [])
41
+ expect(operation.path_sp).to eq :name
42
+ expect(operation.value).to eq value
43
+ }
44
+ end
45
+
46
+ context 'add single attribute' do
47
+ let(:op) { 'add' }
48
+ it {
49
+ allow(ScimRails.config).to(
50
+ receive(:mutable_user_attributes_schema).and_return(mutable_attributes_schema)
51
+ )
52
+ expect(operation.op).to eq 'add'
53
+ expect(operation.path_scim).to eq(attribute: path, rest_path: [])
54
+ expect(operation.path_sp).to eq :name
55
+ expect(operation.value).to eq value
56
+ }
57
+ end
58
+
59
+ context 'remove single attribute' do
60
+ let(:op) { 'remove' }
61
+ it {
62
+ allow(ScimRails.config).to(
63
+ receive(:mutable_user_attributes_schema).and_return(mutable_attributes_schema)
64
+ )
65
+ expect(operation.op).to eq 'remove'
66
+ expect(operation.path_scim).to eq(attribute: path, rest_path: [])
67
+ expect(operation.path_sp).to eq :name
68
+ expect(operation.value).to eq value
69
+ }
70
+ end
71
+
72
+ context 'replace email address' do
73
+ let(:path) { 'emails[type eq "work"].value' }
74
+ let(:value) { 'taro.suzuki@example.com' }
75
+ it {
76
+ allow(ScimRails.config).to(
77
+ receive(:mutable_user_attributes_schema).and_return(mutable_attributes_schema)
78
+ )
79
+ expect(operation.op).to eq 'replace'
80
+ expect(operation.path_scim).to eq(attribute: 'emails',
81
+ filter: { attribute: 'type', operator: 'eq', parameter: 'work' }, rest_path: ['value'])
82
+ expect(operation.path_sp).to eq :email
83
+ expect(operation.value).to eq value
84
+ }
85
+ end
86
+
87
+ context 'replace name.familyName' do
88
+ let(:path) { 'name.familyName' }
89
+ let(:value) { 'Suzuki' }
90
+ it {
91
+ allow(ScimRails.config).to(
92
+ receive(:mutable_user_attributes_schema).and_return(mutable_attributes_schema)
93
+ )
94
+ expect(operation.op).to eq 'replace'
95
+ expect(operation.path_scim).to eq(attribute: 'name', rest_path: ['familyName'])
96
+ expect(operation.path_sp).to eq :family_name
97
+ expect(operation.value).to eq value
98
+ }
99
+ end
100
+ end
101
+ end
@@ -3,81 +3,163 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe ScimPatch do
6
+ shared_examples :user do
7
+ let(:patch) { ScimPatch.new(params, :user) }
8
+ it {
9
+ allow(ScimRails.config).to(
10
+ receive(:mutable_user_attributes_schema).and_return(mutable_user_attributes_schema)
11
+ )
6
12
 
7
- let(:params) {
8
- {
9
- 'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
10
- 'Operations' => [
11
- {
12
- 'op' => 'Replace',
13
- 'path' => 'userName',
14
- 'value' => 'taro.suzuki'
15
- },
16
- {
17
- 'op' => 'Replace',
18
- 'path' => 'emails[type eq "work"].value',
19
- 'value' => 'taro.suzuki@example.com'
20
- },
21
- {
22
- 'op' => 'Replace',
23
- 'path' => 'name.familyName',
24
- 'value' => 'Suzuki'
25
- },
26
- {
27
- 'op' => 'Replace',
28
- 'path' => 'active',
29
- 'value' => 'False'
30
- }
31
- ]
13
+ expect(patch.operations[0].op).to eq 'replace'
14
+ expect(patch.operations[0].path_scim).to eq(attribute: 'emails',
15
+ filter: { attribute: 'type', operator: 'eq', parameter: 'work' }, rest_path: ['value'])
16
+ expect(patch.operations[0].path_sp).to eq :email
17
+ expect(patch.operations[0].value).to eq 'taro.suzuki@example.com'
18
+
19
+ expect(patch.operations[1].op).to eq 'replace'
20
+ expect(patch.operations[1].path_scim).to eq(attribute: 'userName', rest_path: [])
21
+ expect(patch.operations[1].path_sp).to eq :name
22
+ expect(patch.operations[1].value).to eq 'taro.suzuki'
23
+
24
+ expect(patch.operations[2].op).to eq 'replace'
25
+ expect(patch.operations[2].path_scim).to eq(attribute: 'name',
26
+ rest_path: ['familyName'])
27
+ expect(patch.operations[2].path_sp).to eq :family_name
28
+ expect(patch.operations[2].value).to eq 'Suzuki'
29
+
30
+ expect(patch.operations[3].op).to eq 'replace'
31
+ expect(patch.operations[3].path_scim).to eq(attribute: 'active',
32
+ rest_path: [])
33
+ expect(patch.operations[3].path_sp).to eq :active
34
+ expect(patch.operations[3].value).to eq false
32
35
  }
33
- }
36
+ end
34
37
 
35
- let(:mutable_attributes_schema) {
38
+ let(:mutable_user_attributes_schema) do
36
39
  {
37
40
  userName: :name,
38
41
  displayName: :display_name,
39
42
  emails: [
40
43
  {
41
- value: :email
44
+ value: :email,
42
45
  }
43
46
  ],
44
47
  name: {
45
48
  familyName: :family_name,
46
- givenName: :given_name
49
+ givenName: :given_name,
47
50
  },
48
- active: :active
51
+ active: :active,
52
+ }
53
+ end
54
+
55
+ let(:mutable_group_attributes_schema) do
56
+ {
57
+ displayName: :name,
49
58
  }
50
- }
59
+ end
51
60
 
52
- let(:patch) { described_class.new(params, mutable_attributes_schema) }
61
+ describe '#initialize :user' do
62
+ context :multiple_single_value_operations do
63
+ let(:params) do
64
+ {
65
+ 'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
66
+ 'Operations' => [
67
+ {
68
+ 'op' => 'Replace',
69
+ 'path' => 'emails[type eq "work"].value',
70
+ 'value' => 'taro.suzuki@example.com',
71
+ },
72
+ {
73
+ 'op' => 'Replace',
74
+ 'path' => 'userName',
75
+ 'value' => 'taro.suzuki',
76
+ },
77
+ {
78
+ 'op' => 'Replace',
79
+ 'path' => 'name.familyName',
80
+ 'value' => 'Suzuki',
81
+ },
82
+ {
83
+ 'op' => 'Replace',
84
+ 'path' => 'active',
85
+ 'value' => 'False',
86
+ }
87
+ ],
88
+ }
89
+ end
90
+ it_behaves_like :user
91
+ end
53
92
 
54
- describe '#initialize' do
55
- it {
56
- expect(patch.operations[0].op).to eq :replace
57
- expect(patch.operations[0].path_scim).to eq 'userName'
58
- expect(patch.operations[0].path_sp).to eq :name
59
- expect(patch.operations[0].value).to eq 'taro.suzuki'
93
+ context :multiple_value_operation do
94
+ let(:params) do
95
+ {
96
+ 'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
97
+ 'Operations' => [
98
+ {
99
+ 'op' => 'replace',
100
+ 'path' => 'emails[type eq "work"].value',
101
+ 'value' => 'taro.suzuki@example.com',
102
+ },
103
+ {
104
+ 'op' => 'replace',
105
+ 'value' => {
106
+ 'userName' => 'taro.suzuki',
107
+ 'name.familyName' => 'Suzuki',
108
+ 'active' => false,
109
+ },
110
+ }
111
+ ],
112
+ }
113
+ end
114
+ it_behaves_like :user
115
+ end
116
+ end
60
117
 
61
- expect(patch.operations[1].op).to eq :replace
62
- expect(patch.operations[1].path_scim).to eq 'emails[type eq "work"].value'
63
- expect(patch.operations[1].path_sp).to eq :email
64
- expect(patch.operations[1].value).to eq 'taro.suzuki@example.com'
118
+ describe '#initialize :group' do
119
+ let(:params) do
120
+ {
121
+ 'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
122
+ 'Operations' => [
123
+ {
124
+ 'op' => 'Replace',
125
+ 'path' => 'displayName',
126
+ 'value' => 'groupA',
127
+ },
128
+ {
129
+ 'op' => 'Add',
130
+ 'path' => 'members',
131
+ 'value' => [
132
+ {
133
+ 'value' => '1',
134
+ },
135
+ {
136
+ 'value' => '2',
137
+ }
138
+ ],
139
+ }
140
+ ],
141
+ }
142
+ end
143
+ let(:patch) { described_class.new(params, :group) }
144
+ it {
145
+ allow(ScimRails.config).to(
146
+ receive(:mutable_group_attributes_schema).and_return(mutable_group_attributes_schema)
147
+ )
65
148
 
66
- expect(patch.operations[2].op).to eq :replace
67
- expect(patch.operations[2].path_scim).to eq 'name.familyName'
68
- expect(patch.operations[2].path_sp).to eq :family_name
69
- expect(patch.operations[2].value).to eq 'Suzuki'
149
+ expect(patch.operations[0].op).to eq 'replace'
150
+ expect(patch.operations[0].path_scim).to eq(attribute: 'displayName', rest_path: [])
151
+ expect(patch.operations[0].path_sp).to eq :name
152
+ expect(patch.operations[0].value).to eq 'groupA'
70
153
 
71
- expect(patch.operations[3].op).to eq :replace
72
- expect(patch.operations[3].path_scim).to eq 'active'
73
- expect(patch.operations[3].path_sp).to eq :active
74
- expect(patch.operations[3].value).to eq false
154
+ expect(patch.operations[1].op).to eq 'add'
155
+ expect(patch.operations[1].path_scim).to eq(attribute: 'members', rest_path: [])
156
+ expect(patch.operations[1].path_sp).to eq :user_ids
157
+ expect(patch.operations[1].value).to eq [{ 'value' => '1' }, { 'value' => '2' }]
75
158
  }
76
159
  end
77
160
 
78
161
  # describe '#update' do
79
- # create user by factory bot
80
- # patch.update(user)
162
+ # create user by factory bot
163
+ # patch.update(user)
81
164
  # end
82
-
83
165
  end