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
On 1/6/09 4:08 PM, Matt Wynne wrote:> 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 > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersHey 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-dead-in-its-tracks-with-fakeweb 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
On 6 Jan 2009, at 23:29, Ben Mabey wrote:> On 1/6/09 4:08 PM, Matt Wynne wrote: >> 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 >> >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at 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-dead-in-its-tracks-with-fakeweb > > 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
Hey guys, I''ve been running into this *exact* same issue. Luke Melia, in this thread: http://groups.google.com/group/rspec/browse_thread/thread/39a455db0ce19532/185e7f8bdbd79383?lnk=gst&q=cucumber+stub#185e7f8bdbd79383 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 On Jan 6, 4:33?pm, Matt Wynne <m... at mattwynne.net> wrote:> On 6 Jan 2009, at 23:29, Ben Mabey wrote: > > > > > On 1/6/09 4:08 PM, Matt Wynne wrote: > >> 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 myCucumberscenario. > > >> 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 > > >> _______________________________________________ > >> rspec-users mailing list > >> rspec-us... at 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 tostubout the ? > > Net::HTTP requests for? ?If not, then this post may give you some ? > > ideas: > >http://technicalpickles.com/posts/stop-net-http-dead-in-its-tracks-wi... > > > 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 tostubout, ? > as it''s a test-driver I want to leverage. I had figured I might be ? > able to do something like this: > > ? ? ?CucumberSteps -> 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 Wynnehttp://blog.mattwynne.nethttp://www.songkick.com > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users