Commit 7f3919c

mokha <mokha@cisco.com>
2019-01-11 01:49:53
validate single valued complex type
1 parent 7da26f5
Changed files (2)
lib
spec
lib/scim/kit/v2/attribute_type.rb
@@ -30,7 +30,7 @@ module Scim
           boolean: ->(x) { BOOLEAN_VALUES.include?(x) },
           datetime: ->(x) { x.is_a?(DateTime) },
           decimal: ->(x) { x.is_a?(Float) },
-          integer: ->(x) { x&.integer? },
+          integer: ->(x) { x&.integer? rescue false },
           reference: ->(x) { x =~ /\A#{URI.regexp(%w[http https])}\z/ },
           string: ->(x) { x.is_a?(String) }
         }.freeze
@@ -103,6 +103,10 @@ module Scim
         def valid?(value)
           if complex?
             return false unless value.is_a?(Hash)
+            value.keys.each do |key|
+              attribute = attributes.find { |x| x.name.to_s.underscore == key.to_s.underscore }
+              return false unless attribute.valid?(value[key])
+            end
             true
           else
             if multi_valued
spec/scim/kit/v2/attribute_type_spec.rb
@@ -89,6 +89,8 @@ RSpec.describe Scim::Kit::V2::AttributeType do
     specify { expect(described_class.new(name: :x, type: :integer)).to be_valid(1) }
     specify { expect(described_class.new(name: :x, type: :integer)).to be_valid(1_000) }
     specify { expect(described_class.new(name: :x, type: :integer)).not_to be_valid(10.0) }
+    specify { expect(described_class.new(name: :x, type: :integer)).not_to be_valid('10') }
+    specify { expect(described_class.new(name: :x, type: :integer)).not_to be_valid([]) }
 
     specify { expect(described_class.new(name: :x, type: :reference)).to be_valid(FFaker::Internet.uri('https')) }
     specify { expect(described_class.new(name: :x, type: :reference)).not_to be_valid('hello') }
@@ -112,6 +114,21 @@ RSpec.describe Scim::Kit::V2::AttributeType do
       specify { expect(subject).not_to be_valid(email) }
     end
 
+    context 'when single valued complex type' do
+      subject { described_class.new(name: :location, type: :complex) }
+
+      before do
+        subject.multi_valued = false
+        subject.add_attribute(name: :name, type: :string)
+        subject.add_attribute(name: :latitude, type: :integer)
+        subject.add_attribute(name: :longitude, type: :integer)
+      end
+
+      specify { expect(subject).to be_valid(name: 'work', latitude: 100, longitude: 100) }
+      specify { expect(subject).not_to be_valid([name: 'work', latitude: 100, longitude: 100]) }
+      specify { expect(subject).not_to be_valid(name: 'work', latitude: 'wrong', longitude: 100) }
+    end
+
     context 'when multi valued complex type' do
       subject { described_class.new(name: :emails, type: :complex) }
       let(:email) { FFaker::Internet.email }