BookingRepositoryTest   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 306
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 13
eloc 188
c 2
b 0
f 0
dl 0
loc 306
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 5 1
A tearDown() 0 4 1
A testGetAllToInvoiceForUser() 0 12 1
A testGetAllToInvoiceAllCases() 0 11 2
B insertTestData() 0 45 6
A testGetAllToInvoice() 0 14 1
B providerGetAllToInvoiceAllCases() 0 193 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApplicationTest\Repository;
6
7
use Application\Enum\BookableStatus;
8
use Application\Enum\BookingStatus;
9
use Application\Enum\BookingType;
10
use Application\Enum\UserStatus;
11
use Application\Model\Booking;
12
use Application\Model\User;
13
use Application\Repository\BookingRepository;
14
use Cake\Chronos\Chronos;
15
use Ecodev\Felix\Utility;
16
17
class BookingRepositoryTest extends AbstractRepositoryTest
18
{
19
    private BookingRepository $repository;
20
21
    protected function setUp(): void
22
    {
23
        parent::setUp();
24
        $this->repository = $this->getEntityManager()->getRepository(Booking::class);
25
        Chronos::setTestNow(new Chronos('2020-01-01'));
26
    }
27
28
    protected function tearDown(): void
29
    {
30
        Chronos::setTestNow(null);
31
        parent::tearDown();
32
    }
33
34
    public function testGetAllToInvoice(): void
35
    {
36
        $bookings = $this->repository->getAllToInvoice();
37
        $actual = Utility::modelToId($bookings);
38
39
        $expected = [
40
            4004,
41
            4005,
42
            4015,
43
            4007,
44
            4017,
45
        ];
46
47
        self::assertSame($expected, $actual);
48
    }
49
50
    public function testGetAllToInvoiceForUser(): void
51
    {
52
        $user = $this->getEntityManager()->getRepository(User::class)->getOneById(1005);
53
54
        $bookings = $this->repository->getAllToInvoice($user);
55
        $actual = Utility::modelToId($bookings);
56
57
        $expected = [
58
            4007,
59
        ];
60
61
        self::assertSame($expected, $actual);
62
    }
63
64
    private function insertTestData(array $data): void
65
    {
66
        $connection = $this->getEntityManager()->getConnection();
67
        $connection->executeQuery('DELETE FROM booking');
68
69
        foreach ($data as $user) {
70
            $bookings = $user['bookings'] ?? [];
71
            $account = $user['account'] ?? null;
72
73
            unset($user['bookings'], $user['account']);
74
            $connection->insert('user', $user);
75
            $userId = $connection->lastInsertId();
76
77
            foreach ($bookings as $booking) {
78
                $booking['owner_id'] = $userId;
79
80
                $bookable = $booking['bookable'] ?? null;
81
                unset($booking['bookable']);
82
83
                if ($bookable) {
84
                    $connection->insert('bookable', $bookable);
85
                    $bookableId = $connection->lastInsertId();
86
                    $booking['bookable_id'] = $bookableId;
87
                }
88
89
                $connection->insert('booking', $booking);
90
            }
91
92
            if ($account) {
93
                $connection->insert('account', [
94
                    'owner_id' => $userId,
95
                ]);
96
                $accountId = $connection->lastInsertId();
97
98
                $connection->insert('transaction', []);
99
                $transactionId = $connection->lastInsertId();
100
101
                foreach ($account['transaction_lines'] as $line) {
102
                    $line['transaction_id'] = $transactionId;
103
                    $line['debit_id'] = $accountId;
104
105
                    // Automatically link to last bookable created
106
                    $line['bookable_id'] = $bookableId ?? null;
107
108
                    $connection->insert('transaction_line', $line);
109
                }
110
            }
111
        }
112
    }
113
114
    /**
115
     * @dataProvider providerGetAllToInvoiceAllCases
116
     */
117
    public function testGetAllToInvoiceAllCases(array $data, array $expected): void
118
    {
119
        $this->insertTestData($data);
120
        $bookings = $this->repository->getAllToInvoice();
121
122
        $actual = [];
123
        foreach ($bookings as $a) {
124
            $actual[] = $a->getBookable()->getName();
125
        }
126
127
        self::assertSame($expected, $actual);
128
    }
129
130
    public static function providerGetAllToInvoiceAllCases(): iterable
131
    {
132
        $normal = [
133
            [
134
                'role' => User::ROLE_MEMBER,
135
                'status' => UserStatus::Active->value,
136
                'bookings' => [
137
                    [
138
                        'start_date' => '2019-02-25',
139
                        'end_date' => null,
140
                        'status' => BookingStatus::Booked->value,
141
                        'bookable' => [
142
                            'name' => 'cotisation',
143
                            'booking_type' => BookingType::Mandatory->value,
144
                            'status' => BookableStatus::Active->value,
145
                            'periodic_price' => '25.00',
146
                        ],
147
                    ],
148
                    [
149
                        'start_date' => '2020-01-01',
150
                        'end_date' => null,
151
                        'status' => BookingStatus::Booked->value,
152
                        'bookable' => [
153
                            'name' => 'casier',
154
                            'booking_type' => BookingType::AdminAssigned->value,
155
                            'status' => BookableStatus::Active->value,
156
                            'periodic_price' => '25.00',
157
                        ],
158
                    ],
159
                ],
160
                'account' => [
161
                    'transaction_lines' => [
162
                        [
163
                            'balance' => '5.00',
164
                            'transaction_date' => '2019-02-25',
165
                        ],
166
                    ],
167
                ],
168
            ],
169
        ];
170
171
        $inactiveUser = $normal;
172
        $inactiveUser[0]['status'] = UserStatus::Inactive->value;
173
174
        $archivedUser = $normal;
175
        $archivedUser[0]['status'] = UserStatus::Archived->value;
176
177
        $newUser = $normal;
178
        $newUser[0]['status'] = UserStatus::New->value;
179
180
        $bookingOnlyUser = $normal;
181
        $bookingOnlyUser[0]['role'] = User::ROLE_BOOKING_ONLY;
182
183
        $individualUser = $normal;
184
        $individualUser[0]['role'] = User::ROLE_INDIVIDUAL;
185
186
        $trainerUser = $normal;
187
        $trainerUser[0]['role'] = User::ROLE_TRAINER;
188
189
        $responsibleUser = $normal;
190
        $responsibleUser[0]['role'] = User::ROLE_RESPONSIBLE;
191
192
        $administratorUser = $normal;
193
        $administratorUser[0]['role'] = User::ROLE_ADMINISTRATOR;
194
195
        $futureBookingThisYear = $normal;
196
        $futureBookingThisYear[0]['bookings'][0]['start_date'] = '2019-12-31';
197
198
        $futureBookingNextYear = $normal;
199
        $futureBookingNextYear[0]['bookings'][0]['start_date'] = '2021-01-01';
200
201
        $terminatedBooking = $normal;
202
        $terminatedBooking[0]['bookings'][0]['end_date'] = '2019-01-01';
203
204
        $terminatedBooking = $normal;
205
        $terminatedBooking[0]['bookings'][0]['end_date'] = '2019-01-01';
206
207
        $terminatedBookingNextYear = $normal;
208
        $terminatedBookingNextYear[0]['bookings'][0]['end_date'] = '2021-01-01';
209
210
        $applicationBooking = $normal;
211
        $applicationBooking[0]['bookings'][0]['status'] = BookingStatus::Application->value;
212
213
        $processedBooking = $normal;
214
        $processedBooking[0]['bookings'][0]['status'] = BookingStatus::Processed->value;
215
216
        $selfApprovedBookable = $normal;
217
        $selfApprovedBookable[0]['bookings'][0]['bookable']['booking_type'] = BookingType::SelfApproved->value;
218
219
        $applicationBookable = $normal;
220
        $applicationBookable[0]['bookings'][0]['bookable']['booking_type'] = BookingType::Application->value;
221
222
        $inactiveBookable = $normal;
223
        $inactiveBookable[0]['bookings'][0]['bookable']['status'] = BookableStatus::Inactive->value;
224
225
        $freeBookable = $normal;
226
        $freeBookable[0]['bookings'][0]['bookable']['periodic_price'] = 0;
227
228
        $negativeBookable = $normal;
229
        $negativeBookable[0]['bookings'][0]['bookable']['periodic_price'] = -10;
230
231
        $existingTransactionThisYear = $normal;
232
        $existingTransactionThisYear[0]['account']['transaction_lines'][0]['transaction_date'] = '2020-02-01';
233
234
        $existingTransactionNextYear = $normal;
235
        $existingTransactionNextYear[0]['account']['transaction_lines'][0]['transaction_date'] = '2021-02-01';
236
        yield 'normal user get casier and cotisation' => [
237
            $normal,
238
            ['casier', 'cotisation'],
239
        ];
240
        yield 'inactive user get casier and cotisation' => [
241
            $inactiveUser,
242
            ['casier', 'cotisation'],
243
        ];
244
        yield 'archived user get nothing' => [
245
            $archivedUser,
246
            [],
247
        ];
248
        yield 'new user get casier and cotisation' => [
249
            $newUser,
250
            ['casier', 'cotisation'],
251
        ];
252
        yield 'bookingOnly user get nothing' => [
253
            $bookingOnlyUser,
254
            [],
255
        ];
256
        yield 'individual user get casier and cotisation so it can be invoiced to family owner' => [
257
            $individualUser,
258
            ['casier', 'cotisation'],
259
        ];
260
        yield 'trainer user get casier and cotisation' => [
261
            $trainerUser,
262
            ['casier', 'cotisation'],
263
        ];
264
        yield 'responsible user get casier and cotisation' => [
265
            $responsibleUser,
266
            ['casier', 'cotisation'],
267
        ];
268
        yield 'administrator user get casier and cotisation' => [
269
            $administratorUser,
270
            ['casier', 'cotisation'],
271
        ];
272
        yield 'future booking this year are still counted' => [
273
            $futureBookingThisYear,
274
            ['casier', 'cotisation'],
275
        ];
276
        yield 'future booking next year are not yet counted' => [
277
            $futureBookingNextYear,
278
            ['casier'],
279
        ];
280
        yield 'terminated booking are not counted anymore' => [
281
            $terminatedBooking,
282
            ['casier'],
283
        ];
284
        yield 'terminated booking next year are not yet terminated so must be counted' => [
285
            $terminatedBookingNextYear,
286
            ['casier', 'cotisation'],
287
        ];
288
        yield 'application booking is ignored' => [
289
            $applicationBooking,
290
            ['casier'],
291
        ];
292
        yield 'processsed booking is ignored' => [
293
            $processedBooking,
294
            ['casier'],
295
        ];
296
        yield 'self approved bookable is not counted' => [
297
            $selfApprovedBookable,
298
            ['casier'],
299
        ];
300
        yield 'application bookable is not counted' => [
301
            $applicationBookable,
302
            ['casier'],
303
        ];
304
        yield 'inactive bookable is not counted' => [
305
            $inactiveBookable,
306
            ['casier'],
307
        ];
308
        yield 'free bookable is not counted' => [
309
            $freeBookable,
310
            ['casier'],
311
        ];
312
        yield 'negative bookable is counted' => [
313
            $negativeBookable,
314
            ['casier', 'cotisation'],
315
        ];
316
        yield 'existing transaction for this year should not be re-created' => [
317
            $existingTransactionThisYear,
318
            ['cotisation'],
319
        ];
320
        yield 'existing transaction for next year have no impact' => [
321
            $existingTransactionNextYear,
322
            ['casier', 'cotisation'],
323
        ];
324
    }
325
}
326