Commit bf9ccd8

mokha <mokha@cisco.com>
2019-01-30 00:25:10
start to validate complex types
1 parent 2593103
Changed files (3)
lib/scim/kit/v2/attribute.rb
@@ -14,7 +14,8 @@ module Scim
 
         validate :presence_of_value, if: proc { |x| x._type.required }
         validate :inclusion_of_value, if: proc { |x| x._type.canonical_values }
-        validate :validate_type
+        validate :validate_type, unless: proc { |x| x._type.complex? }
+        validate :validate_complex, if: proc { |x| x._type.complex? }
 
         def initialize(resource:, type:, value: nil)
           @_type = type
@@ -71,6 +72,12 @@ module Scim
           errors.add(_type.name, I18n.t('errors.messages.invalid'))
         end
 
+        def validate_complex
+          dynamic_attributes.each do |key, attribute|
+            errors.copy!(attribute.errors) unless attribute.valid?
+          end
+        end
+
         def read_only?
           _type.mutability == Mutability::READ_ONLY
         end
spec/scim/kit/v2/attribute_spec.rb
@@ -215,14 +215,16 @@ RSpec.describe Scim::Kit::V2::Attribute do
       x
     end
 
-    before { subject._value = { name: 'mo', age: 34 } }
-
-    specify { expect(subject).to be_valid }
-
-    context 'when invalid sub attribute' do
-      before { subject._value = { name: 34, age: 'wrong' } }
+    specify do
+      subject.name = 'mo'
+      subject.age = 34
+      expect(subject).to be_valid
+    end
 
-      specify { expect(subject).not_to be_valid }
+    specify do
+      subject.name = 'mo'
+      subject.age = { }
+      expect(subject).not_to be_valid
     end
   end
 
spec/scim/kit/v2/resource_spec.rb
@@ -197,6 +197,63 @@ RSpec.describe Scim::Kit::V2::Resource do
       specify { expect(subject).not_to be_valid }
       specify { expect(subject.errors[:hero]).to be_present }
     end
+
+    context "when validating a complex type" do
+      before do
+        schema.add_attribute(name: :manager, type: :complex) do |x|
+          x.multi_valued = false
+          x.required = false
+          x.mutability = :read_write
+          x.returned = :default
+          x.add_attribute(name: :value, type: :string) do |y|
+            y.multi_valued = false
+            y.required = false
+            y.case_exact = false
+            y.mutability = :read_write
+            y.returned = :default
+            y.uniqueness = :none
+          end
+          x.add_attribute(name: '$ref', type: :reference) do |y|
+            y.multi_valued = false
+            y.required = false
+            y.case_exact = false
+            y.mutability = :read_write
+            y.returned = :default
+            y.uniqueness = :none
+          end
+          x.add_attribute(name: :display_name, type: :string) do |y|
+            y.multi_valued = false
+            y.required = true
+            y.case_exact = false
+            y.mutability = :read_only
+            y.returned = :default
+            y.uniqueness = :none
+          end
+        end
+      end
+
+      context "when valid" do
+        before do
+          subject.manager.value = SecureRandom.uuid
+          subject.manager.write_attribute('$ref', FFaker::Internet.uri('https'))
+          subject.manager.display_name = SecureRandom.uuid
+        end
+
+        specify { expect(subject).to be_valid }
+      end
+
+      context "when invalid" do
+        before do
+          subject.manager.value = SecureRandom.uuid
+          subject.manager.write_attribute('$ref', SecureRandom.uuid)
+          subject.manager.display_name = nil
+          subject.valid?
+        end
+
+        specify { expect(subject).not_to be_valid }
+        specify { expect(subject.errors[:display_name]).to be_present }
+      end
+    end
   end
 
   context 'when building a new resource' do