Integration/request rspec test of my SOAP service - ruby-on-rails

I have part of my rails 2 webservice application which is used as SOAP service (historical reasons, rest of app is REST).
Just two operations AddLead and ShowLead, with wsdl on /soap/wsdl.
I want to test this operations by Rspec integrations tests.
Trying to use Savon gem (/spec/integration/soap_spec.rb):
require "spec_helper"
require 'rubygems'
require 'savon'
describe "Leads" do
before(:all) do
wsdl= "http://localhost:3000/soap/wsdl"
wsdl = "http://www.example.com/soap/wsdl"
#client = Savon.client(:wsdl => wsdl )
puts("WSDL actions: #{#client.operations}")
end
end
But I can not find which URL I should use to point to WSDL.
URL localhost:3000 does not work, ending with error:
Errno::ECONNREFUSED in 'Leads before(:all)'
Connection could not be made, because target server it actively denied. - connect(2)
URL www.example.com (which is output from test url helpers) does not work either, ending with error:
Wasabi::Resolver::HTTPError in 'Leads before(:all)'
Error: 302
Any ideas?
Foton

Try the following link: http://blog.johnsonch.com/2013/04/18/rails-3-soap-and-testing-oh-my/
Inside of your describe block use the HTTPI rack adapter, and then configure that adapter to mount your application. This will give you the ability to use a specific url.
require 'spec_helper'
require 'savon'
describe API::MyService do
HTTPI.adapter = :rack
HTTPI::Adapter::Rack.mount 'application', MyApp::Application
it 'can get a response' do
application_base = "http://application"
client = Savon::Client.new({:wsdl => application_base + '/soap/wsdl' })
...
...
end
...

Related

no method error "merge" in Rails middleware

Hi I am building a Rails/Rack middleware for the Mailgun api, and doing a simple test for connection, which is fine in Postman with exact same params.
It is showing an error in test, Failure/Error: #app.call(env)
NoMethodError:
undefined method `merge!' for #<Mailgun::Tracking::MailLogger:0x0000557e6bc8bb50>
on running RSpec, and no merge method is attempted at all, so dont know where its come from. The api_key and endpoint are initialized in config/initialisers folder as per the Mailgun Tracking gem (which is being used) guidelines.
Only two other files used and code below.
MailLogger class under Mailgun::Tracking module, registered as middleware in app.
require 'logger'
require 'mailgun/tracking'
require 'rack/contrib'
require 'rack'
require 'byebug'
module Mailgun::Tracking
class MailLogger
def initialize(app, options = {
"HTTP_X_MAILGUN_API_KEY" => ENV['MAILGUN_API_KEY'],
"HTTP_X_MAILGUN_ENDPOINT" => ENV['MAILGUN_ENDPOINT']
})
#app = app
#options = options
end
def call(env)
#app.call(env)
end
end
end
The RSpec test
require 'logger'
require "json"
require "rails_helper"
Bundler.require(*Rails.groups)
require_relative "../../lib/middleware/mailgun/mailgun_tracking.rb"
RSpec.describe Mailgun::Tracking::MailLogger, type: 'Mailgun Webhook' do
subject(:response) { app.call(env) }
# env to pass in middleware, url endpoint & key
let(:app) { described_class.new(Rails.application) }
let(:env) { described_class.new(app, options = {
"HTTP_X_MAILGUN_API_KEY" => ENV['MAILGUN_API_KEY'],
"HTTP_X_MAILGUN_ENDPOINT" => ENV['MAILGUN_ENDPOINT']
}) }
it "returns a 200 status code" do
expect(response).to eq([200, {}, ["OK"]])
end
end
Am just looking for a 200, OK on connection, as I already get in Postman with the same header (api_key) and endpoint (events)
but throws this mysterious missing "merge" method error
Not encountered before.
Anyone know why?
Thanks
The actual code calling merge! is hidden in rack implementation and as such is filtered out from the error message. Your problem is that env you define in your test is not an instance of Rack::Environment but rather instance of your middleware. You can generate mocked environment instance using, for example, Rack::MockRequest.env_for("/", method: :get)
That being said, your unit test is currently testing the whole of the rack stack, including the routes and other middlewares. You can isolate your test better by using a mock application:
let(:app) { described_class.new(->(env) [200, {}, 'success']) }

Feature tests not passing REQUEST_URI to a middleware with RSpec and Capybara

I am trying to setup feature testing on an application.
I decided to install Capybara, and thus added it to my project's Gemfile:
group :test do
gem "capybara"
end
I declare my tests on the spec/feature folder, and the test manages to execute:
require "rails_helper"
feature 'My Feature' do
scenario 'User visits feature page' do
visit '/my-feature'
expect(page).to have_text('Stuff')
end
end
Issue: I have an URL middleware that does not detect the env['REQUEST_URI] flag and thus my test fails:
class UrlNormalizationMiddleware
def initialize(app)
#app = app
end
def call(env)
uri_items = env['REQUEST_URI'].split('?')
...
#app.call(env)
end
end
The actual application loads, and passes values on env['REQUEST_URI'], but doesn't on the test environment.
Anything else that I need to setup?
Thanks!
REQUEST_URI is not part of the rack spec, which means it's not guaranteed to be set, and you shouldn't be using it in your middleware. Instead you should be using things like PATH_INFO, QUERY_STRING, etc. which are specified in the rack spec and should therefore be available - https://github.com/rack/rack/blob/master/SPEC

VCR record HTTP interactions with webmock create .yml without values

I am doing HTTP interaction with Ganache - ethereum testnet. Ganache url
: http://127.0.0.1:7545. I connect to its by ethereum.rb gem, which using I think Net::HTTP lib:
class from ethereum.rb gem which establishes connect to ethereum net
spec/support/vcr_setup.rb:
require 'vcr'
# spec/support/vcr_setup.rb
VCR.configure do |c|
#the directory where your cassettes will be saved
c.cassette_library_dir = 'spec/vcr'
c.stub_with :webmock
end
spec/support/webmock.rb:
require 'webmock/rspec'
# spec/support/webmock.rb
WebMock.disable_net_connect!(allow_localhost: true)
my rspec test:
require 'rails_helper'
describe ::EthereumApi::Rpc do
it '#.client' do
VCR.use_cassette 'public_blockchain/rpc/client' do
client = ::Ethereum::HttpClient.new('http://127.0.0.1:7545')
first = client.eth_accounts['result'][0]
expect(first).to eql('0xd1d2982db68fe27216c86c2a03fc4ef136ff8ce2')
end
end
end
And as the result a get .yml file with keys but without values:
.yml without values
spec/vcr/some_folder/my_test.yml:

"undefined method `stub_request'" when accessing the method in an RSpec support file

I have the following file struture in my Ruby-on-Rails project, for the specs:
/spec
/msd
/service
service_spec.rb
/support
/my_module
requests_stubs.rb
My request_stubs.rb have:
module MyModule::RequestsStubs
module_function
def list_clients
url = "dummysite.com/clients"
stub_request(:get, url).to_return(status: 200, body: "clients body")
end
end
In my service_spec.rb I have:
require 'rails_helper'
require 'support/my_module/requests_stubs'
...
because I only want the method available in this file.
The problem is that when running the tests I call the method MyModule::RequestsStubs.list_clients in the service_spec.rb file, I get the following error:
Failure/Error:
stub_request(:get, url).to_return(status: 200, body: "clients body")
NoMethodError:
undefined method `stub_request' for MyModule::RequestsStubs:Module
when accessing the WebMock method stub_request.
The WebMock gem is installed and is required in the spec_helper.rb file.
Why does the error occurs? It looks like it can't access the WebMock gem, or don't know how to access it. Any ideas on how to solve it?
stub_request is defined in the WebMock namespace, so you have to use WebMock.stub_request. To make it available globally, you need to add include WebMock::API to your rails_helper.
Even better, include webmock/rspec instead of just webmock -- it will take care of including the WebMock::API as well as setting up the webmock RSpec matchers.

Looking for Example of Faraday Middleware with Error checking

I am looking for an example of Faraday Middleware that handles http (status code) errors on requests and additionally network timeouts.
After reading the docs for Faraday and it's middleware it's my understanding that this is one of middleware's use cases… I just have no idea what an implementation is supposed to look like.
Thanks
Faraday has an error handling middleware in by default:
faraday.use Faraday::Response::RaiseError
For example:
require 'faraday'
conn = Faraday.new('https://github.com/') do |c|
c.use Faraday::Response::RaiseError
c.use Faraday::Adapter::NetHttp
end
response = conn.get '/cant-find-me'
#=> gems/faraday-0.8.8/lib/faraday/response/raise_error.rb:6:in `on_complete': the server responded with status 404 (Faraday::Error::ResourceNotFound)
If you want to write your own middleware to handle HTTP status code responses, heres a basic example:
require 'faraday'
class CustomErrors < Faraday::Response::Middleware
def on_complete(env)
case env[:status]
when 404
raise RuntimeError, 'Custom 404 response'
end
end
end
conn = Faraday.new('https://github.com/') do |c|
c.use CustomErrors
c.use Faraday::Adapter::NetHttp
end
response = conn.get '/cant-find-me' #=> `on_complete': Custom 404 response (RuntimeError)
For your code, you'll probably want to put it in a separate file, require it, modularise it etc.
If you want to see a good live example, the new Instagram gem has a pretty good setup to raise custom errors: GitHub link

Resources