diff --git a/tests/CartTest.php b/tests/CartTest.php new file mode 100644 index 0000000..fd4a8e1 --- /dev/null +++ b/tests/CartTest.php @@ -0,0 +1,87 @@ +db)); + } + + public function testAddAccumulatesQuantity(): void + { + $productId = $this->seedProduct('Cold Brew', 1400, 50); + $cart = $this->cart(); + + $cart->add($productId, 2); + $cart->add($productId, 3); + + $this->assertSame(5, $cart->count()); + $this->assertSame(1400 * 5, $cart->totalCents()); + } + + public function testAddClampsToAvailableStock(): void + { + $productId = $this->seedProduct('Sencha Tin', 1600, 3); + $cart = $this->cart(); + + $cart->add($productId, 10); + + $lines = $cart->lines(); + $this->assertCount(1, $lines); + $this->assertSame(3, $lines[0]['quantity']); + } + + public function testUpdateToZeroRemovesLine(): void + { + $productId = $this->seedProduct('Notebook', 1200, 20); + $cart = $this->cart(); + $cart->add($productId, 4); + + $cart->update($productId, 0); + + $this->assertTrue($cart->isEmpty()); + $this->assertSame(0, $cart->totalCents()); + } + + public function testRemoveDropsProduct(): void + { + $first = $this->seedProduct('Chef Knife', 8900, 5); + $second = $this->seedProduct('Linen Apron', 3200, 5); + $cart = $this->cart(); + $cart->add($first, 1); + $cart->add($second, 2); + + $cart->remove($first); + + $lines = $cart->lines(); + $this->assertCount(1, $lines); + $this->assertSame($second, (int) $lines[0]['product']['id']); + $this->assertSame(3200 * 2, $cart->totalCents()); + } + + public function testUnknownProductIsIgnored(): void + { + $cart = $this->cart(); + + $cart->add(9999, 1); + + $this->assertTrue($cart->isEmpty()); + } + + public function testLineTotalsAreComputed(): void + { + $a = $this->seedProduct('Walnut Board', 4800, 10); + $b = $this->seedProduct('Wool Throw', 7200, 10); + $cart = $this->cart(); + $cart->add($a, 2); + $cart->add($b, 1); + + $this->assertSame(4800 * 2 + 7200, $cart->totalCents()); + } +} diff --git a/tests/WishlistTest.php b/tests/WishlistTest.php new file mode 100644 index 0000000..7c15ad3 --- /dev/null +++ b/tests/WishlistTest.php @@ -0,0 +1,65 @@ +wishlist = new WishlistRepository($this->db); + $users = new UserRepository($this->db); + $this->userId = $users->create('a@bazaar.test', 'hash', 'A'); + $this->otherUserId = $users->create('b@bazaar.test', 'hash', 'B'); + } + + public function testToggleAddsThenRemoves(): void + { + $productId = $this->seedProduct('Mug', 1200, 5); + + $this->assertTrue($this->wishlist->toggle($this->userId, $productId)); + $this->assertTrue($this->wishlist->has($this->userId, $productId)); + + $this->assertFalse($this->wishlist->toggle($this->userId, $productId)); + $this->assertFalse($this->wishlist->has($this->userId, $productId)); + } + + public function testAddIsIdempotent(): void + { + $productId = $this->seedProduct('Mug', 1200, 5); + + $this->wishlist->add($this->userId, $productId); + $this->wishlist->add($this->userId, $productId); + + $this->assertSame(1, $this->wishlist->count($this->userId)); + } + + public function testWishlistIsScopedPerUser(): void + { + $productId = $this->seedProduct('Mug', 1200, 5); + $this->wishlist->add($this->userId, $productId); + + $this->assertTrue($this->wishlist->has($this->userId, $productId)); + $this->assertFalse($this->wishlist->has($this->otherUserId, $productId)); + $this->assertSame(0, $this->wishlist->count($this->otherUserId)); + } + + public function testForUserReturnsProductRows(): void + { + $first = $this->seedProduct('Mug', 1200, 5); + $second = $this->seedProduct('Plate', 1800, 5); + $this->wishlist->add($this->userId, $first); + $this->wishlist->add($this->userId, $second); + + $rows = $this->wishlist->forUser($this->userId); + $this->assertCount(2, $rows); + $this->assertSame([$first, $second], array_values(array_reverse(array_map('intval', array_column($rows, 'id'))))); + } +}