Test Your Rails Application Configuration

Test Your Rails Application Configuration

Craig Demyanovich

June 11, 2012

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.

config/application.rb

module Foo
		class Application < Rails::Application
				# ...
				# Configure sensitive parameters which will be filtered from the log file.
				config.filter_parameters += [:password]
				# ...
		end
end

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.

spec/config/application_spec.rb
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.

config/application.rb

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.

config/application.rb

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.

Craig Demyanovich

Principal Crafter

Craig Demyanovich is an avid hockey player, and loves visiting new places with his wife, Sandy. He is an experienced software crafter who has delivered high quality software solutions in many different languages, and in all layers of a system’s technology stack. Throughout his career, Craig has helped teams of all sizes build applications at every stage of development, and introduced new practices and processes that prioritize the long-term health of the application.