Search code examples
ruby-on-railsrspecrspec-rails

how to set user agent in rspec route assertions


I am trying to use rails-rpec route specs to test different routing based on different user agents, and I cannot find the correct method or object to stub.

My method looks like this:

require "spec_helper"

describe "articles routing" do
  describe "/articles/#slug" do

    it "routes to Articles#show" do
      get("/articles/fancy-slug").should route_to(controller: "articles",
                                                    action:     "show",
                                                    id:         "fancy-slug")
    end

    describe "when you have an iphone user agent" do
      before(:each) do
        # SOMETHING MAGICAL HAPPENS ALONG THE LINES OF THE LINE BELOW
        # request.user_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25"
      end

      it "routes to Mobile::Articles#show" do
        expect(get: "/articles/fancy-slug").to route_to(controller: "mobile_articles",
                                                      action:     "show",
                                                      id:         "fancy-slug")
      end
    end

  end
end

But for the life of me, I cannot figure out how to stub the request, or the controller, or the whatever. Most of the available documentation seems to refer to an old/outdated version of the get syntax.


Solution

  • I'm not sure this will work, but here's something to try:

    If you look at the source for the RouteToMatcher, it just parses a controller/action pair (given as a hash or in controller#action format) and any other parameters given along with them and then delegates to ActionDispatch::Assertions::RoutingAssertions#assert_recognizes. But that method builds the request object from the parameters you pass in as the argument to route_to. So there's no easy way to access the request object from your spec. However, to build this dummy request, it calls

    ActionController::TestRequest.new

    So you might try

    ActionController::TestRequest.any_instance.stub(:user_agent).
      and_return "Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25"