Comparing changes
v0.2.12
→
v0.2.13
9 commits
5 files changed
Commits
Changed files (5)
lib
scim
spec
scim
kit
lib/scim/kit/v2/attributable.rb
@@ -12,10 +12,22 @@ module Scim
types.each { |x| attribute(x, resource) }
end
+ def assign_attributes(attributes = {})
+ attributes.each do |key, value|
+ next if key.to_sym == :schemas
+
+ if key.to_s.start_with?(Schemas::EXTENSION)
+ assign_attributes(value)
+ else
+ write_attribute(key, value)
+ end
+ end
+ end
+
private
def attribute_for(name)
- dynamic_attributes[name]
+ dynamic_attributes[name.to_s.underscore]
end
def read_attribute(name)
@@ -26,8 +38,11 @@ module Scim
end
def write_attribute(name, value)
- attribute = attribute_for(name)
- attribute._value = value
+ if value.is_a?(Hash)
+ attribute_for(name)&.assign_attributes(value)
+ else
+ attribute_for(name)&._value = value
+ end
end
def create_module_for(type)
lib/scim/kit/v2/resource.rb
@@ -13,16 +13,16 @@ module Scim
attr_reader :meta
attr_reader :schemas
- validates_presence_of :id
validate :schema_validations
- def initialize(schemas:, location: nil)
+ def initialize(schemas:, location: nil, attributes: {})
@meta = Meta.new(schemas[0].name, location)
@meta.disable_timestamps
@schemas = schemas
schemas.each do |schema|
define_attributes_for(self, schema.attributes)
end
+ assign_attributes(attributes)
yield self if block_given?
end
lib/scim/kit/v2/schemas.rb
@@ -4,7 +4,11 @@ module Scim
module Kit
module V2
module Schemas
- CORE = 'urn:ietf:params:scim:schemas:core:2.0'
+ ROOT = 'urn:ietf:params:scim:schemas'
+
+ CORE = "#{ROOT}:core:2.0"
+ EXTENSION = "#{ROOT}:extension"
+ ENTERPRISE_USER = "#{EXTENSION}:enterprise:2.0:User"
GROUP = "#{CORE}:Group"
RESOURCE_TYPE = "#{CORE}:ResourceType"
SERVICE_PROVIDER_CONFIGURATION = "#{CORE}:ServiceProviderConfig"
lib/scim/kit/version.rb
@@ -2,6 +2,6 @@
module Scim
module Kit
- VERSION = '0.2.12'
+ VERSION = '0.2.13'
end
end
spec/scim/kit/v2/resource_spec.rb
@@ -147,13 +147,6 @@ RSpec.describe Scim::Kit::V2::Resource do
end
describe '#valid?' do
- context 'when invalid' do
- before { subject.valid? }
-
- specify { expect(subject).not_to be_valid }
- specify { expect(subject.errors[:id]).to be_present }
- end
-
context 'when valid' do
before { subject.id = SecureRandom.uuid }
@@ -344,4 +337,137 @@ RSpec.describe Scim::Kit::V2::Resource do
specify { expect(subject).to be_mode(:client) }
end
end
+
+ describe '#assign_attributes' do
+ context 'with a simple string attribute' do
+ let(:user_name) { FFaker::Internet.user_name }
+
+ before do
+ schema.add_attribute(name: 'userName')
+ subject.assign_attributes('schemas' => schemas.map(&:id), userName: user_name)
+ end
+
+ specify { expect(subject.user_name).to eql(user_name) }
+ end
+
+ context 'with a simple integer attribute' do
+ before do
+ schema.add_attribute(name: 'age', type: :integer)
+ subject.assign_attributes(schemas: schemas.map(&:id), age: 34)
+ end
+
+ specify { expect(subject.age).to be(34) }
+ end
+
+ context 'with a multi-valued simple string attribute' do
+ before do
+ schema.add_attribute(name: 'colours', type: :string) do |x|
+ x.multi_valued = true
+ end
+ subject.assign_attributes(schemas: schemas.map(&:id), colours: ['red', 'green', :blue])
+ end
+
+ specify { expect(subject.colours).to match_array(%w[red green blue]) }
+ end
+
+ context 'with a single complex attribute' do
+ before do
+ schema.add_attribute(name: :name) do |x|
+ x.add_attribute(name: :given_name)
+ x.add_attribute(name: :family_name)
+ end
+ subject.assign_attributes(schemas: schemas.map(&:id), name: { givenName: 'Tsuyoshi', familyName: 'Garrett' })
+ end
+
+ specify { expect(subject.name.given_name).to eql('Tsuyoshi') }
+ specify { expect(subject.name.family_name).to eql('Garrett') }
+ end
+
+ context 'with a multi-valued complex attribute' do
+ let(:email) { FFaker::Internet.email }
+ let(:other_email) { FFaker::Internet.email }
+
+ before do
+ schema.add_attribute(name: :emails) do |x|
+ x.multi_valued = true
+ x.add_attribute(name: :value)
+ x.add_attribute(name: :primary, type: :boolean)
+ end
+ subject.assign_attributes(schemas: schemas.map(&:id), emails: [
+ { value: email, primary: true },
+ { value: other_email, primary: false }
+ ])
+ end
+
+ specify do
+ expect(subject.emails).to match_array([
+ { value: email, primary: true },
+ { value: other_email, primary: false }
+ ])
+ end
+
+ specify { expect(subject.emails[0][:value]).to eql(email) }
+ specify { expect(subject.emails[0][:primary]).to be(true) }
+ specify { expect(subject.emails[1][:value]).to eql(other_email) }
+ specify { expect(subject.emails[1][:primary]).to be(false) }
+ end
+
+ context 'with an extension schema' do
+ let(:schemas) { [schema, extension] }
+ let(:extension) { Scim::Kit::V2::Schema.new(id: extension_id, name: 'Extension', location: FFaker::Internet.uri('https')) }
+ let(:extension_id) { Scim::Kit::V2::Schemas::ENTERPRISE_USER }
+
+ before do
+ extension.add_attribute(name: :preferred_name)
+ subject.assign_attributes(
+ schemas: schemas.map(&:id),
+ extension_id => { preferredName: 'hunk' }
+ )
+ end
+
+ specify { expect(subject.preferred_name).to eql('hunk') }
+ end
+
+ context 'when initializing the resource with attributes' do
+ subject { described_class.new(schemas: schemas, attributes: attributes) }
+
+ let(:user_name) { FFaker::Internet.user_name }
+ let(:email) { FFaker::Internet.email }
+ let(:attributes) do
+ {
+ schemas: schemas.map(&:id),
+ userName: user_name,
+ age: 34,
+ colours: %w[red green blue],
+ name: { given_name: 'Tsuyoshi', family_name: 'Garrett' },
+ emails: [{ value: email, primary: true }]
+ }
+ end
+
+ before do
+ schema.add_attribute(name: :user_name)
+ schema.add_attribute(name: :age, type: :integer)
+ schema.add_attribute(name: :colours, type: :string) do |x|
+ x.multi_valued = true
+ end
+ schema.add_attribute(name: :name) do |x|
+ x.add_attribute(name: :given_name)
+ x.add_attribute(name: :family_name)
+ end
+ schema.add_attribute(name: :emails) do |x|
+ x.multi_valued = true
+ x.add_attribute(name: :value)
+ x.add_attribute(name: :primary, type: :boolean)
+ end
+ end
+
+ specify { expect(subject.user_name).to eql(user_name) }
+ specify { expect(subject.age).to be(34) }
+ specify { expect(subject.colours).to match_array(%w[red green blue]) }
+ specify { expect(subject.name.given_name).to eql('Tsuyoshi') }
+ specify { expect(subject.name.family_name).to eql('Garrett') }
+ specify { expect(subject.emails[0][:value]).to eql(email) }
+ specify { expect(subject.emails[0][:primary]).to be(true) }
+ end
+ end
end