require 'minitest/autorun'
require 'rack/mock'
require 'rack/contrib/sendfile'

describe "Rack::File" do
  specify "should respond to #to_path" do
    Rack::File.new(Dir.pwd).must_respond_to :to_path
  end
end

describe "Rack::Sendfile" do
  def sendfile_body
    res = ['Hello World']
    def res.to_path ; "/tmp/hello.txt" ; end
    res
  end

  def simple_app(body=sendfile_body)
    lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] }
  end

  def sendfile_app(body=sendfile_body)
    Rack::Sendfile.new(simple_app(body))
  end

  before do
    @request = Rack::MockRequest.new(sendfile_app)
  end

  def request(headers={})
    yield @request.get('/', headers)
  end

  specify "does nothing when no X-Sendfile-Type header present" do
    request do |response|
      response.ok?.must_equal(true)
      response.body.must_equal 'Hello World'
      response.headers.wont_include 'X-Sendfile'
    end
  end

  specify "sets X-Sendfile response header and discards body" do
    request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response|
      response.ok?.must_equal(true)
      response.body.empty?.must_equal(true)
      response.headers['X-Sendfile'].must_equal '/tmp/hello.txt'
    end
  end

  specify "sets X-Lighttpd-Send-File response header and discards body" do
    request 'HTTP_X_SENDFILE_TYPE' => 'X-Lighttpd-Send-File' do |response|
      response.ok?.must_equal(true)
      response.body.empty?.must_equal(true)
      response.headers['X-Lighttpd-Send-File'].must_equal '/tmp/hello.txt'
    end
  end

  specify "sets X-Accel-Redirect response header and discards body" do
    headers = {
      'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect',
      'HTTP_X_ACCEL_MAPPING' => '/tmp/=/foo/bar/'
    }
    request headers do |response|
      response.ok?.must_equal(true)
      response.body.empty?.must_equal(true)
      response.headers['X-Accel-Redirect'].must_equal '/foo/bar/hello.txt'
    end
  end

  specify 'writes to rack.error when no X-Accel-Mapping is specified' do
    request 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect' do |response|
      response.ok?.must_equal(true)
      response.body.must_equal 'Hello World'
      response.headers.wont_include 'X-Accel-Redirect'
      response.errors.must_include 'X-Accel-Mapping'
    end
  end

  specify 'does nothing when body does not respond to #to_path' do
    @request = Rack::MockRequest.new(sendfile_app(['Not a file...']))
    request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response|
      response.body.must_equal 'Not a file...'
      response.headers.wont_include 'X-Sendfile'
    end
  end
end
