createStub(ClinicSubscriptionRepository::class); $subscriptionRepo->method('findByUuid')->willReturn($found); $subscriptionRepo->method('remove')->willReturnCallback(function (ClinicSubscription $s): void { $this->removed = $s; }); return new SubscriptionService( $subscriptionRepo, $this->createStub(SubscriptionPlanRepository::class), $this->createStub(SubscriptionPeriodRepository::class), $this->createStub(SiteConfigRepository::class), ); } public function testGrantedSubscriptionIsRemoved(): void { $subscription = $this->createStub(ClinicSubscription::class); $subscription->method('getPayment')->willReturn(null); $this->service($subscription)->revoke('sub-uuid'); $this->assertSame($subscription, $this->removed); } public function testUnknownUuidIsRejected(): void { try { $this->service(null)->revoke('missing-uuid'); $this->fail('Expected AppException'); } catch (AppException $e) { $this->assertSame(ErrorCodes::ERR_SUBSCRIPTION_NOT_FOUND, $e->getErrorCode()); $this->assertSame(404, $e->getHttpStatus()); } $this->assertNull($this->removed); } public function testPaidSubscriptionIsNotRemoved(): void { $subscription = $this->createStub(ClinicSubscription::class); $subscription->method('getPayment')->willReturn($this->createStub(Payment::class)); try { $this->service($subscription)->revoke('sub-uuid'); $this->fail('Expected AppException'); } catch (AppException $e) { $this->assertSame(ErrorCodes::ERR_CONFLICT_001, $e->getErrorCode()); $this->assertSame(409, $e->getHttpStatus()); } $this->assertNull($this->removed); } }