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\Models\Store\Order;
9use App\Models\Store\OrderItem;
10use App\Models\Store\Product;
11use Tests\TestCase;
12
13class OrderTest extends TestCase
14{
15 public function testContainsSupporterTag()
16 {
17 $order = Order::factory()->create();
18 $product = Product::factory()->create();
19 OrderItem::factory()->create(['order_id' => $order, 'product_id' => $product]);
20 OrderItem::factory()->supporterTag()->create(['order_id' => $order]);
21
22 $this->assertTrue($order->containsSupporterTag());
23 }
24
25 public function testIsHideSupporterFromActivity()
26 {
27 $order = Order::factory()->create();
28 OrderItem::factory()->count(2)->supporterTag()->create(['order_id' => $order]);
29
30 $this->assertFalse($order->isHideSupporterFromActivity());
31
32 $order->items[0]->extra_data->hidden = true;
33 $order->saveOrExplode();
34
35 $this->assertTrue($order->isHideSupporterFromActivity());
36 }
37
38 public function testSetGiftsHidden()
39 {
40 $order = Order::factory()->create();
41 OrderItem::factory()->count(2)->supporterTag()->create(['order_id' => $order]);
42
43 $order->setGiftsHidden(true);
44 OrderItem::each(fn ($item) => $this->assertTrue($item->extra_data->hidden));
45
46 $order->setGiftsHidden(false);
47 OrderItem::each(fn ($item) => $this->assertFalse($item->extra_data->hidden));
48 }
49
50 public function testReserveItems()
51 {
52 $productFactory = Product::factory()->state(['stock' => 5, 'max_quantity' => 5]);
53 $orderItemFactory = OrderItem::factory();
54
55 $product1 = $productFactory->create();
56 $product2 = $productFactory->create();
57
58 $order = Order::factory()
59 ->has($orderItemFactory->state(['product_id' => $product1, 'quantity' => 2]), 'items')
60 ->has($orderItemFactory->state(['product_id' => $product2, 'quantity' => 1]), 'items')
61 ->create();
62
63 $this->expectCountChange(fn () => $product1->fresh()->stock, -2);
64 $this->expectCountChange(fn () => $product2->fresh()->stock, -1);
65 $this->expectCountChange(fn () => $order->fresh()->items()->where('reserved', true)->count(), 2);
66
67 $order->reserveItems();
68 }
69
70 public function testReserveItemsAlreadyReserved()
71 {
72 $productFactory = Product::factory()->state(['stock' => 5, 'max_quantity' => 5]);
73 $orderItemFactory = OrderItem::factory()->reserved();
74
75 $product1 = $productFactory->create();
76 $product2 = $productFactory->create();
77
78 $order = Order::factory()
79 ->has($orderItemFactory->state(['product_id' => $product1, 'quantity' => 2]), 'items')
80 ->has($orderItemFactory->state(['product_id' => $product2, 'quantity' => 1]), 'items')
81 ->create();
82
83 $this->expectCountChange(fn () => $product1->fresh()->stock, 0);
84 $this->expectCountChange(fn () => $product2->fresh()->stock, 0);
85 $this->expectCountChange(fn () => $order->fresh()->items()->where('reserved', true)->count(), 0);
86
87 $order->reserveItems();
88 }
89
90 public function testSwitchOrderItemReservation()
91 {
92 $product1 = Product::factory()->create(['stock' => 5, 'max_quantity' => 5]);
93 $product2 = Product::factory()->create(['stock' => 5, 'max_quantity' => 5]);
94 $orderItem = OrderItem::factory()->create([
95 'product_id' => $product1,
96 'quantity' => 2,
97 'reserved' => true,
98 ]);
99
100 $newProductId = $product2->product_id;
101
102 $order = $orderItem->order;
103 $order->switchItems($orderItem, $product2);
104
105 $order->refresh();
106 $product1->refresh();
107 $product2->refresh();
108
109 $this->assertSame($product1->stock, 7);
110 $this->assertSame($product2->stock, 3);
111 $this->assertSame($order->items()->count(), 1);
112 $this->assertSame($order->items->first()->product_id, $newProductId);
113 }
114}