Your biggest clients sign in with SAML. Test it like everything else.

SAML is how enterprises sign in to your app through Okta, Microsoft, or Google. Lyrebird mimics the identity provider in your tests: it builds the signed responses one would send, in a few lines of Ruby. You don’t need to know much SAML to use it.

Gemfile › gem "lyrebird", group: :test

Gem version Gem downloads

It’s just an integration test

Build a response, post it to your endpoint, and check what happened. Nothing is mocked, and the endpoint is whatever your app already has: ruby-saml, omniauth-saml, Devise, or your own code. Lyrebird’s own tests run every response through ruby-saml, rejection paths included.

test/integration/saml_test.rb
class SAMLTest < ActionDispatch::IntegrationTest
  test "consume creates a session" do
    user = users(:alice)

    response = Lyrebird::Response.build do |r|
      r.issuer      = "https://idp.example.com"
      r.destination = saml_consume_url
      r.recipient   = saml_consume_url
      r.audience    = root_url
      r.name_id     = user.email
      r.sign_with   = Lyrebird::Certificate.default

      r.attributes do |a|
        a.email      = user.email
        a.first_name = user.first_name
        a.last_name  = user.last_name
      end
    end

    post saml_consume_path, params: { SAMLResponse: response.mimic }

    assert_redirected_to dashboard_path
    assert_equal user.id, session[:user_id]
  end
end

Why fake the identity provider?

Stubs skip your verification code, and static fixtures expire. Running a real identity provider is complex and adds overhead.

Test the real thing

Responses are signed with a real certificate, so your app verifies them the same way it verifies production ones. Nothing is stubbed out.

No servers to run

Lyrebird is plain Ruby running in your test process. There’s no container to boot and no network involved, so the tests are fast and work anywhere.

Nothing goes stale

A SAML response is only valid for a few minutes, so a static fixture is already expired by your next test run. Lyrebird builds a fresh one every time.

Test what you turn away

Lyrebird also builds responses your app should reject: expired, wrong audience, or signed by a certificate it doesn’t trust.

Works out of the box

Lyrebird::Response.build with no arguments is a valid response. Certificates are generated for you and reused. Override the defaults once in test_helper.rb if you need to.

Easy to live with

The only dependency is Nokogiri, and the gem stays in your :test group. It works with Minitest, RSpec, or any other framework.

Why the name? The lyrebird copies any sound it hears, from other birds to camera shutters, well enough to fool anyone listening.

This gem does the same to your app. Its responses pass for a real identity provider’s, so single sign-on can be tested like any other feature.

Lyrebird is built by the team at Simple SAML.