Published from
docs/guides/testing.md. Edit that file — this page is generated when the docs site builds.
Testing your app
See also: Concepts & glossary.
Testing your app
require "current_scope/test_helpers"
class ApproveButtonComponentTest < ViewComponent::TestCase
include CurrentScope::TestHelpers
test "renders for a reviewer" do
with_current_user(users(:reviewer)) do
render_inline ApproveButtonComponent.new(report: reports(:pending))
assert_selector "button", text: "Approve"
end
end
end
with_current_user is for in-process unit/view/component checks. To test your own controllers behind the gate in a request or system spec, seed real grants with grant_role! / grant_scoped_role! — they persist assignment rows that survive the request cycle (which with_current_user cannot, since Context re-resolves the subject on every real request). They seed grants only; your app still signs the subject in through its own auth. A second org-wide grant_role! for the same subject raises (one org role per subject) and names CurrentScope.grant! for replace or scoped roles for additive access:
class ReportsAccessTest < ActionDispatch::IntegrationTest
include CurrentScope::TestHelpers
test "a reviewer can list but not destroy" do
reviewer = users(:reviewer)
grant_role!(reviewer, role: roles(:member)) # org-wide grant
grant_scoped_role!(reviewer, role: roles(:viewer), record: reports(:q3)) # one record
sign_in reviewer # your app's own auth
get reports_path
assert_response :success
# Assert the denial too — a test that only walks the allow path cannot
# tell you the gate is still closed on everything else.
delete report_path(reports(:q3))
assert_response :forbidden
end
end
CurrentAttributes resets around every request, job, and test — the ambient subject cannot leak between executions.