test: add order mail and review service tests
This commit is contained in:
1 parent
d1e179bc85
commit
f07c2dbb29
2 files changed
+196
No files matched your search
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Bazaar\Tests;
|
||||
|
||||
use Bazaar\Core\Session;
|
||||
use Bazaar\Mail\LogMailer;
|
||||
use Bazaar\Repositories\OrderRepository;
|
||||
use Bazaar\Repositories\ProductRepository;
|
||||
use Bazaar\Repositories\UserRepository;
|
||||
use Bazaar\Repositories\VariantRepository;
|
||||
use Bazaar\Services\Cart;
|
||||
use Bazaar\Services\OrderService;
|
||||
|
||||
final class OrderMailTest extends DatabaseTestCase
|
||||
{
|
||||
private string $logPath;
|
||||
private LogMailer $mailer;
|
||||
private OrderService $service;
|
||||
private OrderRepository $orders;
|
||||
private ProductRepository $products;
|
||||
private int $userId;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->logPath = sys_get_temp_dir() . '/bazaar-mail-' . uniqid() . '.log';
|
||||
$this->mailer = new LogMailer($this->logPath);
|
||||
$this->orders = new OrderRepository($this->db);
|
||||
$this->products = new ProductRepository($this->db);
|
||||
$this->service = new OrderService(
|
||||
$this->db,
|
||||
$this->orders,
|
||||
$this->products,
|
||||
new VariantRepository($this->db),
|
||||
null,
|
||||
$this->mailer
|
||||
);
|
||||
$this->userId = (new UserRepository($this->db))->create('mailbuyer@bazaar.test', 'hash', 'Mail Buyer');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if (is_file($this->logPath)) {
|
||||
unlink($this->logPath);
|
||||
}
|
||||
}
|
||||
|
||||
private function order(): int
|
||||
{
|
||||
$productId = $this->seedProduct('Teapot', 4200, 10);
|
||||
$cart = new Cart(new Session(), $this->products);
|
||||
$cart->add($productId, 2);
|
||||
return $this->service->createFromCart($this->userId, $cart, 'usd');
|
||||
}
|
||||
|
||||
public function testNoMailBeforePayment(): void
|
||||
{
|
||||
$this->order();
|
||||
$this->assertCount(0, $this->mailer->sent());
|
||||
}
|
||||
|
||||
public function testConfirmationSentOnPaid(): void
|
||||
{
|
||||
$orderId = $this->order();
|
||||
$this->service->markPaid($orderId);
|
||||
|
||||
$sent = $this->mailer->sent();
|
||||
$this->assertCount(1, $sent);
|
||||
$this->assertSame('mailbuyer@bazaar.test', $sent[0]->to);
|
||||
$this->assertStringContainsString('order #' . $orderId, $sent[0]->subject);
|
||||
$this->assertStringContainsString('Teapot', $sent[0]->body);
|
||||
}
|
||||
|
||||
public function testStatusUpdateSentOnFulfilled(): void
|
||||
{
|
||||
$orderId = $this->order();
|
||||
$this->service->markPaid($orderId);
|
||||
$this->service->markFulfilled($orderId);
|
||||
|
||||
$sent = $this->mailer->sent();
|
||||
$this->assertCount(2, $sent);
|
||||
$this->assertStringContainsString('fulfilled', $sent[1]->subject);
|
||||
}
|
||||
|
||||
public function testLogMailerWritesToDisk(): void
|
||||
{
|
||||
$orderId = $this->order();
|
||||
$this->service->markPaid($orderId);
|
||||
|
||||
$this->assertFileExists($this->logPath);
|
||||
$this->assertStringContainsString('mailbuyer@bazaar.test', file_get_contents($this->logPath));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Bazaar\Tests;
|
||||
|
||||
use Bazaar\Repositories\OrderRepository;
|
||||
use Bazaar\Repositories\ReviewRepository;
|
||||
use Bazaar\Repositories\UserRepository;
|
||||
use Bazaar\Services\ReviewService;
|
||||
|
||||
final class ReviewServiceTest extends DatabaseTestCase
|
||||
{
|
||||
private ReviewRepository $reviews;
|
||||
private OrderRepository $orders;
|
||||
private ReviewService $service;
|
||||
private int $buyerId;
|
||||
private int $strangerId;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->reviews = new ReviewRepository($this->db);
|
||||
$this->orders = new OrderRepository($this->db);
|
||||
$this->service = new ReviewService($this->db, $this->reviews);
|
||||
$users = new UserRepository($this->db);
|
||||
$this->buyerId = $users->create('buyer@bazaar.test', 'hash', 'Buyer');
|
||||
$this->strangerId = $users->create('stranger@bazaar.test', 'hash', 'Stranger');
|
||||
}
|
||||
|
||||
private function purchase(int $userId, int $productId, string $status = 'paid'): void
|
||||
{
|
||||
$orderId = $this->orders->create($userId, 5000, 'usd');
|
||||
$this->orders->addItem($orderId, $productId, 'Item', 5000, 1);
|
||||
$this->orders->setStatus($orderId, $status, $status === 'paid' ? 'paidAt' : 'fulfilledAt');
|
||||
}
|
||||
|
||||
public function testStrangerCannotReview(): void
|
||||
{
|
||||
$productId = $this->seedProduct('Lamp', 5000, 5);
|
||||
$this->assertSame(ReviewService::notPurchased, $this->service->eligibility($this->strangerId, $productId));
|
||||
$this->assertFalse($this->service->canReview($this->strangerId, $productId));
|
||||
}
|
||||
|
||||
public function testBuyerCanReviewAfterPaidOrder(): void
|
||||
{
|
||||
$productId = $this->seedProduct('Lamp', 5000, 5);
|
||||
$this->purchase($this->buyerId, $productId, 'paid');
|
||||
|
||||
$this->assertSame(ReviewService::eligible, $this->service->eligibility($this->buyerId, $productId));
|
||||
}
|
||||
|
||||
public function testPendingOrderDoesNotUnlockReview(): void
|
||||
{
|
||||
$productId = $this->seedProduct('Lamp', 5000, 5);
|
||||
$orderId = $this->orders->create($this->buyerId, 5000, 'usd');
|
||||
$this->orders->addItem($orderId, $productId, 'Item', 5000, 1);
|
||||
|
||||
$this->assertFalse($this->service->canReview($this->buyerId, $productId));
|
||||
}
|
||||
|
||||
public function testSubmitThrowsForNonBuyer(): void
|
||||
{
|
||||
$productId = $this->seedProduct('Lamp', 5000, 5);
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->service->submit($this->strangerId, $productId, 5, 'Nice', 'Great lamp');
|
||||
}
|
||||
|
||||
public function testCannotReviewTwice(): void
|
||||
{
|
||||
$productId = $this->seedProduct('Lamp', 5000, 5);
|
||||
$this->purchase($this->buyerId, $productId);
|
||||
$this->service->submit($this->buyerId, $productId, 4, 'Good', 'Solid');
|
||||
|
||||
$this->assertSame(ReviewService::alreadyReviewed, $this->service->eligibility($this->buyerId, $productId));
|
||||
}
|
||||
|
||||
public function testReviewIsPendingUntilModeratedAndSummaryCountsApprovedOnly(): void
|
||||
{
|
||||
$productId = $this->seedProduct('Lamp', 5000, 5);
|
||||
$this->purchase($this->buyerId, $productId);
|
||||
$reviewId = $this->service->submit($this->buyerId, $productId, 5, 'Great', 'Love it');
|
||||
|
||||
$this->assertSame('pending', $this->reviews->find($reviewId)['status']);
|
||||
$this->assertSame(0, $this->reviews->summary($productId)['count']);
|
||||
$this->assertCount(0, $this->reviews->approvedForProduct($productId));
|
||||
|
||||
$this->service->approve($reviewId);
|
||||
|
||||
$summary = $this->reviews->summary($productId);
|
||||
$this->assertSame(1, $summary['count']);
|
||||
$this->assertSame(5.0, $summary['average']);
|
||||
$this->assertCount(1, $this->reviews->approvedForProduct($productId));
|
||||
}
|
||||
|
||||
public function testRatingIsClampedIntoRange(): void
|
||||
{
|
||||
$productId = $this->seedProduct('Lamp', 5000, 5);
|
||||
$this->purchase($this->buyerId, $productId);
|
||||
$reviewId = $this->service->submit($this->buyerId, $productId, 9, 'Too high', 'x');
|
||||
|
||||
$this->assertSame(5, (int) $this->reviews->find($reviewId)['rating']);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user