MessageQueuerTest::createMockUser()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 37
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 26
dl 0
loc 37
rs 9.504
c 0
b 0
f 0
cc 2
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApplicationTest\Service;
6
7
use Application\DBAL\Types\MessageTypeType;
8
use Application\Model\Account;
9
use Application\Model\Bookable;
10
use Application\Model\Message;
11
use Application\Model\User;
12
use Application\Service\MessageQueuer;
13
use Doctrine\ORM\EntityManager;
14
use Ecodev\Felix\Service\MessageRenderer;
15
use Laminas\View\Renderer\RendererInterface;
16
use Money\Money;
17
18
class MessageQueuerTest extends \PHPUnit\Framework\TestCase
19
{
20
    private function createMessageQueuer(): MessageQueuer
21
    {
22
        global $container;
23
24
        $entityManager = $container->get(EntityManager::class);
25
        $viewRenderer = $container->get(RendererInterface::class);
26
        $messageRenderer = new MessageRenderer($viewRenderer, 'my-ichtus.lan');
27
28
        $messageQueuer = new MessageQueuer(
29
            $entityManager,
30
            $messageRenderer,
31
        );
32
33
        return $messageQueuer;
34
    }
35
36
    public function testQueueRegister(): void
37
    {
38
        $user = $this->createMockUserMinimal();
39
        $messageQueuer = $this->createMessageQueuer();
40
        $message = $messageQueuer->queueRegister($user);
41
42
        $this->assertMessage($message, $user, '[email protected]', MessageTypeType::REGISTER, 'Demande de création de compte au Club Nautique Ichtus');
43
    }
44
45
    public function testQueueUnregister(): void
46
    {
47
        $unregisteredUser = $this->createMockUser();
48
        $admin = $this->createMockUserAdmin();
49
        $messageQueuer = $this->createMessageQueuer();
50
        $message = $messageQueuer->queueUnregister($admin, $unregisteredUser);
51
52
        $this->assertMessage($message, $admin, '[email protected]', MessageTypeType::UNREGISTER, 'Démission');
53
    }
54
55
    /**
56
     * @dataProvider userProvider
57
     */
58
    public function testQueueResetPassword(User $user, ?string $expectedEmail): void
59
    {
60
        $messageQueuer = $this->createMessageQueuer();
61
        $message = $messageQueuer->queueResetPassword($user);
62
63
        $this->assertMessage($message, $user, $expectedEmail, MessageTypeType::RESET_PASSWORD, 'Demande de modification de mot de passe');
64
    }
65
66
    public function testQueueBalancePositive(): void
67
    {
68
        $bookables = [];
69
        $bookables[] = $this->createBookable('Cotisation', Money::CHF(9000));
70
        $bookables[] = $this->createBookable('Fonds de réparation interne', Money::CHF(1000));
71
72
        $this->queueBalance($bookables, 'positive');
73
    }
74
75
    public function testQueueBalanceNegative(): void
76
    {
77
        $bookables = [];
78
        $bookables[] = $this->createBookable('Cotisation', Money::CHF(9000));
79
        $bookables[] = $this->createBookable('Fonds de réparation interne', Money::CHF(1000));
80
        $bookables[] = $this->createBookable('Casier 1012', Money::CHF(2000));
81
        $bookables[] = $this->createBookable('Casier 1014', Money::CHF(2000));
82
83
        $this->queueBalance($bookables, 'negative');
84
    }
85
86
    private function queueBalance(array $bookables, string $variant): void
87
    {
88
        $user = new User();
89
        $user->setLogin('john.doe');
90
        $user->setFirstName('John');
91
        $user->setLastName('Doe');
92
        $user->setEmail('[email protected]');
93
94
        $account = new Account();
95
        $account->setBalance(Money::CHF($variant === 'positive' ? 2500 : -4500));
96
        $account->setOwner($user);
97
98
        $messageQueuer = $this->createMessageQueuer();
99
        $message = $messageQueuer->queueBalance($user, $bookables);
100
101
        $this->assertMessage($message, $user, '[email protected]', MessageTypeType::BALANCE, 'Balance de compte', $variant);
102
    }
103
104
    public function testQueueAllBalance(): void
105
    {
106
        $messageQueuer = $this->createMessageQueuer();
107
        $actual = $messageQueuer->queueAllBalance();
108
109
        self::assertsame(2, $actual);
110
    }
111
112
    public function testQueueNegativeBalance(): void
113
    {
114
        $messageQueuer = $this->createMessageQueuer();
115
        $actual = $messageQueuer->queueNegativeBalance();
116
117
        self::assertsame(0, $actual);
118
    }
119
120
    public function testQueueLeaveFamily(): void
121
    {
122
        $messageQueuer = $this->createMessageQueuer();
123
        $user = $this->createMockUser();
124
        $message = $messageQueuer->queueLeaveFamily($user);
125
126
        $this->assertMessage($message, $user, '[email protected]', MessageTypeType::LEAVE_FAMILY, 'Ménage quitté');
127
    }
128
129
    public function testQueueAdminLeaveFamily(): void
130
    {
131
        $messageQueuer = $this->createMessageQueuer();
132
        $user = $this->createMockUser();
133
        $message = $messageQueuer->queueAdminLeaveFamily($user);
134
135
        $this->assertMessage($message, null, '[email protected]', MessageTypeType::ADMIN_LEAVE_FAMILY, 'Ménage quitté');
136
    }
137
138
    public function userProvider(): array
139
    {
140
        $userWithEmail = $this->createMockUser();
141
        $userWithFamilyOwner = $this->createMockUserWithFamilyOwner(true);
142
        $userWithFamilyOwnerWithoutEmail = $this->createMockUserWithFamilyOwner(false);
143
        $userWithoutEmail = $this->createMockUserWithoutEmail();
144
145
        return [
146
            'user with email' => [$userWithEmail, '[email protected]'],
147
            'user without email' => [$userWithoutEmail, null],
148
            'user without email but with family owner with email' => [$userWithFamilyOwner, '[email protected]'],
149
            'user without email but with family owner without email' => [$userWithFamilyOwnerWithoutEmail, null],
150
        ];
151
    }
152
153
    private function createMockUser(?User $owner = null): User
154
    {
155
        $user = $this->createMock(User::class);
156
157
        $user->expects(self::any())
158
            ->method('getId')
159
            ->willReturn(123);
160
161
        $user->expects(self::any())
162
            ->method('getLogin')
163
            ->willReturn('john.doe');
164
165
        $user->expects(self::any())
166
            ->method('getFirstName')
167
            ->willReturn('John');
168
169
        $user->expects(self::any())
170
            ->method('getLastName')
171
            ->willReturn('Doe');
172
173
        $user->expects(self::any())
174
            ->method('getName')
175
            ->willReturn('John Doe');
176
177
        $user->expects(self::any())
178
            ->method('getEmail')
179
            ->willReturn($owner ? null : '[email protected]');
180
181
        $user->expects(self::any())
182
            ->method('createToken')
183
            ->willReturn(str_repeat('X', 32));
184
185
        $user->expects(self::any())
186
            ->method('getOwner')
187
            ->willReturn($owner);
188
189
        return $user;
190
    }
191
192
    private function createMockUserWithFamilyOwner(bool $hasEmail): User
193
    {
194
        $owner = $this->createMock(User::class);
195
196
        $owner->expects(self::any())
197
            ->method('getFirstName')
198
            ->willReturn('Family');
199
200
        $owner->expects(self::any())
201
            ->method('getLastName')
202
            ->willReturn('Owner');
203
204
        $owner->expects(self::any())
205
            ->method('getName')
206
            ->willReturn('Family Owner');
207
208
        $owner->expects(self::any())
209
            ->method('getEmail')
210
            ->willReturn($hasEmail ? '[email protected]' : null);
211
212
        $user = $this->createMockUser($owner);
213
214
        return $user;
215
    }
216
217
    private function createMockUserAdmin(): User
218
    {
219
        $user = $this->createMock(User::class);
220
        $user->expects(self::any())
221
            ->method('getLogin')
222
            ->willReturn('admin');
223
224
        $user->expects(self::any())
225
            ->method('getFirstName')
226
            ->willReturn('Admin');
227
228
        $user->expects(self::any())
229
            ->method('getLastName')
230
            ->willReturn('Istrator');
231
232
        $user->expects(self::any())
233
            ->method('getEmail')
234
            ->willReturn('[email protected]');
235
236
        return $user;
237
    }
238
239
    private function createMockUserMinimal(): User
240
    {
241
        $user = $this->createMock(User::class);
242
        $user->expects(self::any())
243
            ->method('getEmail')
244
            ->willReturn('[email protected]');
245
246
        $user->expects(self::any())
247
            ->method('createToken')
248
            ->willReturn(str_repeat('X', 32));
249
250
        return $user;
251
    }
252
253
    private function createMockUserWithoutEmail(): User
254
    {
255
        $user = $this->createMock(User::class);
256
257
        return $user;
258
    }
259
260
    private function assertMessage(?Message $message, ?User $user, ?string $email, string $type, string $subject, ?string $variant = null): void
261
    {
262
        if (!$email) {
263
            self::assertNull($message);
264
265
            return;
266
        }
267
268
        self::assertSame($type, $message->getType());
0 ignored issues
show
Bug introduced by
The method getType() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

268
        self::assertSame($type, $message->/** @scrutinizer ignore-call */ getType());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
269
        self::assertSame($email, $message->getEmail());
270
        self::assertSame($user, $message->getRecipient());
271
        self::assertNull($message->getDateSent());
272
        self::assertSame($subject, $message->getSubject());
273
274
        $variant = $variant ? '-' . $variant : $variant;
275
        $expectedBody = 'tests/data/emails/' . str_replace('_', '-', $type . $variant) . '.html';
276
        $this->assertFile($expectedBody, $message->getBody());
277
    }
278
279
    /**
280
     * Custom assert that will not produce gigantic diff.
281
     */
282
    private function assertFile(string $file, string $actual): void
283
    {
284
        // Log actual result for easier comparison with external diff tools
285
        $logFile = 'logs/' . $file;
286
        $dir = dirname($logFile);
287
        @mkdir($dir, 0o777, true);
288
        file_put_contents($logFile, $actual);
289
290
        self::assertFileExists($file, 'Expected file must exist on disk, fix it with: cp ' . $logFile . ' ' . $file);
291
        $expected = file_get_contents($file);
292
293
        self::assertTrue($expected === $actual, 'File content does not match, compare with: meld ' . $file . ' ' . $logFile);
294
    }
295
296
    private function createBookable(string $bookableName, Money $periodicPrice): Bookable
297
    {
298
        $bookable = new Bookable();
299
        $bookable->setName($bookableName);
300
        $bookable->setPeriodicPrice($periodicPrice);
301
302
        return $bookable;
303
    }
304
}
305