scimitar 2.7.0 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,7 +14,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
14
14
  ids = 3.times.map { SecureRandom.uuid }.sort()
15
15
 
16
16
  @u1 = MockUser.create!(primary_key: ids.shift(), username: '1', first_name: 'Foo', last_name: 'Ark', home_email_address: 'home_1@test.com', scim_uid: '001', created_at: lmt, updated_at: lmt + 1)
17
- @u2 = MockUser.create!(primary_key: ids.shift(), username: '2', first_name: 'Foo', last_name: 'Bar', home_email_address: 'home_2@test.com', scim_uid: '002', created_at: lmt, updated_at: lmt + 2)
17
+ @u2 = MockUser.create!(primary_key: ids.shift(), username: '2', first_name: 'Foo', last_name: 'Bar', home_email_address: 'home_2@test.com', scim_uid: '002', created_at: lmt, updated_at: lmt + 2, password: 'oldpassword')
18
18
  @u3 = MockUser.create!(primary_key: ids.shift(), username: '3', first_name: 'Foo', home_email_address: 'home_3@test.com', scim_uid: '003', created_at: lmt, updated_at: lmt + 3)
19
19
 
20
20
  @g1 = MockGroup.create!(display_name: 'Group 1')
@@ -345,6 +345,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
345
345
 
346
346
  attributes = {
347
347
  userName: '4',
348
+ password: 'correcthorsebatterystaple',
348
349
  name: {
349
350
  givenName: 'Given',
350
351
  familyName: 'Family'
@@ -379,6 +380,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
379
380
  expect(result['id']).to eql(new_mock.id.to_s)
380
381
  expect(result['meta']['resourceType']).to eql('User')
381
382
  expect(new_mock.username).to eql('4')
383
+ expect(new_mock.password).to eql('correcthorsebatterystaple')
382
384
  expect(new_mock.first_name).to eql('Given')
383
385
  expect(new_mock.last_name).to eql('Family')
384
386
  expect(new_mock.home_email_address).to eql('home_4@test.com')
@@ -523,14 +525,14 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
523
525
  context '#replace' do
524
526
  shared_examples 'a replacer' do | force_upper_case: |
525
527
  it 'which replaces all attributes in an instance' do
526
- attributes = { userName: '4' } # Minimum required by schema
528
+ attributes = { userName: '4' } # Minimum required by schema
527
529
  attributes = spec_helper_hupcase(attributes) if force_upper_case
528
530
 
529
531
  # Prove that certain known pathways are called; can then unit test
530
532
  # those if need be and be sure that this covers #replace actions.
531
533
  #
532
534
  expect_any_instance_of(MockUsersController).to receive(:replace).once.and_call_original
533
- expect_any_instance_of(MockUsersController).to receive(:save! ).once.and_call_original
535
+ expect_any_instance_of(MockUsersController).to receive(:save! ).once.and_call_original
534
536
  expect {
535
537
  put "/Users/#{@u2.primary_key}", params: attributes.merge(format: :scim)
536
538
  }.to_not change { MockUser.count }
@@ -543,12 +545,44 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
543
545
  expect(result['id']).to eql(@u2.primary_key.to_s)
544
546
  expect(result['meta']['resourceType']).to eql('User')
545
547
 
548
+ expect(result).to have_key('name')
549
+ expect(result).to_not have_key('password')
550
+
546
551
  @u2.reload
547
552
 
548
553
  expect(@u2.username).to eql('4')
549
554
  expect(@u2.first_name).to be_nil
550
555
  expect(@u2.last_name).to be_nil
551
556
  expect(@u2.home_email_address).to be_nil
557
+ expect(@u2.password).to be_nil
558
+ end
559
+
560
+ it 'can replace passwords' do
561
+ attributes = { userName: '4', password: 'correcthorsebatterystaple' }
562
+ attributes = spec_helper_hupcase(attributes) if force_upper_case
563
+
564
+ expect {
565
+ put "/Users/#{@u2.primary_key}", params: attributes.merge(format: :scim)
566
+ }.to_not change { MockUser.count }
567
+
568
+ expect(response.status ).to eql(200)
569
+ expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
570
+
571
+ result = JSON.parse(response.body)
572
+
573
+ expect(result['id']).to eql(@u2.primary_key.to_s)
574
+ expect(result['meta']['resourceType']).to eql('User')
575
+
576
+ expect(result).to have_key('name')
577
+ expect(result).to_not have_key('password')
578
+
579
+ @u2.reload
580
+
581
+ expect(@u2.username).to eql('4')
582
+ expect(@u2.first_name).to be_nil
583
+ expect(@u2.last_name).to be_nil
584
+ expect(@u2.home_email_address).to be_nil
585
+ expect(@u2.password).to eql('correcthorsebatterystaple')
552
586
  end
553
587
  end # "shared_examples 'a replacer' do | force_upper_case: |"
554
588
 
@@ -626,7 +660,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
626
660
 
627
661
  context 'with a block' do
628
662
  it 'invokes the block' do
629
- attributes = { userName: '4' } # Minimum required by schema
663
+ attributes = { userName: '4' } # Minimum required by schema
630
664
 
631
665
  expect_any_instance_of(CustomReplaceMockUsersController).to receive(:replace).once.and_call_original
632
666
  expect {
@@ -681,7 +715,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
681
715
 
682
716
  context '#update' do
683
717
  shared_examples 'an updater' do | force_upper_case: |
684
- it 'which patches specific attributes' do
718
+ it 'which patches regular attributes' do
685
719
  payload = {
686
720
  Operations: [
687
721
  {
@@ -717,6 +751,9 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
717
751
  expect(result['id']).to eql(@u2.primary_key.to_s)
718
752
  expect(result['meta']['resourceType']).to eql('User')
719
753
 
754
+ expect(result).to have_key('name')
755
+ expect(result).to_not have_key('password')
756
+
720
757
  @u2.reload
721
758
 
722
759
  expect(@u2.username).to eql('4')
@@ -724,6 +761,45 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
724
761
  expect(@u2.last_name).to eql('Bar')
725
762
  expect(@u2.home_email_address).to eql('home_2@test.com')
726
763
  expect(@u2.work_email_address).to eql('work_4@test.com')
764
+ expect(@u2.password).to eql('oldpassword')
765
+ end
766
+
767
+ it 'which patches "returned: \'never\'" fields' do
768
+ payload = {
769
+ Operations: [
770
+ {
771
+ op: 'replace',
772
+ path: 'password',
773
+ value: 'correcthorsebatterystaple'
774
+ }
775
+ ]
776
+ }
777
+
778
+ payload = spec_helper_hupcase(payload) if force_upper_case
779
+
780
+ expect {
781
+ patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
782
+ }.to_not change { MockUser.count }
783
+
784
+ expect(response.status ).to eql(200)
785
+ expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
786
+
787
+ result = JSON.parse(response.body)
788
+
789
+ expect(result['id']).to eql(@u2.primary_key.to_s)
790
+ expect(result['meta']['resourceType']).to eql('User')
791
+
792
+ expect(result).to have_key('name')
793
+ expect(result).to_not have_key('password')
794
+
795
+ @u2.reload
796
+
797
+ expect(@u2.username).to eql('2')
798
+ expect(@u2.first_name).to eql('Foo')
799
+ expect(@u2.last_name).to eql('Bar')
800
+ expect(@u2.home_email_address).to eql('home_2@test.com')
801
+ expect(@u2.work_email_address).to be_nil
802
+ expect(@u2.password).to eql('correcthorsebatterystaple')
727
803
  end
728
804
 
729
805
  context 'which clears attributes' do
@@ -37,6 +37,114 @@ RSpec.describe Scimitar::Support::HashWithIndifferentCaseInsensitiveAccess do
37
37
  expect(subject()).to_not have_key('bar')
38
38
  end
39
39
  end # "context 'where keys set as symbols' do"
40
+
41
+ context 'access and merging' do
42
+ before :each do
43
+ @original_subject = subject().to_h().dup()
44
+ end
45
+
46
+ it 'returns keys as Strings' do
47
+ subject()[:foo] = 1
48
+ subject()[:BAR] = 2
49
+
50
+ expect(subject().keys).to match_array(@original_subject.keys + ['foo', 'BAR'])
51
+ end
52
+
53
+ it 'retains original case of keys' do
54
+ subject()[:foo ] = 1
55
+ subject()['FoO'] = 40 # (first-time-set case preservation test in passing)
56
+ subject()[:BAR ] = 2
57
+ subject()['Baz'] = 3
58
+
59
+ expectation = @original_subject.merge({
60
+ 'foo' => 40,
61
+ 'BAR' => 2,
62
+ 'Baz' => 3
63
+ })
64
+
65
+ expect(subject()).to eql(expectation)
66
+ end
67
+
68
+ it '#merge does not mutate the receiver and retains case of first-set keys' do
69
+ subject()[:foo] = 1
70
+ subject()[:BAR] = 2
71
+
72
+ pre_merge_subject = subject().dup()
73
+
74
+ result = subject().merge({:FOO => { 'onE' => 40 }, :Baz => 3})
75
+ expectation = @original_subject.merge({
76
+ 'foo' => { 'onE' => 40 },
77
+ 'BAR' => 2,
78
+ 'Baz' => 3
79
+ })
80
+
81
+ expect(subject()).to eql(pre_merge_subject)
82
+ expect(result).to eql(expectation)
83
+ end
84
+
85
+ it '#merge! mutates the receiver retains case of first-set keys' do
86
+ subject()[:foo] = 1
87
+ subject()[:BAR] = 2
88
+
89
+ subject().merge!({:FOO => { 'onE' => 40 }, :Baz => 3})
90
+
91
+ expectation = @original_subject.merge({
92
+ 'foo' => { 'onE' => 40 },
93
+ 'BAR' => 2,
94
+ 'Baz' => 3
95
+ })
96
+
97
+ expect(subject()).to eql(expectation)
98
+ end
99
+
100
+ it '#deep_merge does not mutate the receiver and retains nested key cases' do
101
+ subject()[:foo] = { :one => 10 }
102
+ subject()[:BAR] = 2
103
+
104
+ pre_merge_subject = subject().dup()
105
+
106
+ result = subject().deep_merge({:FOO => { 'ONE' => 40, :TWO => 20 }, :Baz => 3})
107
+ expectation = @original_subject.merge({
108
+ 'foo' => { 'one' => 40, 'TWO' => 20 },
109
+ 'BAR' => 2,
110
+ 'Baz' => 3
111
+ })
112
+
113
+ expect(subject()).to eql(pre_merge_subject)
114
+ expect(result).to eql(expectation)
115
+ end
116
+
117
+ it '#deep_merge! mutates the receiver and retains nested key cases' do
118
+ subject()[:foo] = { :one => 10 }
119
+ subject()[:BAR] = 2
120
+
121
+ subject().deep_merge!({:FOO => { 'ONE' => 40, :TWO => 20 }, :Baz => 3})
122
+
123
+ expectation = @original_subject.merge({
124
+ 'foo' => { 'one' => 40, 'TWO' => 20 },
125
+ 'BAR' => 2,
126
+ 'Baz' => 3
127
+ })
128
+
129
+ expect(subject()).to eql(expectation)
130
+ end
131
+
132
+ it 'retains indifferent behaviour after duplication' do
133
+ subject()[:foo] = { 'onE' => 40 }
134
+ subject()[:BAR] = 2
135
+
136
+ duplicate = subject().dup()
137
+ duplicate.merge!({ 'FOO' => true, 'baz' => 3 })
138
+
139
+ expectation = @original_subject.merge({
140
+ 'foo' => true,
141
+ 'BAR' => 2,
142
+ 'baz' => 3
143
+ })
144
+
145
+ expect(duplicate.to_h).to eql(expectation.to_h)
146
+ end
147
+ end # "context 'access and merging' do"
40
148
  end # "shared_examples 'an indifferent access, case insensitive Hash' do"
41
149
 
42
150
  context 'when created directly' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scimitar
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - RIPA Global
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-01-15 00:00:00.000000000 Z
12
+ date: 2024-03-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -25,20 +25,6 @@ dependencies:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
27
  version: '7.0'
28
- - !ruby/object:Gem::Dependency
29
- name: nokogiri
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - '='
33
- - !ruby/object:Gem::Version
34
- version: 1.15.5
35
- type: :runtime
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - '='
40
- - !ruby/object:Gem::Version
41
- version: 1.15.5
42
28
  - !ruby/object:Gem::Dependency
43
29
  name: rake
44
30
  requirement: !ruby/object:Gem::Requirement
@@ -265,7 +251,7 @@ metadata:
265
251
  homepage_uri: https://www.ripaglobal.com/
266
252
  source_code_uri: https://github.com/RIPAGlobal/scimitar/
267
253
  bug_tracker_uri: https://github.com/RIPAGlobal/scimitar/issues/
268
- changelog_uri: https://github.com/RIPAGlobal/scimitar/blob/master/CHANGELOG.md
254
+ changelog_uri: https://github.com/RIPAGlobal/scimitar/blob/main/CHANGELOG.md
269
255
  post_install_message:
270
256
  rdoc_options: []
271
257
  require_paths:
@@ -281,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
281
267
  - !ruby/object:Gem::Version
282
268
  version: '0'
283
269
  requirements: []
284
- rubygems_version: 3.5.3
270
+ rubygems_version: 3.5.4
285
271
  signing_key:
286
272
  specification_version: 4
287
273
  summary: SCIM v2 for Rails