the browser-facing portion of osu!
at master 3.3 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6namespace Tests\Models\Store; 7 8use App\Exceptions\InsufficientStockException; 9use App\Exceptions\InvariantException; 10use App\Models\Store\OrderItem; 11use App\Models\Store\Product; 12use Tests\TestCase; 13 14class OrderItemTest extends TestCase 15{ 16 /** 17 * @dataProvider deleteDataProvider 18 */ 19 public function testDelete(string $status, ?string $expectedException) 20 { 21 [, $orderItem] = $this->createProductAndOrderItem(5, false); 22 23 $orderItem->order->update(['status' => $status]); 24 25 if ($expectedException === null) { 26 $this->expectNotToPerformAssertions(); 27 } else { 28 $this->expectException($expectedException); 29 } 30 31 $orderItem->delete(); 32 } 33 34 public function testReserveUnreservedProduct() 35 { 36 [$product, $orderItem] = $this->createProductAndOrderItem(5, false); 37 38 $this->expectCountChange(fn () => $product->fresh()->stock, -2); 39 40 $orderItem->reserveProduct(); 41 42 $this->assertTrue($orderItem->fresh()->reserved); 43 } 44 45 public function testReserveReservedProduct() 46 { 47 [$product, $orderItem] = $this->createProductAndOrderItem(5, true); 48 49 $this->expectCountChange(fn () => $product->fresh()->stock, 0); 50 51 $orderItem->reserveProduct(); 52 53 $this->assertTrue($orderItem->fresh()->reserved); 54 } 55 56 public function testReleaseUnreservedProduct() 57 { 58 [$product, $orderItem] = $this->createProductAndOrderItem(5, false); 59 60 $this->expectCountChange(fn () => $product->fresh()->stock, 0); 61 62 $orderItem->releaseProduct(); 63 64 $this->assertFalse($orderItem->fresh()->reserved); 65 } 66 67 public function testReleaseReservedProduct() 68 { 69 [$product, $orderItem] = $this->createProductAndOrderItem(5, true); 70 71 $this->expectCountChange(fn () => $product->fresh()->stock, 2); 72 73 $orderItem->releaseProduct(); 74 75 $this->assertFalse($orderItem->fresh()->reserved); 76 } 77 78 public function testReserveInsufficientStock() 79 { 80 [, $orderItem] = $this->createProductAndOrderItem(1, false); 81 82 $this->expectException(InsufficientStockException::class); 83 $orderItem->reserveProduct(); 84 } 85 86 public function testReleaseWhenStockIsZero() 87 { 88 [$product, $orderItem] = $this->createProductAndOrderItem(0, true); 89 90 $this->expectCountChange(fn () => $product->fresh()->stock, 0); 91 92 $orderItem->releaseProduct(); 93 94 $this->assertFalse($orderItem->fresh()->reserved); 95 } 96 97 public static function deleteDataProvider() 98 { 99 return [ 100 ['checkout', InvariantException::class], 101 ['incart', null], 102 ['processing', InvariantException::class], 103 ]; 104 } 105 106 private function createProductAndOrderItem(int $stock, bool $reserved) 107 { 108 $product = Product::factory()->create(['stock' => $stock, 'max_quantity' => 5]); 109 $orderItem = OrderItem::factory()->create([ 110 'product_id' => $product, 111 'quantity' => 2, 112 'reserved' => $reserved, 113 ]); 114 115 return [$product, $orderItem]; 116 } 117}