Really weird problem when testing controller - please help. I'm totally stumped.

I have a weird problem where I know the code works, the RSpec test
will pass if I run that Spec file by itself, but it fails when I run
all the tests in the entire suite (everything in /specs).

Here is the test:

    require 'spec_helper'

    describe WebpagesController do
      include Devise::TestHelpers

      render_views

      describe "GET 'show'" do
        it "should render the template if it exists" do
          get 'show', :page => "tour"

          response.should render_template("tour")
        end

        it "should render 404 page if template does not exist" do
          expect {
            get 'show', :page => 'does_not_exist'
          }.to_not raise_error(ActionView::MissingTemplate)

          response.should render_template("/public/404")
        end
      end

    end

Here's the code:

    class WebpagesController < ApplicationController

      def show
        begin
          render(params[:page])
        rescue ActionView::MissingTemplate
          render("/public/404")
        end
      end

    end

The idea here is that the 'show' action should render the template
with whatever name is given by the parameter, but if it doesn't exist,
we want to send the user to the generic 404 page.

Now, I could just duplicate the 404 template in the /webpages view
directory, but I really want to figure out how I can get this to pass
using the one provided in the /public folder like I am trying to do
here.

If I run the test in isolation - it PASSES. If I run the test with all
the others, I get the following error:

    expected no ActionView::MissingTemplate, got
#<ActionView::MissingTemplate: Missing template /public/404 with
{:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html], :locale=>[:en, :en]}
in view paths "/home/egervari/Projects/training/app/views", "/usr/
local/lib/ruby/gems/1.9.1/gems/devise-1.3.4/app/views", "/home/
egervari/Projects/training/spec", "/">
    /usr/local/lib/ruby/gems/1.9.1/gems/rspec-expectations-2.5.0/lib/
rspec/expectations/fail_with.rb:29:in `fail_with'
    /usr/local/lib/ruby/gems/1.9.1/gems/rspec-expectations-2.5.0/lib/
rspec/expectations/handler.rb:44:in `handle_matcher'
    /usr/local/lib/ruby/gems/1.9.1/gems/rspec-expectations-2.5.0/lib/
rspec/expectations/extensions/kernel.rb:50:in `should_not'
    /home/egervari/Projects/training/spec/controllers/
webpages_controller_spec.rb:17:in `block (3 levels) in <top
(required)>'

I've honestly been stumped with this one for several days, and I've
just been working on other stuff... but I am a little annoyed to see 1
test failing all the time even though I personally know it's fine.

Thanks for the help

So can you reduce it to minimal example (ie what is the one other test
it needs to run with in order to fail) ?

Also I think your code has a security weakness - some one could set up
params such that params[:page] had the value :inline => "<%=
system('rm -rf /') %>

Fred

So can you reduce it to minimal example (ie what is the one other test
it needs to run with in order to fail) ?

Also I think your code has a security weakness - some one could set up
params such that params[:page] had the value :inline => "<%=
system('rm -rf /') %>

Fred

Well, the test is pretty minimal as it is. I don't know how to
simplify it further. The first 'show' test works, but I included it so
you know what the intention was. The second test is the one that fails
- it cannot find the /public/404 page.

I wasn't aware of this security vulnerability though. How can I write
the controller in the same way without the security problem? I don't
want to make a bunch of static actions for 20 different static pages :frowning:

> So can you reduce it to minimal example (ie what is the one other test
> it needs to run with in order to fail) ?

> Also I think your code has a security weakness - some one could set up
> params such that params[:page] had the value :inline => "<%=
> system('rm -rf /') %>

> Fred

Well, the test is pretty minimal as it is. I don't know how to
simplify it further. The first 'show' test works, but I included it so
you know what the intention was. The second test is the one that fails
- it cannot find the /public/404 page.

I meant the fact that it fails only when you run the whole test suite
- can you narrow it down to "it fails when run at the same time as
test x?

I wasn't aware of this security vulnerability though. How can I write
the controller in the same way without the security problem? I don't
want to make a bunch of static actions for 20 different static pages :frowning:

Well you'd probably be ok if you made sure that params[:page] was a
string.

Also, as long as the route exists and there is a pages controller, /
pages/tour would render app/views/pages/tour.erb (or whatever sort of
template was there)

Fred