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')raisesCalmLens::NotFoundErrorwith status404. - 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.servereturns the stored bytes withcontent-type,content-lengthandx-request-idheaders.
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.