Search code examples
ruby-on-railsrubyrspecsavon

Rspec, sham_rack and Savon 2


I am trying to update our Savon (from version 1) to Version 2. We have a feature test which loads a page which hits the method which fires the Savon. Savon seems to work fine.

However, we have a support file using sham_rack to intercept this request and return some default info. It all works fine in Savon V1, but not with V2. It doesn't seem to trigger at all, and I am not sure if it's something wrong with my code, sham_rack, or Savon.

# Savon call
def client
  @client ||= Savon.client do
    Settings.savon # A YML file, with stuff for turning on logging, etc
    endpoint    'http://www.site.local/SomeService.svc?wsdl=wsdl10'
    namespace   'http://www.somesite.com/URL/1.0'
    namespaces  'xmlns:ns' => 'http://www.somesite.com/URL/1.0',
                'xmlns:arr' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
    pretty_print_xml true
  end
end

# Here action is 'GetAllItems'
def do_collections_server_request(body, action, options = {})
  options.reverse_merge!(raise_errors: true)

  client.globals.raise_errors(options[:raise_errors])
  client.globals.headers('SOAPAction' => "http://www.somesite.com/URL/1.0/IService/#{action}")

  client.call(action, message: body)
end
# spec/support/sham_calls.rb
require 'nokogiri'

ShamRack.at('www.site.local').sinatra do
  post '/SomeService.svc' do
    if request.env['HTTP_SOAPACTION'].include? 'GetAllItems'
      return prepared_xml
    end
  end
end

I can put a message right at the start of the ShamRack.at block, and it fires when it loads. But it doesn't seem to ever trigger the post. This all works fine with Savon 1 (except for the changes I had to make to make Savon work, of course). And it seems to post fine to the endpoint. ShamRack just isn't grabbing it. What am I doing wrong?

Ruby 2.1.1

gems:

rails (3.2.18)
sham_rack (1.3.6)
savon (2.3.3)
      akami (~> 1.2.0)
      builder (>= 2.1.2)
      gyoku (~> 1.1.0)
      httpi (~> 2.1.0)
      nokogiri (>= 1.4.0)
      nori (~> 2.3.0)
      wasabi (~> 3.2.2)

Solution

  • After a lot of investigation, I believe Savon might be running in a different thread. ShamRack says:

    What's the catch? Your Rack request-handling code runs in the same Ruby VM, in fact the same Thread, as your request.

    I believe this is why my Savon requests were not caught by Sinatra. We have one other more direct call out from our app, and ShamRack still catches this.

    In the end, I moved to VCR to solve this issue.

    If anyone else has a solution to this I would love to hear it, but I don't know that I will have the time to fix it now that we are moving forward with VCR.