Skip to content

Testing

Testing

Each module ships the same testing shape as the rest of the cbox ecosystem: an InteractsWith* trait that wires the in-memory bindings, plus Fake* doubles for the ports you would otherwise have to stand up. These are shipped in the package (under each module's Testing/ namespace), not test-only fixtures.

Traits and doubles by module

Module Trait Notable fakes
Metering InteractsWithMetering FakeAllowanceLeaseSource, FakeMeterPolicyResolver, OutageLocalStore, RecordingEnforcementSignals
Wallet InteractsWithWallet —
Ledger InteractsWithLedger —
Reconciliation InteractsWithReconciliation FakeCheckpointStore
Subscription InteractsWithSubscriptionLifecycle FakeForfeitureHandler
Entitlement (audit) InteractsWithEntitlementAudit FakeEntitlementAudit, RecordingEntitlementAuditSignals
Entitlement (rollout) InteractsWithEntitlementRollout FakeEntitlementRollout, FakeRolloutJournal, RecordingCacheInvalidator
Entitlement — FakeEntitlementWriter
Account InteractsWithAccountStanding, InteractsWithBillingCurrencyLock FakeAccountStanding, FakeBillingCurrencyLock
Payment (dunning) InteractsWithDunning FakeDunningStateStore, FakeDelinquentAllowList
Payment (webhooks) InteractsWithWebhooks FakePaymentGateway, FakeWebhookVerifier, FakeProcessedEventStore, FakeSettledPaymentStore, FakeInvoicePaymentApplier
Refund InteractsWithRefunds FakeRefunder, FakeChargebackHandler

Driving a failure path

The metering fakes are built to exercise the hard cases directly. makeEnforcement takes a custom $store and an $infraPolicy, the two knobs an ADR-0004 outcome test needs — pass an OutageLocalStore to make the store throw and assert the three-way outcome fails open (or closed) as configured:

use Cbox\Billing\Metering\Testing\{InteractsWithMetering, OutageLocalStore};
use Cbox\Billing\Metering\Enums\InfraFailurePolicy;

$enforcement = $this->makeEnforcement(
    store: new OutageLocalStore(),        // the store throws → infra-failure path
    infraPolicy: InfraFailurePolicy::Allow,
);

$outcome = $enforcement->reserveOutcome($org, 'api.calls', 1);

$this->assertTrue($outcome->failedOpen()); // admitted under the allow policy

Use the recording signal fakes (RecordingEnforcementSignals, RecordingEntitlementAuditSignals) to assert that operators would have been signalled when a fail-open or an outage fired.