Skip to content

draper+rspec does not honor default_url_options #313

Closed
lidaobing opened this Issue Oct 18, 2012 · 18 comments

5 participants

@lidaobing

how to reproduce:

  1. add default_url_options to ApplicationController
  def self.default_url_options(options = nil)
    {:locale => (I18n.locale =~ /^en/ ? 'en' : nil) }
  end
  1. add locale part to routes.rb
  scope "(:locale)", :locale => /en|zh/ do
    #...
  end
  1. use helper in your decorator
class PostDecorator < Draper::Base
  def as_json(opts={})
    {:post_path => h.post_path(self.model)}
  end
end
  1. add a rspec test
  context '#as_json' do
    it 'should works' do
      post = create :post
      res = PostDecorator.decorate(post).as_json
      res[:post_path].should be_a(String)
    end
  end
  1. run this rspec

it failed with something like:

    ActionController::RoutingError:
       No route matches {:action=>"show", :controller=>"posts", :locale=>#<Post id=1>}
@nashby
drapergem member
nashby commented Oct 18, 2012

@lidaobing does it work without Draper?

@lidaobing

yes, it works without Draper, like in a view test, maybe I need setup a project to reproduce this bug

@nashby
drapergem member
nashby commented Oct 18, 2012

that would be super awesome!

@lidaobing

ok, new way to reproduce this bug:

git clone git://github.com/lidaobing/draper-issue-313.git
cd draper-issue-313/
bundle 
RAILS_ENV=test rake db:migrate
rspec spec/decorators/post_decorator_spec.rb 

if you want to test whether this works, run rails s, and create a new post with "http://localhost:3000/posts/new", then visit "http://localhost:3000/posts/1.json" and "http://localhost:3000/posts/1", both work and have called PostDecorator#as_json

@lidaobing

I add the following code to make the rspec view test works: https://github.com/lidaobing/draper-issue-313/blob/master/spec/spec_helper.rb#L14

you can try the view testcase by rspec spec/views/posts/show.html.erb_spec.rb

module ActionView::Helpers::UrlHelper
  def url_options
    locale = I18n.locale.to_s.split('-')[0]
    { :locale => locale == 'en' ? 'en' : nil }.merge(super)
  end
end

but I don't know any workaround to make draper works

@nashby
drapergem member
nashby commented Oct 18, 2012

@steveklabnik looks like we still have an issue with view context in specs...
@lidaobing for now you can add

config.before :type => :decorator do
  ApplicationController.new.view_context
end

to your RSpec.configure block.

@lidaobing

@nashby cool, it works for me, thanks

@steveklabnik
drapergem member

Ugh. yeah, leaving this open; it needs fixed.

@nashby
drapergem member
nashby commented Oct 18, 2012

@steveklabnik why it was removed here 75a8204 anyway?

@steveklabnik
drapergem member

Because when we started doing https://github.com/drapergem/draper/blob/master/lib/draper/view_context.rb#L34-38 it didn't seem neccesary anymore.

@nashby
drapergem member
nashby commented Oct 18, 2012

@steveklabnik we need integration tests badly.

@steveklabnik
drapergem member
@lidaobing

@nashby your workaround has a problem, the h.post_url no longer works

how to reproduce

git clone git://github.com/lidaobing/draper-issue-313.git
cd draper-issue-313/
bundle 
RAILS_ENV=test rake db:migrate

# without your workaround h.post_url works:
rspec spec/decorators/post_decorator_spec.rb:49

# with your workaround, h.post_url no longer works
rspec spec/decorators/post_decorator_spec.rb:23

@steveklabnik
drapergem member

Ugh. Spent some more time looking at this, still don't know why it doesn't respect default_url_options.

@haines
drapergem member
haines commented Nov 9, 2012

It's because of this:

context.instance_eval do
  def url_options
    ActionMailer::Base.default_url_options
  end
end unless context.request

If you take it out it works fine. I'm going to look into it further to work out why we need to do this. I think part of the problem might be this:

def self.setup_action_mailer(component)
  include Draper::ViewContext
end

which should be

def self.setup_action_mailer(component)
  component.class_eval do
    include Draper::ViewContext
  end
end

but I will investigate further.

@steveklabnik
drapergem member

So, I had a hunch that this was it, but when I took it out, it DIDNT work in the test app.

The git history should show this pretty cleanly... I forget exactly why this was added, but I think it was to help with this kind of thing. If the tests all pass, please submit a pull request. :D

@haines
drapergem member
haines commented Nov 9, 2012

Will do! I'll put some integration tests together first so I don't break anything. This view context stuff is tricky!!

@haines haines referenced this issue Nov 12, 2012
Merged

Fix view context #335

@steveklabnik steveklabnik pushed a commit that closed this issue Nov 12, 2012
@haines haines Fix view context
Closes #313
c5b027d
@kangguru

I'm having a similar problem when helper-specs are executed before the request-specs, i guess because the view_context gets cached in the helper specs and therefore looses the default_url_options set in the ApplicationController when running the request specs

config.before type: :request do
  Draper::ViewContext.clear!
end

is fixing the issue, but i'd be cool if draper could take care of it on its own :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.