A Rails application has many configuration options. Learn how to test one of them.
Why?
Well, what are the consequences of an improperly configurated application? Poor performance? Loss of revenue? Litigation? None of these consequences is desirable. We can avoid them by configuring an application correctly. And, we can be confident that it will stay that way by running examples of correct behavior against the configuration every time it's changed.
Exploring the Configuration
Rails application configuration is primarily exposed in config/application.rb
via an Application
class. [1] Here's an elided example.
The application configuration can also be explored in the console, as shown below. Using pry is optional. [2].
$ rails c
Loading development environment (Rails 3.2.3)
1.9.3p125 :001 > pry
[1] pry(main)> Foo::Application.config
=> #<Rails::Application::Configuration:0x007ff93bc52010
...
@filter_parameters=[:password],
@force_ssl=false,
...
@time_zone="Central Time (US & Canada)",
...
Testing the Configuration
I've highlighted the filter_parameters
option in the file and the console. It informs the application to censor the listed request parameters from logs. Rails filters :password
by default. Let's write an example that proves :password
and :social_security_number
will be filtered.
In an editor, create a new file named spec/config/application_spec.rb
, and write the following two examples.
require 'spec_helper'
describe Portal::Application, 'configuration' do
let(:config) { described_class.config }
[:password, :social_security_number].each do |param|
it "filters #{param.inspect} from logs" do
config.filter_parameters.should include(param)
end
end
end
Run the examples, specifying the "documentation" format for output. [3]
$ rspec spec/config/application_spec.rb --format documentation
Foo::Application configuration
filters :password from logs
filters :social_security_number from logs (FAILED - 1)
Failures:
1) Foo::Application configuration filters :social_security_number from logs
Failure/Error: config.filter_parameters.should include(param)
expected [:password] to include :social_security_number
Diff:
@@ -1,2 +1,2 @@
-[:social_security_number]
+[:password]
# ./spec/config/application_spec.rb:8:in `block (3 levels) in <top (required)>'
Finished in 0.00428 seconds
2 examples, 1 failures
Failed examples:
rspec ./spec/config/application_spec.rb:7 # Foo::Application configuration filters :social_security_number from logs
Perfect. We have one passing example for :password
, and we have one failing example that indicates exactly what we need to do to correct our configuration.
Open config/application.rb
in an editor and find the filter_paramters
option.
module Foo
class Application < Rails::Application
# ...
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
# ...
end
end
To satisfy the failing examples, add :social_security_number
to filter_parameters
.
module Foo
class Application < Rails::Application
# ...
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password, :social_security_number]
# ...
end
end
Rerun the examples. filter_parameters
is set as desired.
$ rspec spec/config/application_spec.rb --format documentation
Foo::Application configuration
filters :password from logs
filters :social_security_number from logs
Finished in 0.00339 seconds
2 examples, 0 failures
Conclusion
A Rails applicaton exposes its configuration via an Application
class. We can easily and simply test that the configuration is what we want it to be and that it remains that way. Thus, we can mitigate the risks, some severe, of an improperly configured application.
Notes
[1] Environment-specific configuration can be set in files in config/environments
.
[2] Here, pry is useful for its much nicer format than the default. It's so much more than that, though. I highly recommend adding it to your toolset. It vastly expands your capabilities to interact with Ruby code.
[3] The --format documentation
option commands RSpec to display examples grouped and nested under their descriptions. Run rspec --help
for more information. If you find a set of options that you always want to use, you can add them to a .rspec
file in your home directory. See read command line configuration options from files.