Similar to stubbing environment variable, can we stub Rails credential key?
Ruby version: 2.6.1
Rails version: 5.2.2
Rspec version: 3.8
allow(Rails.application.credentials).to receive(:my_token).and_return('')
allow(Rails.application.credentials).to receive(:my_token).and_return('123')
Rails.application.credentials.my_token
=> '123'
As credentials is an object you have to stub what you wish to retrieve. So:
allow(Rails.application.credentials).to receive(:my_token).and_return('123')
Rails.application.credentials.my_token
# => 123
allow(Rails.application.credentials).to receive(:[]).with(:my_token).and_return('345')
Rails.application.credentials[:my_token]
# => 345
It'd be better to use it as designed and setup a test environment set of credentials.
Thanks @JonRowe I edited the post to actually focus on the issue (described in your first example).
my_token is already defined in credentials.yml.enc but I need to override the value in my specs.
I tried indeed the following but it keeps the value defined in credentials.yml.enc.
allow(Rails.application.credentials).to receive(:my_token).and_return('123')
Rails.application.credentials.my_token
# => value_from_credentials_file
I just did a test on a fresh_app
And I had no issue.
My credentials file looks like this:
aws:
access_key_id: 123
secret_access_key: 345
olimart: 'from_config'
# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: xxxx
require 'rails_helper'
describe 'Credentials' do
it 'stubs credentials' do
allow(Rails.application.credentials).to receive(:olimart).and_return('123')
expect(Rails.application.credentials.olimart).to eq('123')
end
end
no issues.
@benoittgt What's your master key?
Amazing. The exact same code fails on my end. I appreciate your help.
@benoittgt I'll leave it up to you to decide if this should be reopened :)
I'll leave it up to you to decide if this should be reopened :)
don't think so. Just need to find out why but in the meantime we came up with a workaround.
Actually, I have the exact same issue, and I cannot figure out why, @olimart, what is the workaround you implemented ?
@Uelb
shared_context 'encrypted configuration' do
def stub_credential(key, value)
allow(Rails.application).to receive(:credentials).and_return(OpenStruct.new(key.to_sym => value))
end
end
# usage
stub_credential(:my_credential, 123)
what is the usage for a deeper structure, for example if the credentials.yml file has
test:
level:
MY_DEEP_ENV_VAR: 12345
(sorry, the above should be indented as per a .yml file
would you suggest:
stub_credential([:test][:level][:MY_DEEP_ENV_VAR], 67890) ??
allow(Rails.application).to receive_message_chain(:test, :level, :MY_DEEP_ENV_VAR => 67890)
Rubocop was complaining about receive_message_chain, so I think I'm going to go with
allow(Rails.application).to receive(:credentials).and_return(JSON.parse({ checkr: { secret: 'super duper secret' } }.to_json, object_class: OpenStruct))