stripe = new FakeStripeClient; app()->instance(StripeClient::class, $this->stripe); app(Kernel::class)->call('stripe:sync-catalogue'); $this->product = (string) StripeAddonPrice::query() ->where('addon_key', 'priority_support') ->value('stripe_product_id'); $this->known = (string) StripeAddonPrice::query() ->where('addon_key', 'priority_support') ->where('interval', 'month') ->where('reverse_charge', false) ->value('stripe_price_id'); $this->stripe->plantPrice('price_orphan', $this->product, 9900, 'EUR', 'month', []); }); it('reports the orphan and leaves it alone', function () { $this->artisan('stripe:sweep-orphan-prices') ->expectsOutputToContain('price_orphan') ->assertSuccessful(); expect($this->stripe->archived)->toBe([]); }); it('never reports a price a row knows', function () { $this->artisan('stripe:sweep-orphan-prices') ->doesntExpectOutputToContain($this->known) ->assertSuccessful(); }); it('stops selling the orphan when asked to', function () { $this->artisan('stripe:sweep-orphan-prices', ['--archive' => true]) ->assertSuccessful(); // Archiving is harmless for the same reason it always is here: Stripe goes // on billing every subscription already on an archived Price, it merely // stops being sold. expect($this->stripe->archived)->toBe(['price_orphan']); }); it('touches nothing on a dry run, even when asked to archive', function () { $this->artisan('stripe:sweep-orphan-prices', ['--archive' => true, '--dry-run' => true]) ->expectsOutputToContain('price_orphan') ->assertSuccessful(); expect($this->stripe->archived)->toBe([]); }); it('fails cleanly on a dry run when Stripe is not configured, rather than throwing', function () { // Unlike stripe:sync-catalogue, this command has no local-only path: the // report itself is a live activePricesFor() call, dry-run or not. A guard // that only fired outside --dry-run would let this fall straight into // HttpStripeClient's own "not configured" exception instead of the clean // error below. $this->stripe->configured = false; $this->artisan('stripe:sweep-orphan-prices', ['--dry-run' => true]) ->expectsOutputToContain('Stripe is not configured (STRIPE_SECRET is empty). Nothing was read.') ->assertFailed(); });