Skip to content

Latest commit

 

History

History
122 lines (89 loc) · 3.6 KB

ruby.mdx

File metadata and controls

122 lines (89 loc) · 3.6 KB
title Ruby SDK
description Test email flows in RSpec, Minitest and Capybara — OTPs and magic links auto-extracted. Zero dependencies.

Install

gem install zerodrop

Or in your Gemfile:

gem "zerodrop", group: :test

Zero runtime dependencies. Ruby 3.0+.

Quick start

require "zerodrop"

mail = ZeroDrop::Client.new
inbox = mail.generate_inbox
# => "swift-x7k29ab@zerodrop-sandbox.online"

# Trigger your app's email flow with the inbox address...

email = mail.wait_for_latest(inbox, timeout: 15)

email.otp        # => "123456" — auto-extracted, no regex
email.magic_link # => "https://..." — auto-extracted

RSpec + Capybara

RSpec.describe "Signup email verification", type: :system do
  let(:mail) { ZeroDrop::Client.new }

  it "verifies the account via emailed OTP" do
    inbox = mail.generate_inbox

    visit "/signup"
    fill_in "Email", with: inbox
    fill_in "Password", with: "TestPassword123!"
    click_button "Create account"

    email = mail.wait_for_latest(inbox, timeout: 15)

    expect(email.otp).not_to be_nil
    fill_in "Code", with: email.otp
    click_button "Verify"

    expect(page).to have_current_path("/dashboard")
  end
end

Filtering

email = mail.wait_for_latest(
  inbox,
  timeout: 15,
  filter: ZeroDrop::Filter.new(
    from: "noreply@yourapp.com",
    has_otp: true
  )
)

All string filters are case-insensitive partial matches.

Parallel tests

generate_inbox runs locally — safe with parallel_tests, flatware, turbo_tests. Every call returns a unique isolated inbox.

Free API key (private inboxes)

Without a key, anyone who knows an inbox's name can read it, and one sender can reach only 5 different inboxes a day: past that, the inbox gets a notice from notice@zerodrop.dev instead of the email. Sign in with GitHub at zerodrop.dev/keys for a free key and set it as ZERODROP_API_KEY. With zerodrop 0.2.0 or later, the client reads it, generate_inbox starts names with your key's prefix, only your key can read those inboxes, and mail to them isn't limited:

mail = ZeroDrop::Client.new # reads ZERODROP_API_KEY
mail.generate_inbox
# => "k7x2-swift-x7k29ab@zerodrop-sandbox.online", where k7x2 is your prefix
mail.prefix # => "k7x2"

Error handling

begin
  email = mail.wait_for_latest(inbox, timeout: 15)
rescue ZeroDrop::TimeoutError
  # No email arrived
rescue ZeroDrop::HeldError => e
  # No API key, and ZeroDrop held the email (daily limit); e.message says why
rescue ZeroDrop::AuthError => e
  # The inbox belongs to another key's prefix, or your key is wrong; e.message says which
rescue ZeroDrop::NetworkError => e
  # Transport failure
end

ZeroDrop::HeldError is new in 0.3.0. Without an API key, one sender can reach only 5 different inboxes a day; past that, the email isn't stored and the inbox gets a notice instead. wait_for_latest then raises HeldError at once rather than waiting for the timeout, and fetch_latest raises it when nothing matches. Older versions treat the notice as an email: without a filter they return it, and a filter such as has_otp: true skips it, so the wait times out. A free key from zerodrop.dev/keys lifts the limit for inboxes under your key's prefix.

Workspaces & self-hosting

mail = ZeroDrop::Client.new(
  api_key: ENV["ZERODROP_API_KEY"], # optional since 0.2.0: the client reads it anyway
  base_url: "https://your-instance.yourdomain.com"
)

Links