diff --git a/lib/ews/soap/builders/ews_builder.rb b/lib/ews/soap/builders/ews_builder.rb index 08de1f0f..635dc95f 100644 --- a/lib/ews/soap/builders/ews_builder.rb +++ b/lib/ews/soap/builders/ews_builder.rb @@ -24,11 +24,32 @@ class EwsBuilder include Viewpoint::EWS include Viewpoint::StringUtils + RESERVED_ATTRIBUTE_KEYS = %w{text sub_elements xmlns_attribute}.map(&:to_sym).freeze + attr_reader :nbuild def initialize @nbuild = Nokogiri::XML::Builder.new end + def self.camel_case_attributes(input) + case input + when Hash + result = {} + input.each do |attrib_key, attrib_value| + unless RESERVED_ATTRIBUTE_KEYS.include?(attrib_key) + attrib_key = camel_case(attrib_key) + end + + result[attrib_key] = camel_case_attributes(attrib_value) + end + result + when Array + result = input.map { |value| camel_case_attributes(value) } + else + input + end + end + # Build the SOAP envelope and yield this object so subelements can be built. Once # you have the EwsBuilder object you can use the nbuild object like shown in the # example for the Header section. The nbuild object is the underlying diff --git a/lib/ews/types/calendar_item.rb b/lib/ews/types/calendar_item.rb index 41bd765e..f1560afa 100644 --- a/lib/ews/types/calendar_item.rb +++ b/lib/ews/types/calendar_item.rb @@ -69,15 +69,11 @@ def update_item!(updates, options = {}) # Remap attributes because ews_builder #dispatch_field_item! uses #build_xml! item_attributes = item.to_ews_item.map do |name, value| - if value.is_a? String + case value + when String {name => {text: value}} - elsif value.is_a? Hash - node = {name => {}} - value.each do |attrib_key, attrib_value| - attrib_key = camel_case(attrib_key) unless attrib_key == :text - node[name][attrib_key] = attrib_value - end - node + when Hash + {name => Viewpoint::EWS::SOAP::EwsBuilder.camel_case_attributes(value)} else {name => value} end @@ -102,17 +98,14 @@ def update_item!(updates, options = {}) raise EwsCreateItemError, "Could not update calendar item. #{rm.code}: #{rm.message_text}" unless rm end end - end def duration_in_seconds iso8601_duration_to_seconds(duration) end - private - def key_paths super.merge(CALENDAR_ITEM_KEY_PATHS) end @@ -125,6 +118,5 @@ def key_alias super.merge(CALENDAR_ITEM_KEY_ALIAS) end - end end diff --git a/spec/unit/soap/builders/ews_builder_spec.rb b/spec/unit/soap/builders/ews_builder_spec.rb index da6b19bc..7173af09 100644 --- a/spec/unit/soap/builders/ews_builder_spec.rb +++ b/spec/unit/soap/builders/ews_builder_spec.rb @@ -65,4 +65,82 @@ end end + + describe ".camel_case_attributes" do + let(:result) do + Viewpoint::EWS::SOAP::EwsBuilder.camel_case_attributes(input) + end + + context "flat, no special fields" do + let(:input) do + { foo: 1, bar: "two", baz: "three" } + end + + let(:expected) do + { "Foo" => 1, "Bar" => "two", "Baz" => "three" } + end + + it "produces the expected output" do + expect(result).to eq(expected) + end + end + + context "nested, no special fields" do + let(:input) do + { foo: 1, bar: "two", baz: { quux: "three" } } + end + + let(:expected) do + { "Foo" => 1, "Bar" => "two", "Baz" => { "Quux" => "three" } } + end + + it "produces the expected output" do + expect(result).to eq(expected) + end + end + + context "special fields" do + context "text" do + let(:input) do + { foo: 1, text: "two" } + end + + let(:expected) do + { "Foo" => 1, :text => "two" } + end + + it "produces the expected output" do + expect(result).to eq(expected) + end + end + + context "sub_elements" do + let(:input) do + { foo: 1, sub_elements: [ { bar: 2 }, { baz: "three" } ] } + end + + let(:expected) do + { "Foo" => 1, :sub_elements => [ { "Bar" => 2 }, { "Baz" => "three" } ] } + end + + it "produces the expected output" do + expect(result).to eq(expected) + end + end + + context "xmlns_attribute" do + let(:input) do + { foo: 1, xmlns_attribute: "http://example.com/ns" } + end + + let(:expected) do + { "Foo" => 1, xmlns_attribute: "http://example.com/ns" } + end + + it "produces the expected output" do + expect(result).to eq(expected) + end + end + end + end end