How to test the presence of environnements variables in Rspec - ruby-on-rails

Question
There are many ways to achieve that goal but I would like to know what is the best way to tests the presence of the environmental variables inside a Ruby on Rails project.
Context
We recently had a production issue related to a missing environment variable in one of our Rails project.
To prevent this from happening again, I would like to test the presence of the environments variable in the application.yml configuration file.
I am using Ruby 2.5, Rails 4.2, Spring 2.

Unless checking this specifically in application.yml is an absolute requirement (why?), here is my take. Make a config/initializers/env.rb and put in there something like
%i[FOO BAR BAZ].each do |var|
ENV[var] = ENV.fetch(var)
end
What this does is reads all of your required environment variables (FOO, BAR, BAZ etc.) and Hash#fetch them which will 'raise' if this variable is not set at boot time.

Related

Is there a way to find current environment in a Ruby application similar to rails.env?

I need to implement a feature that sets some Env vars conditionally based on current environment(dev,test,prod). I know in rails this can be accomplished with rails.env. Is there a similar method for Ruby?
No, vanilla ruby doesn't have a concept of "environment". You will have to build this yourself. One simple way is to use an environment variable and read it.
For example, you can require a MYAPP_ENVIRONMENT environment variable. Then you read it with myapp_environment = ENV['MYAPP_ENVIRONMENT']. Then you might have hashes or some other data structure to determine values that are specific to that environment:
ENDPOINT_A = {
prod: 'https://prod.my_company.com',
stage: 'https://stage.my_company.com'
}
Similarly for other variables. Note that the endpoint string is a ruby variable, not an environment variable. You should NOT set environment variables from the ruby code that uses them. The whole point of environment variables is that they are set externally to your app and your app takes them as input to configure how it behaves.
If you want to specify the endpoint through an environment variable, you should set it in the operating system where your ruby app runs. You can do this manually on the machine or through a deployment pipeline or script.

Rails environment variables with Rack-Mini-Profiler

I'm trying to understand how the Rails 'rack-mini-profiler' actually dumps out environment variables when you append the ?pp=env on the base URL of a request. Right now my Gemfile has the gem 'dotenv-rails configured and I'm using .env.local to populate some test variables. My question is, where is the rack-mini-profiler getting the environment variables from? There are many different ways to populate env variables within a rails app, dotenv being one of them. I've been perusing the source code of rack-mini-profiler and can't seem to find it. I see the dump_env function in 'profiler.rb' but I can't see where or how these environment variables are getting pulled from within the code. It is only showing the printing of them by using a do loop of key/value pairs. Here is the example application I'm playing with and you can see the environment variables at this URL: https://preprod.rtcfingroup.com/?pp=env
Appreciate any insight. Really trying to understand this at a low level.
Miniprofiler does not actually have do anything since Ruby exposes the environmental variables through the ENV constant which is a hash like class.
dump_env just iterates over them:
body << "\n\nEnvironment\n---------------\n"
ENV.each do |k, v|
body << "#{k}: #{v}\n"
end

Access the model in production.rb rails 3

I have a model called SystemSettings with a name on and a value. It is where I store the majority of my configuration for my app. I need to be able to access it in my production.rb inside my rails 3.2 app. How would you go about doing this?
Since the Rails config such as production.rbis read before ActiveRecord is initialised you would need to use a callback:
Rails.application.configure do
ActiveSupport.on_load(:active_record) do
config.custom_variable = SystemSettings.find_by(name: "Foo").value
end
end
But since the callback executes later when ActiveRecord is ready you can't immediately use its value which is why your approach may be flawed due to race conditions.
Unless you are building something like a CMS where you need to provide a user interface to edit system settings you will be better off using environmental variables. They are immediately available from memory and do not have the overhead of a database query.
http://guides.rubyonrails.org/v3.2.9/initialization.html

Rails + Rspec: Where do I test app constants?

So I know unit tests go in spec/models, but where do constants defined in initializers and YAML files go?
Ex: This is in my ups_api.yml file:
testing_server:
confirm_url: https://wwwcie.ups.com/ups.app/xml/ShipConfirm
accept_url: https://wwwcie.ups.com/ups.app/xml/ShipAccept
This is loaded in my config/environment.rb. Where/how would I test the value of these constants?
I see no value in testing this sort of thing. You write tests to ensure the correct behavior of code. A configuration setting doesn't involved any kind of logic.

How to specify environment dependencies in Rails?

Where does one list the environment variable dependencies for a Rails application?
I don't want the app to run if the user hasn't specified the variables or at a minimum output some form of notice that says ***Don't run until you've set the following environment variables..."
I'd put something like that in config/boot.rb:
# usual boot.rb stuff...
raise 'Set PANCAKES in your environment!' unless ENV.has_key? 'PANCAKES'
The nice thing about boot.rb is that it is run very early in the start up process so you don't have to wait for all the Rails machinery to start (which can take a long time) before you know there's a problem.

Resources