4

I recently enabled GZIP on my Rails 4 app following this Thoughtbot blog post and I also have added use Rack::Deflater to my config.ru file as suggested by this post. My Rails app seems to be serving compressed content, but when I test for it using RSpec the test fails because response.headers['Content-Encoding'] is nil.

Here is my application.rb:

module MyApp
  class Application < Rails::Application
    # Turn on GZIP compression
    config.middleware.use Rack::Deflater
  end
end

Here is my spec:

require 'rails_helper'

describe GeneralController, type: :controller, focus: true do
    it "a visitor has a browser that supports compression" do
        ['deflate', 'gzip', 'deflate,gzip', 'gzip,deflate'].each do |compression_method|
            get 'about', {}, {'HTTP_ACCEPT_ENCODING' => compression_method }
            binding.pry
            expect(response.headers['Content-Encoding']).to be
        end
    end

    it "a visitor's browser does not support compression" do
        get 'about'
        expect(response.headers['Content-Encoding']).to_not be
    end
end

When I run curl --head -H "Accept-Encoding: gzip" http://localhost:3000/ I get the following output:

HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Ua-Compatible: chrome=1
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
Content-Encoding: gzip
Etag: "f7e364f21dbb81b9580cd39e308a7c15"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 3f018f27-40ab-4a87-a836-67fdd6bd5b6e
X-Runtime: 0.067748
Server: WEBrick/1.3.1 (Ruby/2.0.0/2014-02-24)

When I load the site and look at the Network tab of the inspector I can see that the response size is smaller than before, but my test still fails. I'm not sure if I'm missing a step here with my test or if there is an issue with my implementation of Rack::Deflater.

Community
  • 1
  • 1
Daniel Bonnell
  • 4,817
  • 9
  • 48
  • 88

2 Answers2

2

As @andy-waite pointed, RSpec controller specs are not aware of middleware, but that's why, since RSpec 2.6 we have request specs.

Request specs are, according to the docs:

designed to drive behavior through the full stack

Therefore, using RSpec > 2.6 request specs, your code should look like:

require 'rails_helper'

describe GeneralController, type: :request, focus: true do
  it "a visitor has a browser that supports compression" do
    ['deflate', 'gzip', 'deflate,gzip', 'gzip,deflate'].each do |compression_method|
        get 'about', {}, {'HTTP_ACCEPT_ENCODING' => compression_method }
        binding.pry
        expect(response.headers['Content-Encoding']).to be
    end
  end

  it "a visitor's browser does not support compression" do
    get 'about'
    expect(response.headers['Content-Encoding']).to_not be
  end
end
Carlos
  • 2,883
  • 2
  • 18
  • 19
0

RSpec controller specs are wrapped around Rails functional tests, which are not aware of middleware:

Making Rails tests aware of Rack middleware outside Rails's internal chain

Community
  • 1
  • 1
Andy Waite
  • 10,785
  • 4
  • 33
  • 47