scimitar 1.0.3 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,6 +15,19 @@ RSpec.describe Scimitar::Resources::User do
15
15
  expect(user.as_json['name']['errors']).to be_nil
16
16
  end
17
17
 
18
+ it 'treats attributes as case-insensitive' do
19
+ user = described_class.new(name: Scimitar::ComplexTypes::Name.new(
20
+ FAMILYNAME: 'Smith',
21
+ GIVENNAME: 'John',
22
+ FORMATTED: 'John Smith'
23
+ ))
24
+
25
+ expect(user.name.familyName).to eql('Smith')
26
+ expect(user.name.givenName).to eql('John')
27
+ expect(user.name.formatted).to eql('John Smith')
28
+ expect(user.as_json['name']['errors']).to be_nil
29
+ end
30
+
18
31
  it 'validates that the provided name matches the name schema' do
19
32
  user = described_class.new(name: Scimitar::ComplexTypes::Email.new(
20
33
  value: 'john@smoth.com',
@@ -146,41 +146,41 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
146
146
 
147
147
  context '#create' do
148
148
  context 'creates an item' do
149
- it 'with minimal parameters' do
150
- mock_before = MockUser.all.to_a
149
+ shared_examples 'a creator' do | force_upper_case: |
150
+ it 'with minimal parameters' do
151
+ mock_before = MockUser.all.to_a
151
152
 
152
- expect_any_instance_of(MockUsersController).to receive(:create).once.and_call_original
153
- expect {
154
- post "/Users", params: {
155
- format: :scim,
156
- userName: '4' # Minimum required by schema
157
- }
158
- }.to change { MockUser.count }.by(1)
153
+ attributes = { userName: '4' } # Minimum required by schema
154
+ attributes = spec_helper_hupcase(attributes) if force_upper_case
159
155
 
160
- mock_after = MockUser.all.to_a
161
- new_mock = (mock_after - mock_before).first
156
+ expect_any_instance_of(MockUsersController).to receive(:create).once.and_call_original
157
+ expect {
158
+ post "/Users", params: attributes.merge(format: :scim)
159
+ }.to change { MockUser.count }.by(1)
162
160
 
163
- expect(response.status).to eql(201)
164
- result = JSON.parse(response.body)
161
+ mock_after = MockUser.all.to_a
162
+ new_mock = (mock_after - mock_before).first
165
163
 
166
- expect(result['id']).to eql(new_mock.id.to_s)
167
- expect(result['meta']['resourceType']).to eql('User')
168
- expect(new_mock.username).to eql('4')
169
- end
164
+ expect(response.status).to eql(201)
165
+ result = JSON.parse(response.body)
170
166
 
171
- # A bit of extra coverage just for general confidence.
172
- #
173
- it 'with more comprehensive parameters' do
174
- mock_before = MockUser.all.to_a
167
+ expect(result['id']).to eql(new_mock.id.to_s)
168
+ expect(result['meta']['resourceType']).to eql('User')
169
+ expect(new_mock.username).to eql('4')
170
+ end
175
171
 
176
- expect {
177
- post "/Users", params: {
178
- format: :scim,
172
+ # A bit of extra coverage just for general confidence.
173
+ #
174
+ it 'with more comprehensive parameters' do
175
+ mock_before = MockUser.all.to_a
176
+
177
+ attributes = {
179
178
  userName: '4',
180
179
  name: {
181
180
  givenName: 'Given',
182
181
  familyName: 'Family'
183
182
  },
183
+ meta: { resourceType: 'User' },
184
184
  emails: [
185
185
  {
186
186
  type: 'work',
@@ -192,22 +192,36 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
192
192
  }
193
193
  ]
194
194
  }
195
- }.to change { MockUser.count }.by(1)
196
195
 
197
- mock_after = MockUser.all.to_a
198
- new_mock = (mock_after - mock_before).first
196
+ attributes = spec_helper_hupcase(attributes) if force_upper_case
199
197
 
200
- expect(response.status).to eql(201)
201
- result = JSON.parse(response.body)
198
+ expect {
199
+ post "/Users", params: attributes.merge(format: :scim)
200
+ }.to change { MockUser.count }.by(1)
202
201
 
203
- expect(result['id']).to eql(new_mock.id.to_s)
204
- expect(result['meta']['resourceType']).to eql('User')
205
- expect(new_mock.username).to eql('4')
206
- expect(new_mock.first_name).to eql('Given')
207
- expect(new_mock.last_name).to eql('Family')
208
- expect(new_mock.home_email_address).to eql('home_4@test.com')
209
- expect(new_mock.work_email_address).to eql('work_4@test.com')
210
- end
202
+ mock_after = MockUser.all.to_a
203
+ new_mock = (mock_after - mock_before).first
204
+
205
+ expect(response.status).to eql(201)
206
+ result = JSON.parse(response.body)
207
+
208
+ expect(result['id']).to eql(new_mock.id.to_s)
209
+ expect(result['meta']['resourceType']).to eql('User')
210
+ expect(new_mock.username).to eql('4')
211
+ expect(new_mock.first_name).to eql('Given')
212
+ expect(new_mock.last_name).to eql('Family')
213
+ expect(new_mock.home_email_address).to eql('home_4@test.com')
214
+ expect(new_mock.work_email_address).to eql('work_4@test.com')
215
+ end
216
+ end # "shared_examples 'a creator' do | force_upper_case: |"
217
+
218
+ context 'using schema-matched case' do
219
+ it_behaves_like 'a creator', force_upper_case: false
220
+ end # "context 'using schema-matched case' do"
221
+
222
+ context 'using upper case' do
223
+ it_behaves_like 'a creator', force_upper_case: true
224
+ end # "context 'using upper case' do"
211
225
  end
212
226
 
213
227
  it 'returns 409 for duplicates (by Rails validation)' do
@@ -258,28 +272,38 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
258
272
  # ===========================================================================
259
273
 
260
274
  context '#replace' do
261
- it 'replaces all attributes in an instance' do
262
- expect_any_instance_of(MockUsersController).to receive(:replace).once.and_call_original
263
- expect {
264
- put "/Users/#{@u2.id}", params: {
265
- format: :scim,
266
- userName: '4' # Minimum required by schema
267
- }
268
- }.to_not change { MockUser.count }
275
+ shared_examples 'a replacer' do | force_upper_case: |
276
+ it 'which replaces all attributes in an instance' do
277
+ attributes = { userName: '4' } # Minimum required by schema
278
+ attributes = spec_helper_hupcase(attributes) if force_upper_case
269
279
 
270
- expect(response.status).to eql(200)
271
- result = JSON.parse(response.body)
280
+ expect_any_instance_of(MockUsersController).to receive(:replace).once.and_call_original
281
+ expect {
282
+ put "/Users/#{@u2.id}", params: attributes.merge(format: :scim)
283
+ }.to_not change { MockUser.count }
272
284
 
273
- expect(result['id']).to eql(@u2.id.to_s)
274
- expect(result['meta']['resourceType']).to eql('User')
285
+ expect(response.status).to eql(200)
286
+ result = JSON.parse(response.body)
275
287
 
276
- @u2.reload
288
+ expect(result['id']).to eql(@u2.id.to_s)
289
+ expect(result['meta']['resourceType']).to eql('User')
277
290
 
278
- expect(@u2.username).to eql('4')
279
- expect(@u2.first_name).to be_nil
280
- expect(@u2.last_name).to be_nil
281
- expect(@u2.home_email_address).to be_nil
282
- end
291
+ @u2.reload
292
+
293
+ expect(@u2.username).to eql('4')
294
+ expect(@u2.first_name).to be_nil
295
+ expect(@u2.last_name).to be_nil
296
+ expect(@u2.home_email_address).to be_nil
297
+ end
298
+ end # "shared_examples 'a replacer' do | force_upper_case: |"
299
+
300
+ context 'using schema-matched case' do
301
+ it_behaves_like 'a replacer', force_upper_case: false
302
+ end # "context 'using schema-matched case' do"
303
+
304
+ context 'using upper case' do
305
+ it_behaves_like 'a replacer', force_upper_case: true
306
+ end # "context 'using upper case' do"
283
307
 
284
308
  it 'notes schema validation failures' do
285
309
  expect {
@@ -341,11 +365,9 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
341
365
  # ===========================================================================
342
366
 
343
367
  context '#update' do
344
- it 'patches specific attributes' do
345
- expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
346
- expect {
347
- patch "/Users/#{@u2.id}", params: {
348
- format: :scim,
368
+ shared_examples 'an updater' do | force_upper_case: |
369
+ it 'which patches specific attributes' do
370
+ payload = {
349
371
  Operations: [
350
372
  {
351
373
  op: 'add',
@@ -359,33 +381,36 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
359
381
  }
360
382
  ]
361
383
  }
362
- }.to_not change { MockUser.count }
363
384
 
364
- expect(response.status).to eql(200)
365
- result = JSON.parse(response.body)
385
+ payload = spec_helper_hupcase(payload) if force_upper_case
366
386
 
367
- expect(result['id']).to eql(@u2.id.to_s)
368
- expect(result['meta']['resourceType']).to eql('User')
387
+ expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
388
+ expect {
389
+ patch "/Users/#{@u2.id}", params: payload.merge(format: :scim)
390
+ }.to_not change { MockUser.count }
369
391
 
370
- @u2.reload
392
+ expect(response.status).to eql(200)
393
+ result = JSON.parse(response.body)
371
394
 
372
- expect(@u2.username).to eql('4')
373
- expect(@u2.first_name).to eql('Foo')
374
- expect(@u2.last_name).to eql('Bar')
375
- expect(@u2.home_email_address).to eql('home_2@test.com')
376
- expect(@u2.work_email_address).to eql('work_4@test.com')
377
- end
395
+ expect(result['id']).to eql(@u2.id.to_s)
396
+ expect(result['meta']['resourceType']).to eql('User')
378
397
 
379
- context 'clears attributes' do
380
- before :each do
381
- @u2.update!(work_email_address: 'work_2@test.com')
398
+ @u2.reload
399
+
400
+ expect(@u2.username).to eql('4')
401
+ expect(@u2.first_name).to eql('Foo')
402
+ expect(@u2.last_name).to eql('Bar')
403
+ expect(@u2.home_email_address).to eql('home_2@test.com')
404
+ expect(@u2.work_email_address).to eql('work_4@test.com')
382
405
  end
383
406
 
384
- it 'with simple paths' do
385
- expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
386
- expect {
387
- patch "/Users/#{@u2.id}", params: {
388
- format: :scim,
407
+ context 'which clears attributes' do
408
+ before :each do
409
+ @u2.update!(work_email_address: 'work_2@test.com')
410
+ end
411
+
412
+ it 'with simple paths' do
413
+ payload = {
389
414
  Operations: [
390
415
  {
391
416
  op: 'remove',
@@ -393,28 +418,31 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
393
418
  }
394
419
  ]
395
420
  }
396
- }.to_not change { MockUser.count }
397
421
 
398
- expect(response.status).to eql(200)
399
- result = JSON.parse(response.body)
422
+ payload = spec_helper_hupcase(payload) if force_upper_case
400
423
 
401
- expect(result['id']).to eql(@u2.id.to_s)
402
- expect(result['meta']['resourceType']).to eql('User')
424
+ expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
425
+ expect {
426
+ patch "/Users/#{@u2.id}", params: payload.merge(format: :scim)
427
+ }.to_not change { MockUser.count }
403
428
 
404
- @u2.reload
429
+ expect(response.status).to eql(200)
430
+ result = JSON.parse(response.body)
405
431
 
406
- expect(@u2.username).to eql('2')
407
- expect(@u2.first_name).to be_nil
408
- expect(@u2.last_name).to eql('Bar')
409
- expect(@u2.home_email_address).to eql('home_2@test.com')
410
- expect(@u2.work_email_address).to eql('work_2@test.com')
411
- end
432
+ expect(result['id']).to eql(@u2.id.to_s)
433
+ expect(result['meta']['resourceType']).to eql('User')
412
434
 
413
- it 'by array entry filter match' do
414
- expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
415
- expect {
416
- patch "/Users/#{@u2.id}", params: {
417
- format: :scim,
435
+ @u2.reload
436
+
437
+ expect(@u2.username).to eql('2')
438
+ expect(@u2.first_name).to be_nil
439
+ expect(@u2.last_name).to eql('Bar')
440
+ expect(@u2.home_email_address).to eql('home_2@test.com')
441
+ expect(@u2.work_email_address).to eql('work_2@test.com')
442
+ end
443
+
444
+ it 'by array entry filter match' do
445
+ payload = {
418
446
  Operations: [
419
447
  {
420
448
  op: 'remove',
@@ -422,28 +450,31 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
422
450
  }
423
451
  ]
424
452
  }
425
- }.to_not change { MockUser.count }
426
453
 
427
- expect(response.status).to eql(200)
428
- result = JSON.parse(response.body)
454
+ payload = spec_helper_hupcase(payload) if force_upper_case
429
455
 
430
- expect(result['id']).to eql(@u2.id.to_s)
431
- expect(result['meta']['resourceType']).to eql('User')
456
+ expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
457
+ expect {
458
+ patch "/Users/#{@u2.id}", params: payload.merge(format: :scim)
459
+ }.to_not change { MockUser.count }
432
460
 
433
- @u2.reload
461
+ expect(response.status).to eql(200)
462
+ result = JSON.parse(response.body)
434
463
 
435
- expect(@u2.username).to eql('2')
436
- expect(@u2.first_name).to eql('Foo')
437
- expect(@u2.last_name).to eql('Bar')
438
- expect(@u2.home_email_address).to eql('home_2@test.com')
439
- expect(@u2.work_email_address).to be_nil
440
- end
464
+ expect(result['id']).to eql(@u2.id.to_s)
465
+ expect(result['meta']['resourceType']).to eql('User')
441
466
 
442
- it 'by whole collection' do
443
- expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
444
- expect {
445
- patch "/Users/#{@u2.id}", params: {
446
- format: :scim,
467
+ @u2.reload
468
+
469
+ expect(@u2.username).to eql('2')
470
+ expect(@u2.first_name).to eql('Foo')
471
+ expect(@u2.last_name).to eql('Bar')
472
+ expect(@u2.home_email_address).to eql('home_2@test.com')
473
+ expect(@u2.work_email_address).to be_nil
474
+ end
475
+
476
+ it 'by whole collection' do
477
+ payload = {
447
478
  Operations: [
448
479
  {
449
480
  op: 'remove',
@@ -451,23 +482,38 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
451
482
  }
452
483
  ]
453
484
  }
454
- }.to_not change { MockUser.count }
455
485
 
456
- expect(response.status).to eql(200)
457
- result = JSON.parse(response.body)
486
+ payload = spec_helper_hupcase(payload) if force_upper_case
458
487
 
459
- expect(result['id']).to eql(@u2.id.to_s)
460
- expect(result['meta']['resourceType']).to eql('User')
488
+ expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
489
+ expect {
490
+ patch "/Users/#{@u2.id}", params: payload.merge(format: :scim)
491
+ }.to_not change { MockUser.count }
461
492
 
462
- @u2.reload
493
+ expect(response.status).to eql(200)
494
+ result = JSON.parse(response.body)
463
495
 
464
- expect(@u2.username).to eql('2')
465
- expect(@u2.first_name).to eql('Foo')
466
- expect(@u2.last_name).to eql('Bar')
467
- expect(@u2.home_email_address).to be_nil
468
- expect(@u2.work_email_address).to be_nil
469
- end
470
- end # "context 'clears attributes' do"
496
+ expect(result['id']).to eql(@u2.id.to_s)
497
+ expect(result['meta']['resourceType']).to eql('User')
498
+
499
+ @u2.reload
500
+
501
+ expect(@u2.username).to eql('2')
502
+ expect(@u2.first_name).to eql('Foo')
503
+ expect(@u2.last_name).to eql('Bar')
504
+ expect(@u2.home_email_address).to be_nil
505
+ expect(@u2.work_email_address).to be_nil
506
+ end
507
+ end # "context 'which clears attributes' do"
508
+ end # "shared_examples 'an updater' do | force_upper_case: |"
509
+
510
+ context 'using schema-matched case' do
511
+ it_behaves_like 'an updater', force_upper_case: false
512
+ end # "context 'using schema-matched case' do"
513
+
514
+ context 'using upper case' do
515
+ it_behaves_like 'an updater', force_upper_case: true
516
+ end # "context 'using upper case' do"
471
517
 
472
518
  it 'notes Rails validation failures' do
473
519
  expect {
@@ -11,11 +11,14 @@ RSpec.describe Scimitar::ApplicationController do
11
11
  end
12
12
 
13
13
  context 'format handling' do
14
- it 'renders "not acceptable" if the request does not use SCIM type' do
14
+ it 'renders "OK" if the request does not provide any Content-Type value' do
15
15
  get '/CustomRequestVerifiers', params: { format: :html }
16
16
 
17
- expect(response).to have_http_status(:not_acceptable)
18
- expect(JSON.parse(response.body)['detail']).to eql('Only application/scim+json type is accepted.')
17
+ expect(response).to have_http_status(:ok)
18
+ parsed_body = JSON.parse(response.body)
19
+ expect(parsed_body['request']['is_scim' ]).to eql(true)
20
+ expect(parsed_body['request']['format' ]).to eql('application/scim+json')
21
+ expect(parsed_body['request']['content_type']).to eql('application/scim+json')
19
22
  end
20
23
 
21
24
  it 'renders 400 if given bad JSON' do
@@ -10,11 +10,36 @@ RSpec.describe Scimitar::Engine do
10
10
  # "params" given here as a String, expecting the engine's custom parser to
11
11
  # decode it for us.
12
12
  #
13
- it 'decodes JSON', type: :model do
13
+ it 'decodes simple JSON', type: :model do
14
14
  post '/Users.scim', params: '{"userName": "foo"}', headers: { 'CONTENT_TYPE' => 'application/scim+json' }
15
15
 
16
16
  expect(response.status).to eql(201)
17
17
  expect(JSON.parse(response.body)['userName']).to eql('foo')
18
18
  end
19
+
20
+ it 'decodes nested JSON', type: :model do
21
+ post '/Users.scim', params: '{"userName": "foo", "name": {"givenName": "bar", "familyName": "baz"}}', headers: { 'CONTENT_TYPE' => 'application/scim+json' }
22
+
23
+ expect(response.status).to eql(201)
24
+ expect(JSON.parse(response.body)['userName']).to eql('foo')
25
+ expect(JSON.parse(response.body)['name']['givenName']).to eql('bar')
26
+ expect(JSON.parse(response.body)['name']['familyName']).to eql('baz')
27
+ end
28
+
29
+ it 'is case insensitive at the top level', type: :model do
30
+ post '/Users.scim', params: '{"USERNAME": "foo"}', headers: { 'CONTENT_TYPE' => 'application/scim+json' }
31
+
32
+ expect(response.status).to eql(201)
33
+ expect(JSON.parse(response.body)['userName']).to eql('foo')
34
+ end
35
+
36
+ it 'is case insensitive in nested levels', type: :model do
37
+ post '/Users.scim', params: '{"USERNAME": "foo", "NAME": {"GIVENNAME": "bar", "FAMILYNAME": "baz"}}', headers: { 'CONTENT_TYPE' => 'application/scim+json' }
38
+
39
+ expect(response.status).to eql(201)
40
+ expect(JSON.parse(response.body)['userName']).to eql('foo')
41
+ expect(JSON.parse(response.body)['name']['givenName']).to eql('bar')
42
+ expect(JSON.parse(response.body)['name']['familyName']).to eql('baz')
43
+ end
19
44
  end # "context 'parameter parser' do"
20
45
  end
data/spec/spec_helper.rb CHANGED
@@ -64,3 +64,30 @@ def spec_helper_capture_stdout( &block )
64
64
 
65
65
  return result
66
66
  end
67
+
68
+ # Recursively transform the keys of any given Hash or any Hashes in a given
69
+ # Array into uppercase form, retaining Symbol or String keys. Returns the
70
+ # transformed duplicate structure.
71
+ #
72
+ # Only Hashes or Hash entries within an Array are converted. Other data is left
73
+ # alone. The original input item is not modified.
74
+ #
75
+ # IMPORTANT: HashWithIndifferentAccess or similar subclasses are not supported.
76
+ #
77
+ # +item+:: Hash or Array that might contain some Hashes.
78
+ #
79
+ def spec_helper_hupcase(item)
80
+ if item.is_a?(Hash)
81
+ rehash = item.transform_keys(&:upcase)
82
+ rehash.each do | key, value |
83
+ rehash[key] = spec_helper_hupcase(value)
84
+ end
85
+ rehash
86
+ elsif item.is_a?(Array)
87
+ item.map do | array_entry |
88
+ spec_helper_hupcase(array_entry)
89
+ end
90
+ else
91
+ item
92
+ end
93
+ end
@@ -0,0 +1,30 @@
1
+ # Self-test. Sometimes tests call into utility methods in spec_helper.rb;
2
+ # if those aren't doing what they should, then the tests might give false
3
+ # positive passes.
4
+ #
5
+ require 'spec_helper'
6
+
7
+ RSpec.describe 'spec_helper.rb self-test' do
8
+ context '#spec_helper_hupcase' do
9
+ it 'converts a flat Hash, preserving data type of keys' do
10
+ input = {:one => 1, 'two' => 2}
11
+ output = spec_helper_hupcase(input)
12
+
13
+ expect(output).to eql({:ONE => 1, 'TWO' => 2})
14
+ end
15
+
16
+ it 'converts a nested Hash' do
17
+ input = {:one => 1, 'two' => {:tHrEe => {'fOuR' => 4}}}
18
+ output = spec_helper_hupcase(input)
19
+
20
+ expect(output).to eql({:ONE => 1, 'TWO' => {:THREE => {'FOUR' => 4}}})
21
+ end
22
+
23
+ it 'converts an Array with Hashes' do
24
+ input = {:one => 1, 'two' => [true, 42, {:tHrEe => {'fOuR' => 4}}]}
25
+ output = spec_helper_hupcase(input)
26
+
27
+ expect(output).to eql({:ONE => 1, 'TWO' => [true, 42, {:THREE => {'FOUR' => 4}}]})
28
+ end
29
+ end # "context '#spec_helper_hupcase' do"
30
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Scimitar::Support::HashWithIndifferentCaseInsensitiveAccess do
4
+ shared_examples 'an indifferent access, case insensitive Hash' do
5
+ context 'where keys set as strings' do
6
+ it 'can be retrieved via any case' do
7
+ subject()['foo'] = 1
8
+
9
+ expect(subject()['FOO']).to eql(1)
10
+ expect(subject()[:FoO ]).to eql(1)
11
+ expect(subject()['bar']).to be_nil
12
+ end
13
+
14
+ it 'can be checked for via any case' do
15
+ subject()['foo'] = 1
16
+
17
+ expect(subject()).to have_key('FOO')
18
+ expect(subject()).to have_key(:FoO )
19
+ expect(subject()).to_not have_key('bar')
20
+ end
21
+ end # "context 'where keys set as strings' do"
22
+
23
+ context 'where keys set as symbols' do
24
+ it 'retrieves via any case' do
25
+ subject()[:foo] = 1
26
+
27
+ expect(subject()['FOO']).to eql(1)
28
+ expect(subject()[:FoO ]).to eql(1)
29
+ expect(subject()['bar']).to be_nil
30
+ end
31
+
32
+ it 'enquires via any case' do
33
+ subject()[:foo] = 1
34
+
35
+ expect(subject()).to have_key('FOO')
36
+ expect(subject()).to have_key(:FoO )
37
+ expect(subject()).to_not have_key('bar')
38
+ end
39
+ end # "context 'where keys set as symbols' do"
40
+ end # "shared_examples 'an indifferent access, case insensitive Hash' do"
41
+
42
+ context 'when created directly' do
43
+ subject do
44
+ described_class.new()
45
+ end
46
+
47
+ it_behaves_like 'an indifferent access, case insensitive Hash'
48
+ end # "context 'when created directly' do"
49
+
50
+ context 'when created through conversion' do
51
+ subject do
52
+ { 'test' => 2 }.with_indifferent_access.with_indifferent_case_insensitive_access()
53
+ end
54
+
55
+ it 'includes the original data' do
56
+ expect(subject()[:TEST]).to eql(2)
57
+ end
58
+
59
+ it_behaves_like 'an indifferent access, case insensitive Hash'
60
+ end # "context 'converting hashes' do"
61
+ end