test: add coupon service tests
This commit is contained in:
1 parent
8da8322ede
commit
61fea613bf
1 file changed
+93
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Bazaar\Tests;
|
||||
|
||||
use Bazaar\Repositories\CouponRepository;
|
||||
use Bazaar\Services\CouponResult;
|
||||
use Bazaar\Services\CouponService;
|
||||
|
||||
final class CouponServiceTest extends DatabaseTestCase
|
||||
{
|
||||
private CouponRepository $coupons;
|
||||
private CouponService $service;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->coupons = new CouponRepository($this->db);
|
||||
$this->service = new CouponService($this->coupons);
|
||||
}
|
||||
|
||||
private function coupon(array $overrides = []): int
|
||||
{
|
||||
return $this->coupons->create(array_merge([
|
||||
'code' => 'SAVE10',
|
||||
'type' => 'percent',
|
||||
'value' => 10,
|
||||
'minSubtotalCents' => 0,
|
||||
'maxRedemptions' => null,
|
||||
'startsAt' => null,
|
||||
'expiresAt' => null,
|
||||
'isActive' => true,
|
||||
], $overrides));
|
||||
}
|
||||
|
||||
public function testPercentDiscountIsFloored(): void
|
||||
{
|
||||
$this->coupon(['code' => 'SAVE15', 'value' => 15]);
|
||||
$result = $this->service->evaluate('SAVE15', 999);
|
||||
|
||||
$this->assertTrue($result->isValid());
|
||||
$this->assertSame((int) floor(999 * 0.15), $result->discountCents);
|
||||
}
|
||||
|
||||
public function testFixedDiscountNeverExceedsSubtotal(): void
|
||||
{
|
||||
$this->coupon(['code' => 'FLAT50', 'type' => 'fixed', 'value' => 5000]);
|
||||
$result = $this->service->evaluate('FLAT50', 3000);
|
||||
|
||||
$this->assertTrue($result->isValid());
|
||||
$this->assertSame(3000, $result->discountCents);
|
||||
}
|
||||
|
||||
public function testCodeLookupIsCaseInsensitive(): void
|
||||
{
|
||||
$this->coupon();
|
||||
$this->assertTrue($this->service->evaluate('save10', 5000)->isValid());
|
||||
}
|
||||
|
||||
public function testUnknownCodeIsRejected(): void
|
||||
{
|
||||
$this->assertSame(CouponResult::notFound, $this->service->evaluate('NOPE', 5000)->status);
|
||||
}
|
||||
|
||||
public function testInactiveCouponIsRejected(): void
|
||||
{
|
||||
$this->coupon(['code' => 'OFF', 'isActive' => false]);
|
||||
$this->assertSame(CouponResult::inactive, $this->service->evaluate('OFF', 5000)->status);
|
||||
}
|
||||
|
||||
public function testBelowMinimumIsRejected(): void
|
||||
{
|
||||
$this->coupon(['code' => 'BIG', 'minSubtotalCents' => 10000]);
|
||||
$this->assertSame(CouponResult::belowMinimum, $this->service->evaluate('BIG', 5000)->status);
|
||||
}
|
||||
|
||||
public function testExpiredAndNotStartedWindows(): void
|
||||
{
|
||||
$this->coupon(['code' => 'PAST', 'expiresAt' => '2020-01-01T00:00:00+00:00']);
|
||||
$this->coupon(['code' => 'FUTURE', 'startsAt' => '2999-01-01T00:00:00+00:00']);
|
||||
|
||||
$this->assertSame(CouponResult::expired, $this->service->evaluate('PAST', 5000)->status);
|
||||
$this->assertSame(CouponResult::notStarted, $this->service->evaluate('FUTURE', 5000)->status);
|
||||
}
|
||||
|
||||
public function testExhaustedWhenRedemptionLimitReached(): void
|
||||
{
|
||||
$id = $this->coupon(['code' => 'ONCE', 'maxRedemptions' => 1]);
|
||||
$this->assertTrue($this->service->evaluate('ONCE', 5000)->isValid());
|
||||
|
||||
$this->service->redeem($id);
|
||||
$this->assertSame(CouponResult::exhausted, $this->service->evaluate('ONCE', 5000)->status);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user