Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
455 views
in Technique[技术] by (71.8m points)

ruby on rails - Testing Rack Routing Using rSpec

I have a rule in my routes.rb:

constraints AssetRestrictor do
  match '*seopath' => SeoDispatcher
end

Then in lib/seo_dispatcher.rb, I have this:

class SeoDispatcher
  AD_KEY = "action_dispatch.request.path_parameters"

  def self.call(env)
    seopath = env[AD_KEY][:seopath]

    if seopath
      params = seopath.split('/')           # get array of path components
      env[AD_KEY][:id] = params.last        # the real page name is the last element
      env[AD_KEY][:category] = params.first if params.length > 1
    end

    Rails.logger.debug "routing to show #{env[AD_KEY]}"
    PagesController.action(:show).call(env)
    # TODO error handling for invalid paths
  end
end

class AssetRestrictor
  EXCEPTION_FILES = ['javascripts', 'stylesheets', 'autodiscover']
  def self.matches?(request)
    return false if request.method == 'POST'  # no post requests are SEO-ed
    EXCEPTION_FILES.each do |ex|
      return false if request.url.include?(ex)
    end
    true
  end
end

And basically, the whole thing works. The idea is to peel off the last path component and match it to the slug for a page. SEO people tell me this is the cool way to trick search engines into ranking you higher.

My snarky comments aside, I'm having trouble writing a test in rSpec that exercises this code. My first shot at it was:

describe SeoDispatcher do
  it "routes /insurance/charters-and-guides/how-to-buy-charter-boat-insurance to pages#show :id => how-to-buy-charter-boat-insurance" do
    { :get => "/insurance/charters-and-guides/how-to-buy-charter-boat-insurance"}.should route_to(
      :controller => 'pages',
      :action     => 'show',
      :id         => 'how-to-buy-charter-boat-insurance'
    )
  end
end

But this simply doesn't exercise the Rack dispatch code. Does anyone know how one would (than cuking it) exercise the code? I really want to bring the parameters in from Rack instead of just doing SeoDispatcher.call({"action_dispatch.request.path_parameters" => {:seopath => "/foo/bar"}}).

Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, answered my own question. Request spec:

describe SeoDispatcher do
  describe "seo parsing" do
    it "GET /insurance/charters-and-guides/how-to-buy-charter-boat-insurance displays how-to-buy-charter-boat-insurance (3-part path)" do
      p = Page.make(:title => "how-to-buy-charter-boat-insurance")
      p.save
      get "/insurance/charters-and-guides/how-to-buy-charter-boat-insurance"
      request.path.should == "/insurance/charters-and-guides/how-to-buy-charter-boat-insurance"
      assigns[:page].slug.should == "how-to-buy-charter-boat-insurance"
    end

    it "GET /insurance/charters-and-guides displays guides (2-part path)" do
      p = Page.make(:title => "charters and guides")
      p.save
      get "/insurance/charters-and-guides"
      request.path.should == "/insurance/charters-and-guides"
      assigns[:page].slug.should == "charters-and-guides"
    end

    it "GET /insurance displays insurance (1-part path)" do
      p = Page.make(:title => "insurance")
      p.save
      get "/insurance"
      request.path.should == "/insurance"
      assigns[:page].slug.should == "insurance"
    end
  end
end

If anyone knows a better way, feel free to let me know!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...