Compare commits

...

33 Commits

Author SHA1 Message Date
Ryan Buckley ca754ca6c9 Update rake dev dependency 2021-02-24 12:42:03 -08:00
Ryan Buckley 7d14ff6d47 Version 1.12.0 - support for Rails 6 2019-05-13 16:23:32 -07:00
Ryan Buckley 9eebd6105f
Merge pull request #25 from serggl/rails6
Use ActiveSupport::ParameterFilter instead of ActionDispatch::Http::ParameterFilter in Rails 6 and above
2019-05-13 14:39:33 -07:00
Sergey Glukhov bee00ffd9e Use ActiveSupport::ParameterFilter instead of ActionDispatch::Http::ParameterFilter in Rails 6 and above 2019-05-13 10:56:36 +03:00
Ryan Buckley 653ad4662d Version 1.11.0 2019-03-07 16:45:47 -08:00
Ryan Buckley 071c4992f1 Of course specify gem 2019-03-07 16:41:52 -08:00
Ryan Buckley 03a52c6ba9 Update rubies 2019-03-07 16:39:09 -08:00
Ryan Buckley 0cb84132b5 Support latest grape versions 2019-03-07 16:36:45 -08:00
Ryan Buckley db00fe6c04 [#24] Change initializer order only for older Rails versions (< 5) 2019-03-07 16:22:06 -08:00
Ryan Buckley 3e64a80ab7
Merge pull request #16 from mmclead/one_line_log_option
adding an option to format log message to be one line
2019-03-07 15:15:21 -08:00
Ryan Buckley e8a0f6e6aa Version 1.10.0 2018-08-21 12:29:47 -07:00
Ryan Buckley 37d4c5a41a
Merge pull request #23 from cutalion/patch-1
Add "require" to usage example
2018-08-21 12:26:53 -07:00
Alexander 6c7b2ab2b1
Add "require" to usage example
It's not obvious that one must require `grape/middleware/logger` and not `grape-middleware-logger`
2018-08-18 23:37:16 +03:00
Ryan Buckley 1bf905ab4e
Merge pull request #22 from controlshift/master
Support for recently released v1.1.0 of grape
2018-08-16 16:35:38 -07:00
anero 03be692a90
Updated gemspect to support recently released v1.1.0 of grape 2018-08-14 12:28:05 -03:00
Ryan Buckley 03da0189a5 Reduce files included in gem 2017-07-07 12:06:38 -07:00
Ryan Buckley 664e99fe75 Update changelog with 1.9 2017-07-07 11:58:33 -07:00
Ryan Buckley 669084ad7b Version 1.9.0 2017-07-07 11:55:34 -07:00
Ryan Buckley c65301549d Merge pull request #19 from badlamer/master
allow install on grape 1.0
2017-07-07 11:50:30 -07:00
Yury Druzhkov e9d682b12b allow install on grape 1.0 2017-07-04 08:51:47 +03:00
Mason McLead 6546c93512 renaming to :condensed 2017-06-02 10:20:07 -07:00
Mason McLead 4276cd642a adding an option to format log message to be one line 2017-06-02 09:59:00 -07:00
Ryan Buckley 7a2ed6be11 Version 1.8.0 2017-04-22 14:31:24 -07:00
Ryan Buckley ab49f3a7a1 Merge pull request #17 from visits-works/feature/with_header_option
Add 'headers' option to log request headers
2017-04-21 11:48:42 -07:00
Keisuke Yamamoto b52ea9adeb Bugfix, logic optimization, correct code format
- Fix typo in README
- Replace tab character with spaces and correct wrong indents.
- Bugfix: headers are not sorted by keys when the option is `:all`
- Optimize filtering logic
2017-04-21 14:13:57 +09:00
Keisuke Yamamoto 753b94ecb0 Add 'headers' option to log request headers. 2017-04-20 12:40:38 +09:00
Ryan Buckley 9c3ef01017 version 1.7.1 2016-11-01 19:32:35 -07:00
Ryan Buckley 01fe05a1c7 Add changelog entry 2016-11-01 19:32:10 -07:00
Ryan Buckley b8623b9e0a Add code of conduct ❤️ 2016-11-01 19:29:22 -07:00
Ryan Buckley 3708afad53 Update travis rubies 2016-11-01 19:12:41 -07:00
Ryan Buckley f34a839bf9 Change post message a bit 2016-11-01 19:07:00 -07:00
Ryan Buckley 0873cae652 Update post install message 2016-09-16 16:34:29 -07:00
Ryan Buckley ad6116e210 Merge pull request #14 from ridiculous/spec-for-after_exception
Add spec for testing exception logging
2016-09-16 12:37:06 -07:00
16 changed files with 319 additions and 49 deletions

5
.byebug_history Normal file
View File

@ -0,0 +1,5 @@
exit
c
log_statements.compact.delete_if(&:empty?).each(&:strip!)
log_statements.compact.delete_if(&:empty?).each(&:lstrip)
log_statements.compact.delete_if(&:empty?).each(&:strip)

View File

@ -1,9 +1,8 @@
language: ruby
rvm:
- 1.9.3
- 2.1.5
- 2.2.4
- 2.3.0
- 2.3.8
- 2.4.5
- 2.5.3
before_install:
- gem install bundler -v 1.10.5
- gem install mime-types -v 2.6.2
- gem install bundler
- gem install mime-types

View File

@ -1,3 +1,19 @@
1.12.0 (5/13/2019)
==================
* [#25] Support Rails 6.0.0 (Thanks [@serggl](https://github.com/serggl))
1.9.0 (7/7/2017)
==================
* [#19] Support Grape 1.0.0 (Thanks [@badlamer](https://github.com/badlamer))
1.8.0 (4/22/2017)
==================
* [#17] Add a `:headers` option, which can be either `:all` or an array of strings. (Thanks [@yamamotok](https://github.com/yamamotok))
1.7.1 (11/1/2016)
==================
* Log the error class name (https://github.com/ridiculous/grape-middleware-logger/pull/13)
1.7.0 (8/2/2016)
==================

30
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,30 @@
# Grape::Middleware::logger Code of Conduct
The Grape::Middleware::logger project strongly values contributors from anywhere, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, physical appearance, body size, race, ethnicity, age, religion, or nationality. As a result, the Grape::Middleware::logger team has agreed to and enforces this code of conduct in order to provide a harassment-free experience for everyone who participates in the development of Grape::Middleware::logger.
### Summary
Harassment in code and discussion or violation of physical boundaries is completely unacceptable anywhere in the Grape::Middleware::logger projects codebases, issue trackers, chat rooms, mailing lists, meetups, and any other events. Violators will be warned and then blocked or banned by the core team at or before the 3rd violation.
### In detail
Harassment includes offensive verbal comments related to level of experience, gender, gender identity and expression, sexual orientation, disability, physical appearance, body size, race, ethnicity, age, religion, nationality, the use of sexualized language or imagery, deliberate intimidation, stalking, sustained disruption, and unwelcome sexual attention.
Individuals asked to stop any harassing behavior are expected to comply immediately.
Maintainers, including the core team, are also subject to the anti-harassment policy.
If anyone engages in abusive, harassing, or otherwise unacceptable behavior, including maintainers, we may take appropriate action, up to and including warning the offender, deletion of comments, removal from the projects codebase and communication systems, and escalation to Github support.
If you are being harassed, notice that someone else is being harassed, or have any other concerns, please contact a member of the core team immediately.
We expect everyone to follow these rules anywhere in the logger projects codebases, issue trackers, IRC channel, group chat, and mailing lists.
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Finally, don't forget that it is human to make mistakes! We all do. Lets work together to help each other, resolve issues, and learn from the mistakes that we will all inevitably make from time to time.
### License
MIT

View File

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

View File

@ -22,6 +22,9 @@ gem 'grape-middleware-logger'
## Usage
```ruby
require 'grape'
require 'grape/middleware/logger'
class API < Grape::API
# @note Make sure this is above your first +mount+
insert_after Grape::Middleware::Formatter, Grape::Middleware::Logger
@ -52,23 +55,29 @@ Completed 422 in 6.29ms
The middleware logger can be customized with the following options:
* The `:logger` option can be any object that responds to `.info(String)`
* The `:condensed` option configures the log output to be on one line instead of multiple. It accepts `true` or `false`. The default configuration is `false`
* The `:filter` option can be any object that responds to `.filter(Hash)` and returns a hash.
* The `:headers` option can be either `:all` or array of strings.
+ If `:all`, all request headers will be output.
+ If array, output will be filtered by names in the array. (case-insensitive)
For example:
```ruby
insert_after Grape::Middleware::Formatter, Grape::Middleware::Logger, {
logger: Logger.new(STDERR),
filter: Class.new { def filter(opts) opts.reject { |k, _| k.to_s == 'password' } end }.new
condensed: true,
filter: Class.new { def filter(opts) opts.reject { |k, _| k.to_s == 'password' } end }.new,
headers: %w(version cache-control)
}
```
## Using Rails?
`Rails.logger` and `Rails.application.config.filter_parameters` will be used automatically as the default logger and
`Rails.logger` and `Rails.application.config.filter_parameters` will be used automatically as the default logger and
param filterer, respectively. This behavior can be overridden by passing the `:logger` or
`:filter` option when mounting.
You may want to disable Rails logging for API endpoints, so that the logging doesn't double-up. You can achieve this
You may want to disable Rails logging for API endpoints, so that the logging doesn't double-up. You can achieve this
by switching around some middleware. For example:
```ruby

View File

@ -1,4 +1,5 @@
require 'rspec/core/rake_task'
require 'bundler/gem_tasks'
RSpec::Core::RakeTask.new(:spec) do |config|
config.pattern = 'spec/lib/**/*_spec.rb'

View File

@ -2,7 +2,7 @@
Gem::Specification.new do |spec|
spec.name = 'grape-middleware-logger'
spec.version = '1.7.0'
spec.version = '1.12.0'
spec.platform = Gem::Platform::RUBY
spec.authors = ['Ryan Buckley']
spec.email = ['arebuckley@gmail.com']
@ -11,22 +11,21 @@ Gem::Specification.new do |spec|
spec.homepage = 'https://github.com/ridiculous/grape-middleware-logger'
spec.license = 'MIT'
spec.files = `git ls-files -z`.split("\x0")
spec.files = `git ls-files -z`.split("\x0").grep(%r{^lib/|gemspec})
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']
spec.post_install_message = %q{
GrapeMiddlewareLogger v1.7+ should be mounted with +insert_after+ to properly include POST request params:
insert_after Grape::Middleware::Formatter, Grape::Middleware::Logger
Grape::Middleware::Logger 1.7+ should be mounted with +insert_after+ to properly include POST params:
insert_after Grape::Middleware::Formatter, Grape::Middleware::Logger
}
spec.add_dependency 'grape', '>= 0.17', '< 1'
spec.add_development_dependency 'bundler', '~> 1.7'
spec.add_dependency 'grape', '>= 0.17'
spec.add_development_dependency 'mime-types', '~> 2'
spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'rake', '>= 12.3.3'
spec.add_development_dependency 'rspec', '>= 3.2', '< 4'
end

View File

@ -7,7 +7,7 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
attr_reader :logger
class << self
attr_accessor :logger, :filter
attr_accessor :logger, :filter, :headers, :condensed
def default_logger
default = Logger.new(STDOUT)
@ -19,6 +19,8 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
def initialize(_, options = {})
super
@options[:filter] ||= self.class.filter
@options[:headers] ||= self.class.headers
@options[:condensed] ||= false
@logger = options[:logger] || self.class.logger || self.class.default_logger
end
@ -26,14 +28,19 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
start_time
# sets env['grape.*']
super
logger.info ''
logger.info %Q(Started %s "%s" at %s) % [
env[Grape::Env::GRAPE_REQUEST].request_method,
env[Grape::Env::GRAPE_REQUEST].path,
start_time.to_s
]
logger.info %Q(Processing by #{processed_by})
logger.info %Q( Parameters: #{parameters})
log_statements = [
'',
%Q(Started %s "%s" at %s) % [
env[Grape::Env::GRAPE_REQUEST].request_method,
env[Grape::Env::GRAPE_REQUEST].path,
start_time.to_s
],
%Q(Processing by #{processed_by}),
%Q( Parameters: #{parameters})]
log_statements.append(%Q( Headers: #{headers})) if @options[:headers]
log_info(log_statements)
end
# @note Error and exception handling are required for the +after+ hooks
@ -62,8 +69,12 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
end
def after(status)
logger.info "Completed #{status} in #{((Time.now - start_time) * 1000).round(2)}ms"
logger.info ''
log_info(
[
"Completed #{status} in #{((Time.now - start_time) * 1000).round(2)}ms",
''
]
)
end
#
@ -91,6 +102,18 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
end
end
def headers
request_headers = env[Grape::Env::GRAPE_REQUEST_HEADERS].to_hash
return Hash[request_headers.sort] if @options[:headers] == :all
headers_needed = Array(@options[:headers])
result = {}
headers_needed.each do |need|
result.merge!(request_headers.select { |key, value| need.to_s.casecmp(key).zero? })
end
Hash[result.sort]
end
def start_time
@start_time ||= Time.now
end
@ -106,6 +129,14 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
result.concat endpoint.options[:path].map { |path| path.to_s.sub(BACKSLASH, '') }
endpoint.options[:for].to_s << result.join(BACKSLASH)
end
def log_info(log_statements=[])
if @options[:condensed]
logger.info log_statements.compact.delete_if(&:empty?).each(&:strip!).join(" - ")
else
log_statements.each { |log_statement| logger.info log_statement }
end
end
end
require_relative 'logger/railtie' if defined?(Rails)

View File

@ -1,6 +1,12 @@
class Grape::Middleware::Logger::Railtie < Rails::Railtie
initializer 'grape.middleware.logger', after: :load_config_initializers do
options = Rails::VERSION::MAJOR < 5 ? { after: :load_config_initializers } : {}
initializer 'grape.middleware.logger', options do
Grape::Middleware::Logger.logger = Rails.application.config.logger || Rails.logger.presence
Grape::Middleware::Logger.filter = ActionDispatch::Http::ParameterFilter.new Rails.application.config.filter_parameters
parameter_filter_class = if Rails::VERSION::MAJOR >= 6
ActiveSupport::ParameterFilter
else
ActionDispatch::Http::ParameterFilter
end
Grape::Middleware::Logger.filter = parameter_filter_class.new Rails.application.config.filter_parameters
end
end

View File

@ -32,8 +32,10 @@ FactoryGirl.define do
grape_request { build :grape_request }
grape_endpoint { build(:grape_endpoint) }
params { grape_request.params }
headers { grape_request.headers }
post_params { { 'secret' => 'key', 'customer' => [] } }
rails_post_params { { 'name' => 'foo', 'password' => 'access' } }
other_env_params { {} }
initialize_with do
new.merge(
@ -42,10 +44,21 @@ FactoryGirl.define do
'action_dispatch.request.request_parameters' => rails_post_params,
Grape::Env::GRAPE_REQUEST => grape_request,
Grape::Env::GRAPE_REQUEST_PARAMS => params,
Grape::Env::GRAPE_REQUEST_HEADERS => headers,
Grape::Env::RACK_REQUEST_FORM_HASH => post_params,
Grape::Env::API_ENDPOINT => grape_endpoint
)
).merge(other_env_params)
end
trait :prefixed_basic_headers do
other_env_params { {
'HTTP_VERSION' => 'HTTP/1.1',
'HTTP_CACHE_CONTROL' => 'max-age=0',
'HTTP_USER_AGENT' => 'Mozilla/5.0',
'HTTP_ACCEPT_LANGUAGE' => 'en-US'
} }
end
end
factory :grape_endpoint, class: Grape::Endpoint do
@ -84,9 +97,20 @@ FactoryGirl.define do
end
factory :grape_request, class: OpenStruct do
headers { {} }
initialize_with {
new(request_method: 'POST', path: '/api/1.0/users', headers: {}, params: { 'id' => '101001' })
new(request_method: 'POST', path: '/api/1.0/users', headers: headers, params: { 'id' => '101001' })
}
trait :basic_headers do
headers { {
'Version' => 'HTTP/1.1',
'Cache-Control' => 'max-age=0',
'User-Agent' => 'Mozilla/5.0',
'Accept-Language' => 'en-US'
} }
end
end
factory :app do

View File

@ -1,3 +1,4 @@
require 'tempfile'
class RailsApp < Rails::Application
RailsLogger = Class.new Logger
config.logger = RailsLogger.new(Tempfile.new '')

View File

@ -0,0 +1,65 @@
require 'spec_helper'
describe Grape::Middleware::Logger, type: :integration do
let(:app) { build :app }
subject { described_class.new(app, options) }
let(:grape_endpoint) { build(:grape_endpoint) }
let(:env) { build(:expected_env, :prefixed_basic_headers, grape_endpoint: grape_endpoint) }
context ':all option is set to option headers' do
let(:options) { {
filter: build(:param_filter),
headers: :all,
logger: Logger.new(Tempfile.new('logger'))
} }
it 'all headers will be shown, headers will be sorted by name' 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", "secret"=>"[FILTERED]", "customer"=>[], "name"=>"foo", "password"=>"[FILTERED]"})
expect(subject.logger).to receive(:info).with %Q( Headers: {"Accept-Language"=>"en-US", "Cache-Control"=>"max-age=0", "User-Agent"=>"Mozilla/5.0", "Version"=>"HTTP/1.1"})
expect(subject.logger).to receive(:info).with /Completed 200 in \d+.\d+ms/
expect(subject.logger).to receive(:info).with ''
subject.call!(env)
end
end
context 'list of names ["User-Agent", "Cache-Control"] is set to option headers' do
let(:options) { {
filter: build(:param_filter),
headers: %w(User-Agent Cache-Control),
logger: Logger.new(Tempfile.new('logger'))
} }
it 'two headers will be shown' 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", "secret"=>"[FILTERED]", "customer"=>[], "name"=>"foo", "password"=>"[FILTERED]"})
expect(subject.logger).to receive(:info).with %Q( Headers: {"Cache-Control"=>"max-age=0", "User-Agent"=>"Mozilla/5.0"})
expect(subject.logger).to receive(:info).with /Completed 200 in \d+.\d+ms/
expect(subject.logger).to receive(:info).with ''
subject.call!(env)
end
end
context 'a single string "Cache-Control" is set to option headers' do
let(:options) { {
filter: build(:param_filter),
headers: 'Cache-Control',
logger: Logger.new(Tempfile.new('logger'))
} }
it 'only Cache-Control header will be shown' 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", "secret"=>"[FILTERED]", "customer"=>[], "name"=>"foo", "password"=>"[FILTERED]"})
expect(subject.logger).to receive(:info).with %Q( Headers: {"Cache-Control"=>"max-age=0"})
expect(subject.logger).to receive(:info).with /Completed 200 in \d+.\d+ms/
expect(subject.logger).to receive(:info).with ''
subject.call!(env)
end
end
end

View File

@ -11,14 +11,28 @@ describe Grape::Middleware::Logger, type: :integration do
let(:grape_endpoint) { build(:grape_endpoint) }
let(:env) { build(:expected_env, grape_endpoint: grape_endpoint) }
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", "secret"=>"[FILTERED]", "customer"=>[], "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)
context 'when the option[:condensed] is false' do
let(:options) { { filter: build(:param_filter), logger: Logger.new(Tempfile.new('logger')), condensed: false } }
it 'logs all parts of the request on multiple lines' 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", "secret"=>"[FILTERED]", "customer"=>[], "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
end
context 'when the options[:condensed is true' do
let(:options) { { filter: build(:param_filter), logger: Logger.new(Tempfile.new('logger')), condensed: true } }
it 'logs all parts of the request on one line' do
expect(subject.logger).to receive(:info).with %Q(Started POST "/api/1.0/users" at #{subject.start_time} - Processing by TestAPI/users - Parameters: {"id"=>"101001", "secret"=>"[FILTERED]", "customer"=>[], "name"=>"foo", "password"=>"[FILTERED]"})
expect(subject.logger).to receive(:info).with /Completed 200 in \d+.\d+ms/
subject.call!(env)
end
end
context 'when an exception occurs' do

View File

@ -42,14 +42,27 @@ describe Grape::Middleware::Logger, type: :rails_integration do
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", "secret"=>"key", "customer"=>[], "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)
context 'when the option[:condensed] is false' do
let(:options) { { condensed: false } }
it 'logs all parts of the request on multiple lines' 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", "secret"=>"key", "customer"=>[], "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
end
context 'when the option[:condensed] is true' do
let(:options) { { condensed: true } }
it 'logs all parts of the request on one line' do
expect(subject.logger).to receive(:info).with %Q(Started POST "/api/1.0/users" at #{subject.start_time} - Processing by TestAPI/users - Parameters: {"id"=>"101001", "secret"=>"key", "customer"=>[], "name"=>"foo", "password"=>"[FILTERED]"})
expect(subject.logger).to receive(:info).with /Completed 200 in \d+.\d+ms/
subject.call!(env)
end
end
describe 'the "processing by" section' do

View File

@ -0,0 +1,57 @@
require 'spec_helper'
describe Grape::Middleware::Logger do
let(:app) { double('app') }
subject { described_class.new(app, options) }
describe '#headers' do
let(:grape_request) { build :grape_request, :basic_headers }
let(:env) { build :expected_env, grape_request: grape_request }
before { subject.instance_variable_set(:@env, env) }
context 'when @options[:headers] has a symbol :all' do
let(:options) { { headers: :all, logger: Object.new } }
it 'all request headers should be retrieved' do
expect(subject.headers.fetch('Accept-Language')).to eq('en-US')
expect(subject.headers.fetch('Cache-Control')).to eq('max-age=0')
expect(subject.headers.fetch('User-Agent')).to eq('Mozilla/5.0')
expect(subject.headers.fetch('Version')).to eq('HTTP/1.1')
end
end
context 'when @options[:headers] is a string "user-agent"' do
let(:options) { { headers: 'user-agent', logger: Object.new } }
it 'only "User-Agent" should be retrieved' do
expect(subject.headers.fetch('User-Agent')).to eq('Mozilla/5.0')
expect(subject.headers.length).to eq(1)
end
end
context 'when @options[:headers] is an array of ["user-agent", "Cache-Control", "Unknown"]' do
let(:options) { { headers: %w(user-agent Cache-Control Unknown), logger: Object.new } }
it '"User-Agent" and "Cache-Control" should be retrieved' do
expect(subject.headers.fetch('Cache-Control')).to eq('max-age=0')
expect(subject.headers.fetch('User-Agent')).to eq('Mozilla/5.0')
end
it '"Unknown" name does not make any effect' do
expect(subject.headers.length).to eq(2)
end
end
end
describe '#headers if no request header' do
let(:env) { build :expected_env }
before { subject.instance_variable_set(:@env, env) }
context 'when @options[:headers] is set, but no request header is there' do
let(:options) { { headers: %w(user-agent Cache-Control), logger: Object.new } }
it 'subject.headers should return empty hash' do
expect(subject.headers.length).to eq(0)
end
end
end
end