Table of Contents

Class TestActorProvider

Namespace
Trellis.Testing
Assembly
Trellis.Testing.dll

Mutable IActorProvider for integration and authorization testing. Stores the current actor in an AsyncLocal<T> so parallel tests using overlapping WithActor(Actor) scopes never interfere with each other.

public sealed class TestActorProvider : IActorProvider
Inheritance
TestActorProvider
Implements
Inherited Members
Extension Methods

Examples

var actorProvider = new TestActorProvider("admin", "Orders.Read", "Orders.Write");

// Temporarily switch to a restricted user
await using var scope = actorProvider.WithActor("user-1", "Orders.Read");
var result = await mediator.Send(new CreateOrderCommand());
result.Should().BeFailure(); // missing Orders.Write
// scope disposes → actor reverts to admin

Constructors

TestActorProvider(string, params string[])

Initializes a new TestActorProvider with an actor created from the specified user ID and permissions.

public TestActorProvider(string userId, params string[] permissions)

Parameters

userId string

The unique identifier of the actor.

permissions string[]

The permissions granted to the actor.

TestActorProvider(Actor)

Initializes a new TestActorProvider with the specified Actor.

public TestActorProvider(Actor actor)

Parameters

actor Actor

The initial (default) actor returned when no scope is active.

Exceptions

ArgumentNullException

Thrown when actor is null.

Methods

GetCurrentActorAsync(CancellationToken)

Returns the current authenticated actor for the request, or None when the request has no usable authenticated actor.

public Task<Maybe<Actor>> GetCurrentActorAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Token to cancel the asynchronous operation.

Returns

Task<Maybe<Actor>>

From<T>(T?) wrapping the resolved Actor when an authenticated identity is present and the framework can identify the actor.

None when the request has no usable authenticated actor — typically the request lacks credentials, the authentication middleware did not produce an authenticated identity, or the authenticated identity is missing the claim needed to identify the actor. The Trellis mediator authorization pipeline maps this to Error.AuthenticationRequired (HTTP 401) per RFC 9110 §15.5.2. "No authenticated actor" is client-error state, not an exception — model it via the return value, not by throwing.

Exceptions

InvalidOperationException

Thrown only for genuine infrastructure or configuration failures — for example, the provider was invoked outside an HTTP request scope (missing HttpContext), a user-supplied mapping delegate threw, or an option is misconfigured. The mediator pipeline does not catch this case; it surfaces as Error.Unexpected (HTTP 500), which is correct because these are bugs rather than authentication state. Do not throw for "missing actor" — return None instead.

WithActor(string, params string[])

Temporarily replaces the current actor with one created from the specified user ID and permissions. Returns a TestActorScope that restores the previous actor on dispose.

public TestActorScope WithActor(string userId, params string[] permissions)

Parameters

userId string

The unique identifier of the actor.

permissions string[]

The permissions granted to the actor.

Returns

TestActorScope

A disposable scope that restores the previous actor.

WithActor(Actor)

Temporarily replaces the current actor for the current async flow. Returns a TestActorScope that restores the previous actor on dispose.

public TestActorScope WithActor(Actor actor)

Parameters

actor Actor

The actor to use for the duration of the scope.

Returns

TestActorScope

A disposable scope that restores the previous actor.

Exceptions

ArgumentNullException

Thrown when actor is null.