Ruby testing

Test your integration without API calls using the Ruby SDK.

Mock client

require 'calmlens/testing'
mock = CalmLens::MockClient.new # accepts project_id:, now:, create_id:, queued_status:, analyzed_status: and client settings
asset = mock.assets.moderate(name: 'note', content: {plain_text: 'hello', type: 'text/plain'})
mock.assets.retrieve(asset_id: asset['id'])['status'] # => "approved"
mock.assets.list(filter: 'status==approved')['total'] # => 1
mock.cdn.serve(asset_identifier: asset['id']).body    # => "hello"

request = mock.requests.last
request.method # => "GET"
request.path   # => "/assets/project-1/<asset id>/content"

The mock runs the real client's validation, encoding, retries and error handling, then answers from an in-memory stand-in for the API and CDN:

  • Uploads create assets you can retrieve, list, search, move, update and delete. Folders, multipart uploads, idempotency keys and lenses behave like the API's.
  • Errors use the API's codes, HTTP statuses and body shape, so mock.assets.retrieve(asset_id: 'missing') raises CalmLens::NotFoundError with status 404.
  • List filters support == and !=, with * wildcards, joined by ; (and) and , (or), and ordering is applied. Other filter operators raise an error instead of being ignored.
  • cdn.serve returns the stored bytes with content-type, content-length and x-request-id headers.

The mock does not classify content. moderate gives each asset analyzed_status:, which can be a status, fields to merge ({'status' => 'rejected', 'report' => {'flagged' => true}}) or a callable that receives the asset; create gives queued_status:. Change records through mock.state, such as mock.state.assets[id]['status'] = 'rejected', to arrange a test.

Events

cursor = mock.events.list['cursor']
mock.enqueue_event(type: 'asset.approved', asset_id: asset['id'], facts: [{key: 'reviewer-name', value: 'Sam'}])
mock.events.each(after: cursor).map { |event| event['type'] } # => ["asset.approved"]

Scripted responses and failures

Queued responses and errors answer the next requests in order, before the stand-in:

mock.enqueue(status: 429, body: {code: 'rate/limited', message: 'Slow down'}, headers: {'retry-after' => '0'})
mock.enqueue_raw(body: 'not json')
mock.enqueue_error(Net::ReadTimeout.new)   # raises CalmLens::TimeoutError (sdk/timeout)
mock.enqueue_error(Errno::ECONNRESET.new)  # raises CalmLens::ConnectionError (sdk/transport-error)

Retries apply as in the real client, so a queued 503 on a read is retried. Pass max_retries: 0 to see the first failure. mock.requests returns copies of every request received, with method, url, path (relative to the API or CDN base URL), decoded query, headers and body.

Signing in

Signing out

Cookies on CalmLens

We use essential cookies to keep you signed in and the site secure. With your permission, we'll also use functional cookies to remember preferences such as your layout and documentation language, and to offer Google One Tap sign-in. We don't use analytics or advertising cookies. Manage cookies