Forum: RSpec Cucumber: acceptance testing OAuth

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Cdf378de2284d8acf137122e541caa28?d=identicon&s=25 Matt Wynne (mattwynne)
on 2009-01-07 00:12
(Received via mailing list)
Hi,

We're adding OAuth support for our API, and I paired with the guy
who's spiked it today to try and write some features to drive out the
behaviour we need.

It ended up getting quite tricky, so if you don't mind I'd like to
bounce my ideas of this list and see what you think.

The spike uses the OAuth Provider plugin[1] which is what we're
planning to integrate. This adds a ClientApplication model to your
database. A ClientApplication represents, for example, the flickr
uploader application that I've downlaoded. One User has many
ClientApplications.

A ClientApplication instance has a #key and a #secret which are stored
on the server, and also known by the application on the client side
which it represents.


Anyway, so back to my Cucumber scenario.

In the Given step, I create a User and a ClientApplication. Now I have
to pretend to be the actual API client making a request to my rails app.

At this point, I need to make some special magic OAuth parameters for
the HTTP request, called 'signature' and 'signature_method'. These
signify some magic munging of the key and secret for the
ClientApplication which will (hopefully) be understood and processed
by the SUT.

In the real world, you would delegate the work of talking to an OAuth
provider like this to the oauth gem[2]. I had a crack, for an hour or
so, to use the gem in my When step, injecting a fake replacement for
the Net::HTTP which it uses and instead forwarding calls to rails
IntegrationSession post / get methods.

This wasn't easy. Net::HTTPResponse objects don't look much like
ActionController::CgiResponse objects, for example, so you have to do
a lot of bridging.


So I feel like it's time to pull back and have a re-think. Has anyone
else tried to do something similar, and has some code to bridge from
Net::HTTP objects to the ones used by Rails' Test::IntegrationSession?

Am we barking up the wrong tree? Should we perhaps just spin up a web
server for the test session and just go ahead and call the app through
the gem?

Any other ideas? Am I missing anything else obvious?

All thoughts greatly appreciated guys!

cheers,

Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com

[1] http://github.com/pelle/oauth-plugin/tree/master
[2] http://github.com/pelle/oauth/tree/master
C694a032be7518a0d704318895f8fe1d?d=identicon&s=25 Ben Mabey (mabes)
on 2009-01-07 00:34
(Received via mailing list)
On 1/6/09 4:08 PM, Matt Wynne wrote:
> planning to integrate. This adds a ClientApplication model to your
>
> provider like this to the oauth gem[2]. I had a crack, for an hour or
> else tried to do something similar, and has some code to bridge from
> cheers,
> rspec-users mailing list
> rspec-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users


Hey Matt,
I don't know the first thing about OAuth and what integrating it into an
app entails.  Is it too much of a simplification in saying that it is a
third-party webservice that you need to stub out the Net::HTTP requests
for?  If not, then this post may give you some ideas:
http://technicalpickles.com/posts/stop-net-http-de...

Sorry if this wasn't too much help.. I guess I don't understand what
sort of "bridge from Net::HTTP objects to the ones used by Rails'
Test::IntegrationSession" really means.

-Ben
Cdf378de2284d8acf137122e541caa28?d=identicon&s=25 Matt Wynne (mattwynne)
on 2009-01-07 02:18
(Received via mailing list)
On 6 Jan 2009, at 23:29, Ben Mabey wrote:

>> The spike uses the OAuth Provider plugin[1] which is what we're
>> Anyway, so back to my Cucumber scenario.
>>
>>
>>
>>
> that it is a third-party webservice that you need to stub out the
> Net::HTTP requests for?  If not, then this post may give you some
> ideas:
> http://technicalpickles.com/posts/stop-net-http-de...
>
> Sorry if this wasn't too much help.. I guess I don't understand what
> sort of "bridge from Net::HTTP objects to the ones used by Rails'
> Test::IntegrationSession" really means.

Yeah I know that was pretty rambling. Let me have another go at
explaining what I'm trying to do, for the benefit of anyone else who
might be wondering what I'm on about.

Real world:

     API Client -> OAuth Gem -> Net::HTTP -> (The Internet) -> My
Rails App

So in order to acceptance-test my Rails app's OAuth features, I need
to make requests that look a lot like the ones made by the OAuth gem
when the API client asks it to call my Rails app and authenticate
itself.

So it's not so much that Net::HTTP is a dependency I want to stub out,
as it's a test-driver I want to leverage. I had figured I might be
able to do something like this:

     Cucumber Steps -> OAuth Gem -> Patched Net::HTTP ->
Test::IntegrationSession -> My Rails App

The 'bridge' I'm talking about is something that looks enough like
Net::HTTP for the OAuth gem to be happy to talk to it, but that will
actually pass on it's calls to the Rails Test::IntegrationSession
get / post methods, and pass back the response.

Does that make any more sense?

Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com
91a296784a35bb4efb6221abc282127d?d=identicon&s=25 Adam Greene (Guest)
on 2009-01-14 09:53
(Received via mailing list)
Hey guys,

I've been running into this *exact* same issue.  Luke Melia, in this
thread:
http://groups.google.com/group/rspec/browse_thread...

offers an interesting way around this issue.

What I ended up doing, was in the *_steps.rb file for this particular
feature test, I put this at the top of the file:
require 'spec/mocks'
require Spec::Runner.configuration.mock_framework
include Spec::Plugins::MockFramework


and then for the very specific step, it looks something like this:

Given /I approve the linkage to [SOME SERVICE]/ do
  begin
    setup_mocks_for_rspec

    #we want to prevent the [SOME SERVICE] connection, so mocking it
at the conduit level
    # code goes here to mock or do expectations

    visit '/my/page/which/is/the/callback/for/
oauth', :get, :permission => '1', :oauth_token => session
[:request_token]
    #check that I do the right thing on a successful oauth
approval....

    verify_mocks_for_rspec
  ensure
    teardown_mocks_for_rspec
  end
end

It works like a charm, but has been noted almost everywhere on this
email list, it is a sort of last resort thing.


Any thoughts on if this is a good way to do this or not?
thanks!
adam
This topic is locked and can not be replied to.