Skip to content

Commit

Permalink
Merge pull request #69 from colloquial-solutions/topic/complex-values…
Browse files Browse the repository at this point in the history
…-replace

Allow specifying of nested values in dotpath notation for path-less replace operations
  • Loading branch information
pond authored Jan 11, 2024
2 parents 1faf525 + 28816cd commit 0317e8c
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 1 deletion.
5 changes: 4 additions & 1 deletion app/models/scimitar/resources/mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,10 @@ def from_patch_backend_apply!(nature:, path:, value:, altering_hash:)

when 'replace'
if path_component == 'root'
altering_hash[path_component].merge!(value)
dot_pathed_value = value.inject({}) do |hash, (k, v)|
hash.deep_merge!(::Scimitar::Support::Utilities.dot_path(k.split('.'), v))
end
altering_hash[path_component].deep_merge!(dot_pathed_value)
else
altering_hash[path_component] = value
end
Expand Down
13 changes: 13 additions & 0 deletions bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env ruby

require 'bundler/setup'
require 'rails'

require_relative '../lib/scimitar'

# (If you use this, don't forget to add pry to your Gemfile!)
# require "pry"
# Pry.start

require 'irb'
IRB.start(__FILE__)
1 change: 1 addition & 0 deletions lib/scimitar.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'scimitar/version'
require 'scimitar/support/hash_with_indifferent_case_insensitive_access'
require 'scimitar/support/utilities'
require 'scimitar/engine'

module Scimitar
Expand Down
51 changes: 51 additions & 0 deletions lib/scimitar/support/utilities.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module Scimitar

# Namespace containing various chunks of Scimitar support code that don't
# logically fit into other areas.
#
module Support

# A namespace that contains various stand-alone utility methods which act
# as helpers for other parts of the code base, without risking namespace
# pollution by e.g. being part of a module loaded into a client class.
#
module Utilities

# Takes an array of components that usually come from a dotted path such
# as <tt>foo.bar.baz</tt>, along with a value that is found at the end of
# that path, then converts it into a nested Hash with each level of the
# Hash corresponding to a step along the path.
#
# This was written to help with edge case SCIM uses where (most often, at
# least) inbound calls use a dotted notation where nested values are more
# commonly accepted; converting to nesting makes it easier for subsequent
# processing code, which needs only handle nested Hash data.
#
# As an example, passing:
#
# ['foo', 'bar', 'baz'], 'value'
#
# ...yields:
#
# {'foo' => {'bar' => {'baz' => 'value'}}}
#
# Parameters:
#
# +array+:: Array containing path components, usually acquired from a
# string with dot separators and a call to String#split.
#
# +value+:: The value found at the path indicated by +array+.
#
# If +array+ is empty, +value+ is returned directly, with no nesting
# Hash wrapping it.
#
def self.dot_path(array, value)
return value if array.empty?

{}.tap do | hash |
hash[array.shift()] = self.dot_path(array, value)
end
end
end
end
end
22 changes: 22 additions & 0 deletions spec/models/scimitar/resources/mixin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2717,6 +2717,28 @@ def self.scim_queryable_attributes
expect(@instance.username).to eql('1234')
end

it 'which updates nested values using root syntax' do
@instance.update!(first_name: 'Foo', last_name: 'Bar')

path = 'name.givenName'
path = path.upcase if force_upper_case

patch = {
'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
'Operations' => [
{
'op' => 'replace',
'value' => {
path => 'Baz'
}
}
]
}

@instance.from_scim_patch!(patch_hash: patch)
expect(@instance.first_name).to eql('Baz')
end

it 'which updates nested values' do
@instance.update!(first_name: 'Foo', last_name: 'Bar')

Expand Down

0 comments on commit 0317e8c

Please sign in to comment.