I have a rack application (specifically a Sinatra one, but I don't think that matters) which, when running normally, happily outputs a bunch of information about the requests which are being made of it to STDOUT eg:
127.0.0.1 - - [25/Jul/2013 10:05:39] "GET /oath2/token?password=ohnoes HTTP/1.1" 404 507 0.0013
I'm trying write an extension for Rack::CommonLogger
that will remove passwords from the logfile, so of course my first task is to write a test.
I have rack/test
set up with rspec
like so, but I can't figure out how to capture the outgoing logs so I can scan what's in them! Any ideas?
require 'my_webapp'
describe "My Webapp" do
include Rack::Test::Methods
def app
@app ||= MyWebapp.new
end
it 'should not log the text of any GET password parameter' do
get '/oauth2/token?password=ohnoes'
# Not sure about this!
log_output.should_not =~ /ohnoes/
end
end
You need to stub and set expectations on whatever method your custom logger is calling to write its output.
So, for example, if your custom logger writes directly to STDERR
with a single argument, you would use:
STDERR.stub(:write) {|arg| expect(arg).to_not match(/password/)}
If your custom logger writes to the default logger (i.e. env['rack.errors']
) instead of STDERR, then you would stub the write
method of that object instead. I would have shown that example, but I can't figure out how to get a hold of the Rack environment within an RSpec test.
A couple of notes on this implementation:
any_number_of_times
, as in
STDERR.should_receive(:write).any_number_of_times
is deprecated in
favor of stub
STDERR.stub(:write).with(/regex/)