Skip to content

Instantly share code, notes, and snippets.

@murbanski
Last active February 27, 2024 19:53
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save murbanski/6b971a3edc91b562acaf to your computer and use it in GitHub Desktop.
Save murbanski/6b971a3edc91b562acaf to your computer and use it in GitHub Desktop.
RSpec 3.1 and Rails 4 HTTP Digest Auth testing
# spec/controllers/api_clients_controller_spec.rb
RSpec.describe APIClientsController, type: :controller do
let(:api_client) { mock_model(APIClient) }
context "when HTTP Digest auth credentials are invalid" do
before do
authenticate_with_http_digest("invalid_login", "invalid_password") do
get :index
end
end
it { should respond_with(:unauthorized) }
end
context "when HTTP Digest auth credentials are missing" do
before do
get :index
end
it { should respond_with(:unauthorized) }
end
describe "GET #index" do
before do
expect(APIClient).to receive(:ordered_by_name).and_return([:api_client1, :api_client2])
authenticate_with_http_digest("valid_username", "valid_password") do
get :index
end
end
it "loads @api_clients to be shown in the template" do
expect(assigns[:api_clients]).to eq([:api_client1, :api_client2])
end
it { should respond_with(:success) }
it { should render_template(:index) }
end
end
# spec/support/digest_auth_helpers.rb
module SpecHelpers
module DigestAuthHelpers
def authenticate_with_http_digest(user, password, &request_trigger)
request.env['HTTP_AUTHORIZATION'] = encode_credentials(user, password, &request_trigger)
request_trigger.call
end
# Shamelessly stolen from the Rails 4 test framework.
# See https://github.com/rails/rails/blob/a3b1105ada3da64acfa3843b164b14b734456a50/actionpack/test/controller/http_digest_authentication_test.rb
def encode_credentials(user, password, &request_trigger)
# Perform unauthenticated request to retrieve digest parameters to use on subsequent request
request_trigger.call
expect(response).to have_http_status(:unauthorized)
credentials = decode_credentials(response.headers['WWW-Authenticate'])
credentials.merge!({ username: user, nc: "00000001", cnonce: "0a4f113b", password_is_ha1: false })
path_info = request.env['PATH_INFO'].to_s
credentials.merge!(uri: path_info)
request.env["ORIGINAL_FULLPATH"] = path_info
ActionController::HttpAuthentication::Digest.encode_credentials(request.method, credentials, password, credentials[:password_is_ha1])
end
# Also shamelessly stolen from the Rails 4 test framework.
# See https://github.com/rails/rails/blob/a3b1105ada3da64acfa3843b164b14b734456a50/actionpack/test/controller/http_digest_authentication_test.rb
def decode_credentials(header)
ActionController::HttpAuthentication::Digest.decode_credentials(header)
end
end
end
# spec/rails_helper.rb
RSpec.configure do |config|
# ...
config.include SpecHelpers::DigestAuthHelpers, type: :controller
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment