Documentation
¶
Overview ¶
Package testhelper is the test harness: it builds the application over a per-process database with the committed fixtures loaded, and hands tests typed actors for each API surface.
Index ¶
- Constants
- func AutomationWithSteps(ctx context.Context, db *ent.Client, create *ent.AutomationCreate, ...) (*ent.Automation, error)
- func ColumnIsNullable(t *testing.T, sqlDB *sql.DB, table, column string) bool
- func ColumnsOf(t *testing.T, sqlDB *sql.DB, table string, columns ...string) int
- func Elapse(d time.Duration)
- func EmptyDBURL(t *testing.T) string
- func ErrorContainsOrNone(tb testing.TB, err error, want string)
- func ExternalRuleGroup(tb testing.TB, def string) externalapi.ConditionGroup
- func HTTPGet(t *testing.T, url string) (status int, body string)
- func InstallOtel(t *testing.T, setup func(context.Context) (func(context.Context) error, error))
- func IsolateOtel(t *testing.T)
- func LatestSteps(ctx context.Context, t *testing.T, db *ent.Client, automationID int64) string
- func LatestVersionID(ctx context.Context, db *ent.Client, automationID int64) (int64, error)
- func OutboxEnvelopesOn(ctx context.Context, client *ent.Client, names ...string) ([]events.Envelope, error)
- func PrivateOutbox() events.SubscribeOption
- func RealDB(t *testing.T) *sql.DB
- func RealDBURL(t *testing.T) string
- func Receive[T any](tb testing.TB, ch <-chan T, msg string) T
- func RequestCookie(name, value string) *http.Cookie
- func RequireClosed[T any](tb testing.TB, ch <-chan T, msg string)
- func RewriteURL(from, to string) func(inner ht.Client) ht.Client
- func ServiceCredentialValue(prefix, secret string) string
- func SiteRuleGroup(tb testing.TB, def string) siteapi.SiteConditionGroup
- func TryHTTPGet(ctx context.Context, url string) (status int, body string, err error)
- func UnvalidatedConstraints(t *testing.T, sqlDB *sql.DB, table string) []string
- type Authenticator
- type AuthenticatorOption
- type CapturingSender
- type Confirmations
- type FakeRelayRanges
- type FakeSES
- type FakeSignin
- func (f *FakeSignin) Authorize(t *testing.T, authURL string, who SigninIdentity) string
- func (f *FakeSignin) Credentials() config.SigninCredentials
- func (f *FakeSignin) Deny(t *testing.T, authURL string) string
- func (f *FakeSignin) Endpoints() signin.Endpoints
- func (f *FakeSignin) GitHubEndpoints() signin.Endpoints
- type Option
- func WithClock(now func() time.Time) Option
- func WithConfig(edit func(*config.Config)) Option
- func WithLicenseKey(pub ed25519.PublicKey, key string) Option
- func WithOAuthFetcher(f webhook.Doer) Option
- func WithRateLimits(limits config.RateLimits) Option
- func WithRunningVersion(v string) Option
- func WithSNSCertificates(f preset.CertFetcher) Option
- func WithSignin(f *FakeSignin) Option
- func WithSigninGitHub(f *FakeSignin) Option
- func WithStaffVolumeFloor(n int) Option
- func WithSystemSenderWithoutFrom() Option
- func WithTXTLookup(lookup sending.TXTLookup) Option
- func WithoutLicense() Option
- func WithoutSystemSender() Option
- type OutboxCursor
- type OutboxMessage
- type OutboxRow
- type RedirectBrowser
- type Reply
- type SigninEmail
- type SigninIdentity
- type TestEnv
- func (env *TestEnv) Abuse() *abuse.Detector
- func (env *TestEnv) AgeOutbox(t *testing.T, age time.Duration, offsets ...int64)
- func (env *TestEnv) CancelPendingFor(t *testing.T, contactID int64, ...) error
- func (env *TestEnv) ClaimOutbound(ctx context.Context, workspaceID, messageID int64, at time.Time)
- func (env *TestEnv) ClaimRecipient(ctx context.Context, recipientID int64, age time.Duration)
- func (env *TestEnv) CollectAcme(t *testing.T) *collectapi.Client
- func (env *TestEnv) CollectAnonymous(t *testing.T) *collectapi.Client
- func (env *TestEnv) CollectWithKey(t *testing.T, key string) *collectapi.Client
- func (env *TestEnv) CoreHolds() *holds.Holds
- func (env *TestEnv) DeliverQueuedBroadcasts(t *testing.T)
- func (env *TestEnv) DeliverToEE(t *testing.T)
- func (env *TestEnv) EnqueueJob(t *testing.T, args river.JobArgs)
- func (env *TestEnv) EnqueueRunningJob(t *testing.T, args river.JobArgs)
- func (env *TestEnv) ExpiredConfirmToken(t *testing.T, target tracking.ConfirmTarget) string
- func (env *TestEnv) ExtendHold(ctx context.Context, workspaceID, holdID int64, until time.Time)
- func (env *TestEnv) ExternalAnchor(t *testing.T) *externalapi.Client
- func (env *TestEnv) ExternalAnonymous(t *testing.T) *externalapi.Client
- func (env *TestEnv) ExternalScoped(t *testing.T, scopes ...string) *externalapi.Client
- func (env *TestEnv) ExternalVia(t *testing.T, bearer string, wrap func(inner ht.Client) ht.Client) *externalapi.Client
- func (env *TestEnv) ExternalWithToken(t *testing.T, bearer string) *externalapi.Client
- func (env *TestEnv) FixturePasskey(t *testing.T, opts ...AuthenticatorOption) *Authenticator
- func (env *TestEnv) FixturePegPasskey(t *testing.T, opts ...AuthenticatorOption) *Authenticator
- func (env *TestEnv) FixtureUnverifiedPasskey(t *testing.T, opts ...AuthenticatorOption) *Authenticator
- func (env *TestEnv) IssueServiceCredential(t *testing.T, name string, scopes ...serviceapi.ServiceScope) string
- func (env *TestEnv) JobRowsOf(t *testing.T, kind string) []*rivertype.JobRow
- func (env *TestEnv) JobSchedules(t *testing.T, kind string) []time.Time
- func (env *TestEnv) JobsOf(t *testing.T, kind string) []map[string]any
- func (env *TestEnv) MCPClient(t *testing.T, token string) *mcp.ClientSession
- func (env *TestEnv) NewAuthenticator(t *testing.T, opts ...AuthenticatorOption) *Authenticator
- func (env *TestEnv) NewRedirectBrowser(t *testing.T) *RedirectBrowser
- func (env *TestEnv) OutboundModule() *outbound.Module
- func (env *TestEnv) Outbox(t *testing.T, names ...string) []OutboxMessage
- func (env *TestEnv) OutboxCount(t *testing.T, name string, match map[string]any) int
- func (env *TestEnv) OutboxCursors(t *testing.T) map[string]OutboxCursor
- func (env *TestEnv) OutboxEnvelopes(t *testing.T, names ...string) []events.Envelope
- func (env *TestEnv) OutboxEvents(t *testing.T, names ...string) []events.DomainEvent
- func (env *TestEnv) OutboxRows(t *testing.T) []OutboxRow
- func (env *TestEnv) PlaceRecipient(ctx context.Context, broadcastID, contactID int64) int64
- func (env *TestEnv) RefreshUsage(t *testing.T, now time.Time)
- func (env *TestEnv) RunNextStep(t *testing.T, mod *stepping.Module) bool
- func (env *TestEnv) RunQueuedSteps(t *testing.T, mod *stepping.Module)
- func (env *TestEnv) ScopedBearer(t *testing.T, scopes ...string) string
- func (env *TestEnv) ScopedBearerFor(t *testing.T, workspaceID int64, scopes ...string) string
- func (env *TestEnv) ServiceClient(t *testing.T, value string) *serviceapi.Client
- func (env *TestEnv) ServiceClientOnPublicPort(t *testing.T, value string) *serviceapi.Client
- func (env *TestEnv) SetOutboxCursor(t *testing.T, group string, txID uint64, acked *int64)
- func (env *TestEnv) SiteActor(t *testing.T, email string) *siteapi.Client
- func (env *TestEnv) SiteActorVia(t *testing.T, email string, wrap func(inner ht.Client) ht.Client) *siteapi.Client
- func (env *TestEnv) SiteAnonymous(t *testing.T) *siteapi.Client
- func (env *TestEnv) SiteBrowser(t *testing.T) *siteapi.Client
- func (env *TestEnv) SiteToken(t *testing.T, email string, edit func(*gptoken.Claims)) string
- func (env *TestEnv) SiteWithToken(t *testing.T, token string) *siteapi.Client
- func (env *TestEnv) StaffAnonymous(t *testing.T) *staffapi.Client
- func (env *TestEnv) StaffWithToken(t *testing.T, token string) *staffapi.Client
- func (env *TestEnv) SuppressDestination(ctx context.Context, destination string)
- func (env *TestEnv) SuspendWorkspace(ctx context.Context, id int64, at time.Time)
- func (env *TestEnv) Transport(extraHeaders map[string]string) ht.Client
- func (env *TestEnv) TryDeliverQueuedBroadcasts(t *testing.T) error
- func (env *TestEnv) UnsubscribeFromBroadcasts(ctx context.Context, destination string)
- func (env *TestEnv) UnsuspendWorkspace(ctx context.Context, id int64)
Constants ¶
const MCPEndpoint = "http://local/mcp"
MCPEndpoint is the in-memory URL of the MCP surface (the host is a placeholder; requests never leave the process).
const SystemFrom = "noreply@sphericon.test"
SystemFrom is the From address of the test Instance's System sender.
const TrackingCNAMETarget = "edge.sphericon.test"
TrackingCNAMETarget is the edge host the test instance names for Tracking domain CNAMEs (SPHERICON_TRACKING_CNAME_TARGET); WithConfig clears it to test the feature off.
Variables ¶
This section is empty.
Functions ¶
func AutomationWithSteps ¶
func AutomationWithSteps(ctx context.Context, db *ent.Client, create *ent.AutomationCreate, steps string) (*ent.Automation, error)
AutomationWithSteps saves the Automation that create describes together with its version 1, which holds steps (the executor's JSON step list), and returns the Automation. The version is the Automation's steps (ADR 0049): an Automation made with create alone has none and enrolls nobody.
func ColumnIsNullable ¶
ColumnIsNullable reports whether the table's column allows NULL.
func Elapse ¶
Elapse lets d of the fake clock pass inside a testing/synctest bubble: the bubble advances its clock as soon as every goroutine in it is blocked, so this returns at once in real time. It is the one way a test moves time forward. `time.Sleep` is banned (forbidigo): outside a bubble a sleep waits on the wall clock and makes the test slow and flaky, so wait on a condition instead.
func EmptyDBURL ¶
EmptyDBURL is the URL of a test's own database with no schema at all, for code that migrates a fresh instance (RealDB starts at the fixture state).
func ErrorContainsOrNone ¶
ErrorContainsOrNone is the assertion of a table row whose expected error is a text: a row with none expects no error, any other expects an error that contains it.
func ExternalRuleGroup ¶
func ExternalRuleGroup(tb testing.TB, def string) externalapi.ConditionGroup
ExternalRuleGroup is SiteRuleGroup for the external API.
func InstallOtel ¶
InstallOtel isolates the OTel globals (IsolateOtel), runs setup (telemetry.Setup bound to a config; passed in so telemetry's own tests can use it without an import cycle) and shuts it down when the test ends.
func IsolateOtel ¶
IsolateOtel clears the OTel config file variable and restores the process-wide OTel globals when the test ends, so a test may call telemetry.Setup without leaking providers.
func LatestSteps ¶
LatestSteps is the stored JSON step list of the Automation's newest version.
func LatestVersionID ¶
LatestVersionID is the id of the Automation's newest version.
func OutboxEnvelopesOn ¶
func OutboxEnvelopesOn(ctx context.Context, client *ent.Client, names ...string) ([]events.Envelope, error)
OutboxEnvelopesOn is OutboxEnvelopes for a database a test wrote to for real, read through the ent client the test holds on it.
func PrivateOutbox ¶
func PrivateOutbox() events.SubscribeOption
PrivateOutbox makes a subscriber read the outbox of a database of the test's own (RealDB) without waiting for transactions it cannot see.
watermill's default adapter delivers a row only when its transaction id is below pg_snapshot_xmin, and that horizon is cluster-wide: any open transaction in any database of the shared test server (another package's rolled-back test, another checkout's dev backend) holds every subscriber back until it ends, so delivery takes as long as the longest unrelated transaction. The horizon exists so a row that commits late is not overtaken by a later one; in a database no one else writes to, the only writer is the test, which commits before the subscriber can read, so nothing can be overtaken. Never use it on a database other writers share.
func RealDB ¶
RealDB is a database of the test's own on the test server, at the fixture state and NOT inside a transaction: whatever the test commits is committed, and a second connection sees it. For code that needs a real commit (the outbox router, concurrent workers, a whole app). pgtestdb clones it from a template and drops it when the test ends, so nothing is cleaned up by hand. The ordinary tests ride go-txdb (Setup).
func RealDBURL ¶
RealDBURL is RealDB for code that opens its own connection (an app, a pool under test): the URL of the test's own database at the fixture state, dropped with the test.
func Receive ¶
Receive waits for a value on ch and returns it; the test fails with msg when none arrives within receiveTimeout. The wait is the condition, not a guess: it returns as soon as the value is there.
func RequestCookie ¶
RequestCookie is the cookie a test sends with a request: a browser returns only the name and the value, so the attributes are the ones the server sets (Secure, HttpOnly, SameSite) and matter to nothing but the one place that builds the struct.
func RequireClosed ¶
RequireClosed fails the test with msg unless ch is closed (or holds a value) right now.
func RewriteURL ¶
RewriteURL wraps a transport so every occurrence of from in a request's URL (path and query) becomes to. A typed client cannot spell a malformed id, so a test sends a valid sentinel id and swaps it on the wire.
func ServiceCredentialValue ¶
ServiceCredentialValue is the value a service presents for a fixture credential, from the fixture catalog's prefix and secret (fixtures.ServiceCredentialPrimaryPrefix and fixtures.ServiceCredentialPrimarySecret, say).
func SiteRuleGroup ¶
func SiteRuleGroup(tb testing.TB, def string) siteapi.SiteConditionGroup
SiteRuleGroup builds a site API rule group from its JSON, so a test reads as the rule it sends instead of the nested generated union.
func TryHTTPGet ¶
TryHTTPGet is HTTPGet without test assertions, safe to call from a polling goroutine such as require.Eventually.
Types ¶
type Authenticator ¶
type Authenticator struct {
// contains filtered or unexported fields
}
Authenticator is a virtual WebAuthn authenticator and the browser in front of it (ADR 0051): it answers the options the server hands out the way a platform authenticator would, on descope/virtualwebauthn's attestation and assertion builders, so no CBOR or COSE is built by hand. It holds the credentials it created, each with the user handle the server gave it.
A test drives a ceremony through the /site client: it posts `begin`, hands the options JSON from the response to Attest (registration) or Assert (login), and posts the returned JSON to `finish`. The same options and response bytes can be posted twice to test a replay.
func (*Authenticator) Assert ¶
func (a *Authenticator) Assert(optionsJSON []byte) []byte
Assert answers a login ceremony's request options: it picks a held credential (one of the options' allowed credentials, or the first it holds for a usernameless login, where the list is empty), counts the use, and returns the response a browser posts to `finish` (the W3C AuthenticationResponseJSON), carrying the credential's user handle.
func (*Authenticator) Attest ¶
func (a *Authenticator) Attest(optionsJSON []byte) []byte
Attest answers a registration ceremony's creation options (the JSON `begin` returned): it creates a credential and returns the response a browser posts to `finish` (the W3C RegistrationResponseJSON). The authenticator keeps the credential from now on, as a real one does whether or not the server accepts it. It fails the test when the options exclude a credential this authenticator already holds (a browser refuses to register it twice).
func (*Authenticator) CredentialID ¶
func (a *Authenticator) CredentialID(i int) string
CredentialID is the base64url id of the i-th credential this authenticator holds, the form the server's responses and the fixture catalog use.
type AuthenticatorOption ¶
type AuthenticatorOption func(*virtualwebauthn.AuthenticatorOptions)
AuthenticatorOption tunes a virtual authenticator.
func WithoutUserVerification ¶
func WithoutUserVerification() AuthenticatorOption
WithoutUserVerification makes the authenticator skip the biometric or PIN check, so the responses it builds carry no user-verified flag (a security key without a PIN).
type CapturingSender ¶
type CapturingSender struct {
Err error
// contains filtered or unexported fields
}
CapturingSender is a messaging.EmailSender that records sends for assertions. Set Err to make Send fail with it — used to drive the send-path error branches (e.g. the verified-domain gate) that the real providers are stubbed out of.
func (*CapturingSender) DefaultFrom ¶
func (s *CapturingSender) DefaultFrom() (address, name string)
DefaultFrom is the integration-configured sender the fixtures' default integration uses; its domain (codebasics.dev) is a verified Sending domain, so sends without an explicit From pass Outbound send's domain gate (ADR 0010).
func (*CapturingSender) Messages ¶
func (s *CapturingSender) Messages() []messaging.EmailMessage
Messages returns a copy of the captured sends.
func (*CapturingSender) Send ¶
func (s *CapturingSender) Send(_ context.Context, msg messaging.EmailMessage) (messaging.Receipt, error)
func (*CapturingSender) SetErr ¶
func (s *CapturingSender) SetErr(err error)
SetErr makes subsequent Send calls fail with err (nil clears it).
type Confirmations ¶
type Confirmations struct {
// contains filtered or unexported fields
}
Confirmations stands in for the network behind a Preset's confirm action (an SNS SubscribeURL), so no test fetches a URL. It records what the hook asked to confirm.
func (*Confirmations) Fail ¶
func (c *Confirmations) Fail(err error)
Fail makes the next confirmations fail with err (nil clears it).
func (*Confirmations) URLs ¶
func (c *Confirmations) URLs() []string
URLs are the URLs confirmed so far, in order.
type FakeRelayRanges ¶
type FakeRelayRanges struct {
// contains filtered or unexported fields
}
FakeRelayRanges is the source of the iCloud Private Relay list a test scripts, so no test reaches Apple (machine.Source). It publishes an empty list until a test says otherwise.
func (*FakeRelayRanges) Fail ¶
func (f *FakeRelayRanges) Fail(err error)
Fail makes the next fetches fail with err.
func (*FakeRelayRanges) Fetch ¶
func (f *FakeRelayRanges) Fetch(context.Context) (io.ReadCloser, error)
Fetch implements machine.Source.
func (*FakeRelayRanges) Publish ¶
func (f *FakeRelayRanges) Publish(csv string)
Publish makes the next fetches return csv, one range per row, and succeed.
type FakeSES ¶
type FakeSES struct {
// contains filtered or unexported fields
}
FakeSES stands in for the SES account behind every "ses" Integration the server builds in a test: its send quota is whatever the test scripts (by default none is reported and the lookup succeeds), so no test ever reaches the real SES API.
func (*FakeSES) Catalog ¶
Catalog is a catalog whose "ses" provider builds the fake itself, so discovery reaches it through the stored, encrypted Integration config exactly as it reaches the real sender; "smtp" builds a sender that cannot report a quota.
func (*FakeSES) SetQuotaErr ¶
SetQuotaErr makes the next GetSendQuota calls fail with err (nil clears it): a missing ses:GetSendQuota permission, or an SES-compatible service without the call.
type FakeSignin ¶
type FakeSignin struct {
Server *httptest.Server
// ClientID and ClientSecret are what the Instance is configured with.
ClientID, ClientSecret string
// contains filtered or unexported fields
}
FakeSignin is an httptest provider the Sign-in registry is pointed at: it serves the token and key endpoints of an OIDC provider, answers an authorization request with a code for the chosen identity, and checks what a real provider checks (client credentials, the redirect URI, PKCE S256). The routes live on one mux so a provider with more endpoints (GitHub's account and emails) is more handlers on it.
func NewFakeSignin ¶
func NewFakeSignin(t *testing.T) *FakeSignin
NewFakeSignin starts the fake and stops it when the test ends.
func (*FakeSignin) Authorize ¶
func (f *FakeSignin) Authorize(t *testing.T, authURL string, who SigninIdentity) string
Authorize is the person consenting at the provider: it takes the authorization URL `start` redirected to and returns the callback URL (path and query) the provider sends the browser back to, carrying a code for who and the request's own state.
func (*FakeSignin) Credentials ¶
func (f *FakeSignin) Credentials() config.SigninCredentials
Credentials is what the Instance is configured with for a provider.
func (*FakeSignin) Deny ¶
func (f *FakeSignin) Deny(t *testing.T, authURL string) string
Deny is the person refusing consent: the callback URL carries the provider's error.
func (*FakeSignin) Endpoints ¶
func (f *FakeSignin) Endpoints() signin.Endpoints
Endpoints points the registry's Google entry at the fake.
func (*FakeSignin) GitHubEndpoints ¶
func (f *FakeSignin) GitHubEndpoints() signin.Endpoints
GitHubEndpoints points the registry's GitHub entry at the fake: plain OAuth2, with the account and its emails read from the API.
type Option ¶
type Option func(*setup)
Option tunes the server a test builds with Setup.
func WithClock ¶
WithClock replaces the clock of the account attempt module (the login delay), so a test freezes or advances time instead of sleeping.
func WithConfig ¶
WithConfig edits a private copy of the test config before the server is built.
func WithLicenseKey ¶
WithLicenseKey builds the instance as the composition root does for SPHERICON_LICENSE_KEY: the key is loaded through licensekey.Load against pub, so a lapsed key boots as the core and a forged one fails the test's setup (ADR 0035).
func WithOAuthFetcher ¶
WithOAuthFetcher replaces the client that downloads OAuth Client ID Metadata Documents, so a test serves a document from an httptest TLS server (the production client refuses loopback).
func WithRateLimits ¶
func WithRateLimits(limits config.RateLimits) Option
WithRateLimits turns the rate limits on with the given (small) budgets. Without it every limit is 0 (disabled), so tests never throttle each other; limiters are per Setup, so budgets never leak between tests either.
func WithRunningVersion ¶
WithRunningVersion sets the version the Instance's Release check compares against, so a test runs as a release build ("0.1.0") instead of the "dev" test build.
func WithSNSCertificates ¶
func WithSNSCertificates(f preset.CertFetcher) Option
WithSNSCertificates replaces where an `sns` Preset gets its signing certificate (the test certificate by default), so a test makes the fetch fail.
func WithSignin ¶
func WithSignin(f *FakeSignin) Option
WithSignin enables the provider "google" on the test Instance, pointed at the fake.
func WithSigninGitHub ¶
func WithSigninGitHub(f *FakeSignin) Option
WithSigninGitHub enables the provider "github" on the test Instance, pointed at the fake.
func WithStaffVolumeFloor ¶
WithStaffVolumeFloor sets the fewest sends in the Staff console's window for a rate to be defined, so a test crosses the floor with a handful of fixture Events.
func WithSystemSenderWithoutFrom ¶
func WithSystemSenderWithoutFrom() Option
WithSystemSenderWithoutFrom gives the Instance a System sender that names no From of its own, which a Test send must refuse rather than send with an empty From.
func WithTXTLookup ¶
WithTXTLookup replaces the TXT resolver of Sending domain and Join domain verification, so a test publishes and withdraws records in a zone of its own (dnstest.NewZone). The default answers NXDOMAIN to everything.
func WithoutLicense ¶
func WithoutLicense() Option
WithoutLicense builds the instance with no EE license key, like a plain core self-host. Setup's default is an instance licensed for every EE feature.
func WithoutSystemSender ¶
func WithoutSystemSender() Option
WithoutSystemSender runs the Instance with no outbound mail, so it has no System sender for a Test send to fall back to (ADR 0041).
type OutboxCursor ¶
OutboxCursor is one consumer group's stored position. Acked is nil for a group that has never acknowledged a message.
type OutboxMessage ¶
OutboxMessage is one outbox envelope with its payload decoded generically (numbers as json.Number, so ids compare exactly).
type OutboxRow ¶
OutboxRow is one raw outbox row: its position in the (transaction_id, offset) order the subscribers read in, and when it was written.
type RedirectBrowser ¶
type RedirectBrowser struct {
// contains filtered or unexported fields
}
RedirectBrowser is one browser talking to the server by plain requests without a body: it keeps cookies like a browser does and never follows a redirect on its own, so a test reads each Location and carries it to the next hop (the provider, then back), as the person's browser does.
type Reply ¶
type Reply struct {
StatusCode int
Header http.Header
Body string
// contains filtered or unexported fields
}
Reply is what the server answered one GET, with its body already read.
type SigninEmail ¶
SigninEmail is one more address of a GitHub account.
type SigninIdentity ¶
type SigninIdentity struct {
Subject string
Email string
EmailVerified bool
HostedDomain string
Name string
// Login is a GitHub account's handle, the name it falls back to.
Login string
// OtherEmails are the further addresses of a GitHub account, beside the primary one
// (Email, EmailVerified).
OtherEmails []SigninEmail
}
SigninIdentity is who the fake provider says the person is: the subject, the email and whether it is verified, Google's `hd` claim, the name. Every flow of a test runs with one chosen here.
type TestEnv ¶
type TestEnv struct {
// Instance is the module the server shares: run its Release check with CheckRelease.
Instance *instance.Module
DB *ent.Client // transaction-bound; rolled back when the test finishes
SQLDB *sql.DB // the same txdb connection the ent client and bus ride
Bus *events.Bus // domain-event bus over SQLDB (nested savepoint per WithinTx)
Server http.Handler
// Internal is the handler of the internal listener (ADR 0026), built like the
// composition root builds it: the service endpoints and nothing else. Nil on an
// unlicensed instance, where no listener would be bound.
Internal http.Handler
// Tracker is the instance the server and the sender share: mint tracking,
// unsubscribe and confirmation tokens with it, never with a second one.
Tracker *tracking.Tracker
// Cipher is the instance the server seals with, for modules a test builds directly.
Cipher *secrets.Cipher
// Integrations is the module the server serves Integrations and their hooks with.
Integrations *integrations.Module
// AppURL is SPHERICON_APP_URL of the env: the origin and relying party id of a Passkey
// ceremony (ADR 0051).
AppURL string
// Holds is the module the sender's freeze check reads, for a test that builds its own
// Outbound module.
Holds *holds.Holds
// Captured sends from the inline jobs adapter, for assertions.
SystemMail *CapturingSender // platform mail (welcome, …)
CustomerMail *CapturingSender // workspace/campaign mail (broadcasts)
// SES scripts the send quota every "ses" Integration reports.
SES *FakeSES
// Machine is the detector the tracking endpoints judge hits by, fed by PrivateRelay, the
// scripted source of the published Private Relay list: Refresh replaces the stored ranges.
Machine *machine.Detector
PrivateRelay *FakeRelayRanges
// Confirmations records the subscription URLs a Preset's confirm action fetched.
Confirmations *Confirmations
// SecondFactor is the module the server verifies Second factors with, on the
// env's clock (ADR 0020).
SecondFactor *secondfactor.Module
// Staff members is the Staff member module the server logs staff in with (ADR 0026); it
// refuses every call on an unlicensed env.
StaffMembers *staff.Module
// contains filtered or unexported fields
}
func (*TestEnv) Abuse ¶
Abuse is the abuse detector as the composition root builds it (ADR 0026), over the env's bus and platform sender; a pass is Run(ctx, now).
func (*TestEnv) AgeOutbox ¶
AgeOutbox backdates the outbox rows with the given offsets by age (all rows when no offsets are given), so a test can place rows on either side of a retention floor; the producer always stamps rows with the current time.
func (*TestEnv) CancelPendingFor ¶
func (env *TestEnv) CancelPendingFor(t *testing.T, contactID int64, cancel func(context.Context, *ent.Scoped, int64, events.QueuePurger) error) error
CancelPendingFor runs an owner's CancelPending for a Contact of the Initech Workspace the way Erasure does, inside a purging transaction.
func (*TestEnv) ClaimOutbound ¶
ClaimOutbound moves the claim of a fixture Outbound message to `at`: a pending fixture message holds a claim long past, so a test that needs a live claim (a send still in flight) moves it instead of creating a message.
func (*TestEnv) ClaimRecipient ¶
ClaimRecipient moves the claim of a placed recipient's message (only Bob's has one) to `age` ago: another attempt's claim, live while younger than the send lease.
func (*TestEnv) CollectAcme ¶
func (env *TestEnv) CollectAcme(t *testing.T) *collectapi.Client
CollectAcme returns a /collect client carrying the Acme collect key.
func (*TestEnv) CollectAnonymous ¶
func (env *TestEnv) CollectAnonymous(t *testing.T) *collectapi.Client
CollectAnonymous returns a /collect client carrying no key.
func (*TestEnv) CollectWithKey ¶
CollectWithKey returns a /collect client carrying the given raw key (for wrong-credential tests).
func (*TestEnv) CoreHolds ¶
CoreHolds is the holds module of an instance that ignores Staff holds (no `staff` license), for a test under testing/synctest: fake time starts in 2000, before the real-clock expiry of the fixture holds, which would read active there.
func (*TestEnv) DeliverQueuedBroadcasts ¶
DeliverQueuedBroadcasts runs the send of every Broadcast that has a send job waiting in the queue, the way a worker would (synchronously, ignoring the schedule), and returns once each has been planned and its recipients sent. Nothing works the queue under txdb, so a test that sends a Broadcast and then needs it delivered calls this.
func (*TestEnv) DeliverToEE ¶
DeliverToEE hands every envelope on this test's outbox to the Enterprise subscribers, as the router would (no router runs under txdb). Each call redelivers the whole outbox, so calling it twice exercises at-least-once redelivery.
func (*TestEnv) EnqueueJob ¶
EnqueueJob puts one available job of args into the queue.
func (*TestEnv) EnqueueRunningJob ¶
EnqueueRunningJob puts one job of args into the queue already in the running state, as a worker holds it. river's insert API only creates waiting jobs, so this goes through the driver's full insert, which takes a state.
func (*TestEnv) ExpiredConfirmToken ¶
ExpiredConfirmToken is a confirmation token for target, signed like the Tracker's but already past its exp: the state a link reaches after its TTL. Mint live tokens with env.Tracker; this exists only for the expiry path.
func (*TestEnv) ExtendHold ¶
ExtendHold moves the expiry of a fixture Staff hold of a Workspace to `until`: the fixture holds are lapsed, so a test that wants a freeze lifts one of them instead of creating a hold.
func (*TestEnv) ExternalAnchor ¶
func (env *TestEnv) ExternalAnchor(t *testing.T) *externalapi.Client
ExternalAnchor returns an /api client bearing the fixture anchor token (scopes contacts, tokens and events, read and write).
func (*TestEnv) ExternalAnonymous ¶
func (env *TestEnv) ExternalAnonymous(t *testing.T) *externalapi.Client
ExternalAnonymous returns an /api client carrying no credential.
func (*TestEnv) ExternalScoped ¶
ExternalScoped returns an /api client bearing a fresh Acme token that has exactly the given scopes, created through the production token code.
func (*TestEnv) ExternalVia ¶
func (env *TestEnv) ExternalVia(t *testing.T, bearer string, wrap func(inner ht.Client) ht.Client) *externalapi.Client
ExternalVia is ExternalWithToken with the in-memory transport wrapped by wrap, for tests that change the request on the wire (e.g. RewriteURL).
func (*TestEnv) ExternalWithToken ¶
ExternalWithToken returns an /api client bearing the given raw token value (for wrong-credential tests).
func (*TestEnv) FixturePasskey ¶
func (env *TestEnv) FixturePasskey(t *testing.T, opts ...AuthenticatorOption) *Authenticator
FixturePasskey is a virtual authenticator that already holds the committed fixture Passkey (fixtures.PasskeyPatLaptop: Pat's laptop), signing with the private key the fixture states.
func (*TestEnv) FixturePegPasskey ¶
func (env *TestEnv) FixturePegPasskey(t *testing.T, opts ...AuthenticatorOption) *Authenticator
FixturePegPasskey is a virtual authenticator that already holds Peg's fixture Passkey (fixtures.PasskeyPegKey), the only way the password-less Peg signs in.
func (*TestEnv) FixtureUnverifiedPasskey ¶
func (env *TestEnv) FixtureUnverifiedPasskey(t *testing.T, opts ...AuthenticatorOption) *Authenticator
FixtureUnverifiedPasskey is a virtual authenticator that already holds Una's fixture Passkey (fixtures.PasskeyUnverifiedUnaKey): her email was never verified, so the gate stops her login.
func (*TestEnv) IssueServiceCredential ¶
func (env *TestEnv) IssueServiceCredential(t *testing.T, name string, scopes ...serviceapi.ServiceScope) string
IssueServiceCredential issues a Service credential through the same module the command line uses and returns the value to present: the issuing helper of the tests. The credential belongs to the service called name and carries exactly scopes.
func (*TestEnv) JobRowsOf ¶
JobRowsOf returns the queued jobs of kind as river holds them, oldest first.
func (*TestEnv) JobSchedules ¶
JobSchedules returns when the queued jobs of kind are due, oldest first.
func (*TestEnv) MCPClient ¶
MCPClient connects the official go-sdk MCP client to /mcp over the in-memory app (no socket) and returns the live session. An empty token connects without an Authorization header. The session closes with the test.
func (*TestEnv) NewAuthenticator ¶
func (env *TestEnv) NewAuthenticator(t *testing.T, opts ...AuthenticatorOption) *Authenticator
NewAuthenticator is a virtual authenticator for the env's Instance: its relying party id and origin come from the env's SPHERICON_APP_URL, never a literal, so it fits every checkout.
func (*TestEnv) NewRedirectBrowser ¶
func (env *TestEnv) NewRedirectBrowser(t *testing.T) *RedirectBrowser
NewRedirectBrowser is a browser with no cookies.
func (*TestEnv) OutboundModule ¶
OutboundModule is the Outbound module the harness's own sends run through, for a test that sends from a surface the API does not expose (an Automation step).
func (*TestEnv) Outbox ¶
func (env *TestEnv) Outbox(t *testing.T, names ...string) []OutboxMessage
Outbox returns the outbox messages of this test's transaction, oldest first, optionally only those of the given event names.
func (*TestEnv) OutboxCount ¶
OutboxCount counts the outbox messages named name whose payload has every key/value of match (values compare by their printed form: 42 matches "42").
func (*TestEnv) OutboxCursors ¶
func (env *TestEnv) OutboxCursors(t *testing.T) map[string]OutboxCursor
OutboxCursors returns every consumer group's offsets row, keyed by group.
func (*TestEnv) OutboxEnvelopes ¶
OutboxEnvelopes returns the envelopes published on the outbox in this test's transaction, oldest first. With names, only envelopes of those event names.
func (*TestEnv) OutboxEvents ¶
OutboxEvents is OutboxEnvelopes decoded into their typed events.
func (*TestEnv) OutboxRows ¶
OutboxRows returns every outbox row of this test's transaction in (transaction_id, offset) order.
func (*TestEnv) PlaceRecipient ¶
PlaceRecipient moves the parked recipient of a Contact (Alice, Bob or Carol, parked on the archived Broadcast in the fixtures) onto the Broadcast, with its message if it has one, and returns the recipient's id. A test that needs a Broadcast with exactly the recipients it names places them.
func (*TestEnv) RefreshUsage ¶
RefreshUsage runs the usage job once as of now under the harness license, which includes the `staff` license feature: it closes the elapsed Usage periods and refreshes the Live usage of the open one, as the periodic job does (the river schedule does not run in tests).
func (*TestEnv) RunNextStep ¶
RunNextStep takes the oldest waiting step job of an Enrollment from the queue, executes its step through mod as the worker would and deletes the job, the way a finished job leaves the queue. It reports whether there was a job. The job is run whatever its schedule says: a step that is early for its Enrollment's resume time queues itself again, so a test that lets waits pass gives the module a clock past them.
func (*TestEnv) RunQueuedSteps ¶
RunQueuedSteps runs the waiting step jobs through mod, oldest first, until none is left: the steps an Enrollment's own jobs queue are run too, so an Automation is driven to its end (or to the HTTP step job, which this does not run).
func (*TestEnv) ScopedBearer ¶
ScopedBearer returns the raw bearer value of a fresh Acme token that has exactly the given scopes, for tests that must speak raw HTTP or MCP.
func (*TestEnv) ScopedBearerFor ¶
ScopedBearerFor is ScopedBearer for another fixture Workspace (tenant-isolation tests, e.g. fixtures.GlobexID).
func (*TestEnv) ServiceClient ¶
ServiceClient returns a service-endpoints client presenting value as its bearer credential, served by the internal listener's handler (env.Internal), the only place the service endpoints exist. Build the value of a fixture credential with ServiceCredentialValue, or issue one with IssueServiceCredential.
func (*TestEnv) ServiceClientOnPublicPort ¶
ServiceClientOnPublicPort is ServiceClient aimed at the public server instead, where the service endpoints must not exist.
func (*TestEnv) SetOutboxCursor ¶
SetOutboxCursor upserts a consumer group's offsets row, as if that group had acknowledged the message at offset acked of transaction txID (nil acked leaves the ack NULL).
func (*TestEnv) SiteActor ¶
SiteActor returns a /site client authenticated as the fixture user with the given login email (use the fixtures.*Email constants). Each request carries a session token minted for it (see SiteToken); hold a SiteToken for a session that must outlive an epoch bump.
func (*TestEnv) SiteActorVia ¶
func (env *TestEnv) SiteActorVia(t *testing.T, email string, wrap func(inner ht.Client) ht.Client) *siteapi.Client
SiteActorVia is SiteActor with the in-memory transport wrapped by wrap, for tests that observe the wire (e.g. raw response bodies).
func (*TestEnv) SiteAnonymous ¶
SiteAnonymous returns a /site client carrying no credential.
func (*TestEnv) SiteBrowser ¶
SiteBrowser returns an anonymous /site client that keeps cookies between its requests the way one browser does: a cookie a response sets goes back on the next request whose URL its path and attributes match. Two SiteBrowser clients are two browsers, which is what the Registration browser tests need (ADR 0030).
func (*TestEnv) SiteToken ¶
SiteToken mints the session token a login issues for the fixture user with the given email: the go-pkgz claims, stamped by the production apiauth.StampUser (User id and current session epoch), signed with the test config's secret and valid for SPHERICON_SESSION_TTL from the env's clock. edit, when not nil, changes the claims before signing, for tests of tokens a login never issues (expired, without an epoch). The token is fixed at minting: a later epoch bump ends it.
func (*TestEnv) SiteWithToken ¶
SiteWithToken returns a /site client carrying the given raw session token (for tests of tokens in states a login never issues, minted with SiteToken).
func (*TestEnv) StaffAnonymous ¶
StaffAnonymous returns an /staff client carrying no session.
func (*TestEnv) StaffWithToken ¶
StaffWithToken returns an /staff client carrying the given raw session token in the Staff member cookie (obtained from a real two-step login, or minted for a test of a token in a state a login never issues).
func (*TestEnv) SuppressDestination ¶
SuppressDestination puts a destination of Acme on the Suppression list by re-opening the fixture's lifted Suppression for it: a test that needs a Suppression landing at a chosen moment reopens that row instead of creating one.
func (*TestEnv) SuspendWorkspace ¶
SuspendWorkspace leaves a Workspace suspended at `at` the way internal/suspension does: the actor and the reason are written with suspended_at, as the table's check requires.
func (*TestEnv) Transport ¶
Transport returns an ogen http.Client that dispatches in-memory to the server (no socket). Pass it via the generated client's WithClient option so the typed client builds URLs and encodes/decodes DTOs for you. extraHeaders are applied to every request (e.g. x-collect-key).
func (*TestEnv) TryDeliverQueuedBroadcasts ¶
TryDeliverQueuedBroadcasts is DeliverQueuedBroadcasts for a test that expects the send to be refused (a Hold): it returns the first error a send returns instead of failing the test.
func (*TestEnv) UnsubscribeFromBroadcasts ¶
UnsubscribeFromBroadcasts opts a destination of Acme out of Broadcasts by moving the fixture's per-Automation opt-out onto it: a test that needs an opt-out landing at a chosen moment moves that row instead of creating one.
Source Files
¶
- actor.go
- authenticator.go
- automations.go
- broadcasts.go
- browser.go
- confirmations.go
- cookie.go
- elapse.go
- errors.go
- fakerelay.go
- fakeses.go
- holds.go
- jobs.go
- mcp.go
- outbound.go
- outbox.go
- private_outbox.go
- realdb.go
- receive.go
- schemainfo.go
- segments.go
- service.go
- signin_browser.go
- signin_fake.go
- staff.go
- suppressions.go
- suspension.go
- telemetry.go
- testhelper.go
- tokens.go
- usage.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package metricstest scrapes the real /metrics handler for tests and reads its Prometheus exposition.
|
Package metricstest scrapes the real /metrics handler for tests and reads its Prometheus exposition. |