use railtie

This commit is contained in:
Ryan Buckley 2015-12-12 00:05:32 -08:00
parent 9a0326ff09
commit b2491299ed
7 changed files with 114 additions and 58 deletions

View File

@ -6,4 +6,5 @@ gemspec
group :test do group :test do
gem 'rake' gem 'rake'
gem "factory_girl", "~> 4.0" gem "factory_girl", "~> 4.0"
gem "rails", "~> 4.2"
end end

View File

@ -6,11 +6,20 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
attr_reader :logger attr_reader :logger
class << self
attr_accessor :logger, :filter
def default_logger
default = Logger.new(STDOUT)
default.formatter = ->(*args) { args.last.to_s << "\n".freeze }
default
end
end
def initialize(_, options = {}) def initialize(_, options = {})
super super
@logger = options[:logger] @options[:filter] ||= self.class.filter
@logger ||= Rails.logger if defined?(Rails) && Rails.logger.present? @logger = options[:logger] || self.class.logger || self.class.default_logger
@logger ||= default_logger
end end
def before def before
@ -94,10 +103,6 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
endpoint = env[Grape::Env::API_ENDPOINT] endpoint = env[Grape::Env::API_ENDPOINT]
endpoint.options[:for].to_s << '#'.freeze << endpoint.options[:path].map { |path| path.to_s.sub(BACKSLASH, '') }.join(BACKSLASH) endpoint.options[:for].to_s << '#'.freeze << endpoint.options[:path].map { |path| path.to_s.sub(BACKSLASH, '') }.join(BACKSLASH)
end end
def default_logger
default = Logger.new(STDOUT)
default.formatter = ->(*args) { args.last.to_s << "\n".freeze }
default
end
end end
require_relative 'logger/railtie' if defined?(Rails)

View File

@ -0,0 +1,6 @@
class Grape::Middleware::Logger::Railtie < Rails::Railtie
initializer 'grape.middleware.logger' do
Grape::Middleware::Logger.logger = ::Rails.application.config.logger
Grape::Middleware::Logger.filter = ::ActionDispatch::Http::ParameterFilter.new(::Rails.application.config.filter_parameters)
end
end

View File

@ -1,5 +1,4 @@
require 'spec_helper' require 'spec_helper'
require 'grape/middleware/logger'
describe Grape::Middleware::Logger, type: :integration do describe Grape::Middleware::Logger, type: :integration do
let(:app) { build :app } let(:app) { build :app }
@ -49,4 +48,5 @@ describe Grape::Middleware::Logger, type: :integration do
end end
end end
end end
end end

View File

@ -0,0 +1,82 @@
require 'rails_helper'
describe Grape::Middleware::Logger, type: :rails_integration do
let(:app) { build :app }
let(:options) { {} }
subject { described_class.new(app, options) }
let(:app_response) { build :app_response }
let(:grape_request) { build :grape_request }
let(:grape_endpoint) { build(:grape_endpoint) }
let(:env) { build(:expected_env, grape_endpoint: grape_endpoint) }
describe '#logger' do
context 'when @options[:logger] is nil' do
context 'when Rails.application.config.logger is defined' do
it 'uses the Rails logger' do
expect(subject.logger).to be_present
expect(subject.logger).to be Rails.application.config.logger
expect(subject.logger.formatter).to be_nil
end
end
context 'when the class logger is nil' do
before { described_class.logger = nil }
it 'uses the default logger' do
expect(subject.logger).to be_present
expect(subject.logger).to_not be Rails.application.config.logger
expect(subject.logger).to be_a(Logger)
expect(subject.logger.formatter.call('foo')).to eq "foo\n"
end
end
end
context 'when @options[:logger] is set' do
let(:options) { { logger: Object.new } }
it 'returns the logger object' do
expect(subject.logger).to eq options[:logger]
end
end
end
it 'logs all parts of the request' do
expect(subject.logger).to receive(:info).with ''
expect(subject.logger).to receive(:info).with %Q(Started POST "/api/1.0/users" at #{subject.start_time})
expect(subject.logger).to receive(:info).with %Q(Processing by TestAPI#users)
expect(subject.logger).to receive(:info).with %Q( Parameters: {"id"=>"101001", "name"=>"foo", "password"=>"[FILTERED]"})
expect(subject.logger).to receive(:info).with /Completed 200 in \d.\d+ms/
expect(subject.logger).to receive(:info).with ''
subject.call!(env)
end
describe 'the "processing by" section' do
before { subject.call!(env) }
context 'namespacing' do
let(:grape_endpoint) { build(:namespaced_endpoint) }
it 'ignores the namespacing' do
expect(subject.processed_by).to eq 'TestAPI#users'
end
context 'with more complex route' do
let(:grape_endpoint) { build(:namespaced_endpoint, :complex) }
it 'only escapes the first slash and leaves the rest of the untouched' do
expect(subject.processed_by).to eq 'TestAPI#users/:name/profile'
end
end
end
context 'with more complex route' do
let(:grape_endpoint) { build(:grape_endpoint, :complex) }
it 'only escapes the first slash and leaves the rest of the untouched' do
expect(subject.processed_by).to eq 'TestAPI#users/:name/profile'
end
end
end
end

View File

@ -99,52 +99,4 @@ describe Grape::Middleware::Logger do
end end
end end
end end
describe '#logger' do
context 'when @options[:logger] is nil' do
let(:options) { {} }
context 'when Rails is defined' do
before do
module Rails
class << self
attr_accessor :logger
end
end
end
it 'defaults to the the standard Logger' do
expect(subject.logger).to be_a(Logger)
end
it 'logs each message in the correct format' do
expect(subject.logger.formatter.call('foo')).to eq "foo\n"
end
context 'when Rails.logger is defined' do
before do
Rails.logger = double('rails_logger')
end
it 'sets @logger to Rails.logger' do
expect(subject.logger).to be Rails.logger
end
after do
Rails.logger = nil
end
end
after do
Object.send :remove_const, :Rails
end
end
end
context 'when @options[:logger] is set' do
it 'returns the logger object' do
expect(subject.logger).to eq options[:logger]
end
end
end
end end

10
spec/rails_helper.rb Normal file
View File

@ -0,0 +1,10 @@
require 'rails'
class MyRailsApp < Rails::Application
RailsLogger = Class.new Logger
config.logger = RailsLogger.new(Tempfile.new '')
config.filter_parameters += [:password]
end
require 'spec_helper'
Grape::Middleware::Logger::Railtie.run_initializers