require 'spec_helper' describe MethodKeys do it 'lets you access hash keys with methods' do h = {:foo => :bar} class << h; include MethodKeys; end h.foo.should == :bar h.nonexistent.should be_nil end it 'provides a Hash-like class' do mh = MethodHash.new mh[:one] = 1 mh[:ten] = 10 mh.one.should == 1 mh.ten.should == 10 mh.nothing.should be_nil end end describe 'expand' do it 'turns Ruby into XML' do xmlns = 'urn:partner.soap.sforce.com' expanded = '' builder = Builder::XmlMarkup.new(:target => expanded) data = ['partner:create', ['partner:sObjects', ['spartner:type', 'Contact', 'AccountId', '01234567890ABCD', 'FirstName', 'Jane', 'LastName', 'Doe'], 'partner:sObjects', ['spartner:type', 'Account', 'Name', 'Acme Rockets, Inc.']]] expand(builder, data) expanded.should == CreateXml end end describe 'a SoapResponse implementation' do before :all do fname = File.join(File.dirname(__FILE__), 'soap-response.xml') @contents = File.open(fname) {|f| f.read} [:rexml, :expat, :hpricot, :nokogiri].each do |processor| name = "SoapResponse#{processor.to_s.capitalize}".to_sym variable = "@#{processor}_recs".to_sym results = begin klass = RForce.const_get name klass.new(@contents).parse.queryResponse[:result][:records] rescue NameError nil end instance_variable_set(variable, results) end end it 'turns XML into objects' do @rexml_recs.size.should == 58 @rexml_recs.first.keys.size.should == 99 end it 'returns the same results with expat' do @expat_recs.should == @rexml_recs end it 'returns the same results with hpricot' do @hpricot_recs.should == @rexml_recs end it 'understands XML entities' do expected = "Bee's knees" @rexml_recs.first.Description.should == expected @expat_recs.first.Description.should == expected @hpricot_recs.first.Description.should == expected end end describe 'SoapResponseHpricot' do it 'parses basic XML entities' do text = '<tag attr="Bee's knees & toes">' SoapResponseHpricot.unescapeXML(text).should == %q() end end SOAP_WRAPPER = <<-XML %s XML shared_examples_for 'a SOAP response' do def wrap_in_salesforce_envelope(xml) SOAP_WRAPPER % xml end it 'parses nested elements into nested hashes' do xml = wrap_in_salesforce_envelope(""" Bin """) klass.new(xml).parse.should == {:foo => {:bar => "Bin"}} end it 'parses repeated elements into arrays' do xml = wrap_in_salesforce_envelope(""" Bin Bash """) klass.new(xml).parse.should == {:foo => {:bar => ["Bin", "Bash"]}} end it 'parses records with single record as an array' do xml = wrap_in_salesforce_envelope(""" Contact """) klass.new(xml).parse.should == {:records => [{:type => "Contact"}]} end it 'parses records with multiple records as an array' do xml = wrap_in_salesforce_envelope(""" Contact Contact """) klass.new(xml).parse.should == {:records => [{:type => "Contact"}, {:type => "Contact"}]} end it 'parses Id array as single string' do xml = wrap_in_salesforce_envelope(""" some_id some_id """) klass.new(xml).parse.should == {:foo => {:Id => "some_id"}} end it 'parses booleans and numbers' do xml = wrap_in_salesforce_envelope(""" 20 true false normal string """) klass.new(xml).parse.should == {:foo => {:size => 20, :done => true, :more => false, :string => "normal string"}} end it 'disregards namespacing when determining hash keys' do xml = wrap_in_salesforce_envelope(""" Bin Bash """) klass.new(xml).parse.should == {:foo => {:bar => ["Bin", "Bash"]}} end it 'unescapes any HTML contained in text nodes' do xml = wrap_in_salesforce_envelope(""" Bin <tag attr="Bee's knees & toes"> """) klass.new(xml).parse()[:foo][:bar].last.should == %q() end it 'returns an object that can be navigated via methods in addition to keys' do xml = wrap_in_salesforce_envelope("bash") klass.new(xml).parse().foo.bar.bin.should == "bash" end end describe 'SoapResponseNokogiri' do it_behaves_like 'a SOAP response' do let(:klass) { SoapResponseNokogiri } end end describe 'SoapResponseExpat' do it_behaves_like 'a SOAP response' do let(:klass) { SoapResponseExpat } end end describe 'SoapResponseRexml' do it_behaves_like 'a SOAP response' do let(:klass) { SoapResponseRexml } end end describe 'SoapResponseHpricot' do it_behaves_like 'a SOAP response' do let(:klass) { SoapResponseHpricot } end end CreateXml = < Contact 01234567890ABCD Jane Doe Account Acme Rockets, Inc. HERE