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
6declare(strict_types=1);
7
8namespace Tests\Models;
9
10use App\Models\Artist;
11use App\Models\Country;
12use Exception;
13use Tests\TestCase;
14
15class ModelTest extends TestCase
16{
17 /**
18 * @dataProvider dataProviderForDecrementInstance
19 */
20 public function testDecrementInstance(callable $countryFn, bool $isChanged): void
21 {
22 $country = $countryFn();
23 $anotherCountry = Country::factory()->create();
24 $column = 'playcount';
25
26 $this->expectCountChange(fn () => $country->$column, $isChanged ? -1 : 0);
27 $this->expectCountChange(fn () => $anotherCountry->$column, 0);
28
29 $country->decrementInstance($column);
30 $country->refresh();
31 $anotherCountry->refresh();
32 }
33
34 /**
35 * @dataProvider dataProviderForDecrementInstance
36 */
37 public function testDecrementInstanceSpecifyCount(callable $countryFn, bool $isChanged): void
38 {
39 $country = $countryFn();
40 $anotherCountry = Country::factory()->create();
41 $column = 'playcount';
42 $change = 10;
43
44 $this->expectCountChange(fn () => $country->$column, $isChanged ? -$change : 0);
45 $this->expectCountChange(fn () => $anotherCountry->$column, 0);
46
47 $country->decrementInstance($column, $change);
48 $country->refresh();
49 $anotherCountry->refresh();
50 }
51
52 public function testGetWithHasMore()
53 {
54 Artist::factory()->count(5)->create();
55 $count = Artist::count();
56
57 $limit = $count - 1;
58 [$artists, $hasMore] = Artist::select()->limit($limit)->getWithHasMore();
59
60 $this->assertSame($limit, $artists->count());
61 $this->assertTrue($hasMore);
62
63 $offset = 2;
64 $limit = $count - $offset - 1;
65 [$artists, $hasMore] = Artist::select()->offset($offset)->limit($limit)->getWithHasMore();
66
67 $this->assertSame($limit, $artists->count());
68 $this->assertTrue($hasMore);
69
70 $limit = $count;
71 [$artists, $hasMore] = Artist::select()->limit($limit)->getWithHasMore();
72
73 $this->assertSame($limit, $artists->count());
74 $this->assertFalse($hasMore);
75
76 $offset = 2;
77 $limit = $count - $offset;
78 [$artists, $hasMore] = Artist::select()->offset($offset)->limit($limit)->getWithHasMore();
79
80 $this->assertSame($limit, $artists->count());
81 $this->assertFalse($hasMore);
82
83 $offset = 2;
84 $limit = $count;
85 [$artists, $hasMore] = Artist::select()->offset($offset)->limit($limit)->getWithHasMore();
86
87 $this->assertSame($limit - $offset, $artists->count());
88 $this->assertFalse($hasMore);
89 }
90
91 public function testGetWithHasMoreMissingLimit()
92 {
93 $this->expectException(Exception::class);
94
95 Artist::select()->getWithHasMore();
96 }
97
98 /**
99 * @dataProvider dataProviderForDecrementInstance
100 */
101 public function testIncrementInstance(callable $countryFn, bool $isChanged): void
102 {
103 $country = $countryFn();
104 $anotherCountry = Country::factory()->create();
105 $column = 'playcount';
106
107 $this->expectCountChange(fn () => $country->playcount, $isChanged ? 1 : 0);
108 $this->expectCountChange(fn () => $anotherCountry->$column, 0);
109
110 $country->incrementInstance($column);
111 $country->refresh();
112 $anotherCountry->refresh();
113 }
114
115 /**
116 * @dataProvider dataProviderForDecrementInstance
117 */
118 public function testIncrementInstanceSpecifyCount(callable $countryFn, bool $isChanged): void
119 {
120 $country = $countryFn();
121 $anotherCountry = Country::factory()->create();
122 $column = 'playcount';
123 $change = 10;
124
125 $this->expectCountChange(fn () => $country->$column, $isChanged ? $change : 0);
126 $this->expectCountChange(fn () => $anotherCountry->$column, 0);
127
128 $country->incrementInstance($column, $change);
129 $country->refresh();
130 $anotherCountry->refresh();
131 }
132
133 public static function dataProviderForDecrementInstance(): array
134 {
135 return [
136 [fn () => Country::factory()->create(), true],
137 [fn () => new Country(['playcount' => 0]), false],
138 ];
139 }
140}