Failed Conditions
Push — master ( 64d413...b77024 )
by Adrien
10:04
created

MessageQueuerTest::createMockUserWithFamilyOwner()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 15
c 0
b 0
f 0
dl 0
loc 23
rs 9.7666
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 userProvider(): array
121
    {
122
        $userWithEmail = $this->createMockUser();
123
        $userWithFamilyOwner = $this->createMockUserWithFamilyOwner(true);
124
        $userWithFamilyOwnerWithoutEmail = $this->createMockUserWithFamilyOwner(false);
125
        $userWithoutEmail = $this->createMockUserWithoutEmail();
126
127
        return [
128
            'user with email' => [$userWithEmail, '[email protected]'],
129
            'user without email' => [$userWithoutEmail, null],
130
            'user without email but with family owner with email' => [$userWithFamilyOwner, '[email protected]'],
131
            'user without email but with family owner without email' => [$userWithFamilyOwnerWithoutEmail, null],
132
        ];
133
    }
134
135
    private function createMockUser(?User $owner = null): User
136
    {
137
        $user = $this->createMock(User::class);
138
139
        $user->expects(self::any())
140
            ->method('getId')
141
            ->willReturn(123);
142
143
        $user->expects(self::any())
144
            ->method('getLogin')
145
            ->willReturn('john.doe');
146
147
        $user->expects(self::any())
148
            ->method('getFirstName')
149
            ->willReturn('John');
150
151
        $user->expects(self::any())
152
            ->method('getLastName')
153
            ->willReturn('Doe');
154
155
        $user->expects(self::any())
156
            ->method('getName')
157
            ->willReturn('John Doe');
158
159
        $user->expects(self::any())
160
            ->method('getEmail')
161
            ->willReturn($owner ? null : '[email protected]');
162
163
        $user->expects(self::any())
164
            ->method('createToken')
165
            ->willReturn(str_repeat('X', 32));
166
167
        $user->expects(self::any())
168
            ->method('getOwner')
169
            ->willReturn($owner);
170
171
        return $user;
172
    }
173
174
    private function createMockUserWithFamilyOwner(bool $hasEmail): User
175
    {
176
        $owner = $this->createMock(User::class);
177
178
        $owner->expects(self::any())
179
            ->method('getFirstName')
180
            ->willReturn('Family');
181
182
        $owner->expects(self::any())
183
            ->method('getLastName')
184
            ->willReturn('Owner');
185
186
        $owner->expects(self::any())
187
            ->method('getName')
188
            ->willReturn('Family Owner');
189
190
        $owner->expects(self::any())
191
            ->method('getEmail')
192
            ->willReturn($hasEmail ? '[email protected]' : null);
193
194
        $user = $this->createMockUser($owner);
195
196
        return $user;
197
    }
198
199
    private function createMockUserAdmin(): User
200
    {
201
        $user = $this->createMock(User::class);
202
        $user->expects(self::any())
203
            ->method('getLogin')
204
            ->willReturn('admin');
205
206
        $user->expects(self::any())
207
            ->method('getFirstName')
208
            ->willReturn('Admin');
209
210
        $user->expects(self::any())
211
            ->method('getLastName')
212
            ->willReturn('Istrator');
213
214
        $user->expects(self::any())
215
            ->method('getEmail')
216
            ->willReturn('[email protected]');
217
218
        return $user;
219
    }
220
221
    private function createMockUserMinimal(): User
222
    {
223
        $user = $this->createMock(User::class);
224
        $user->expects(self::any())
225
            ->method('getEmail')
226
            ->willReturn('[email protected]');
227
228
        $user->expects(self::any())
229
            ->method('createToken')
230
            ->willReturn(str_repeat('X', 32));
231
232
        return $user;
233
    }
234
235
    private function createMockUserWithoutEmail(): User
236
    {
237
        $user = $this->createMock(User::class);
238
239
        return $user;
240
    }
241
242
    private function assertMessage(?Message $message, ?User $user, ?string $email, string $type, string $subject, ?string $variant = null): void
243
    {
244
        if (!$email) {
245
            self::assertNull($message);
246
247
            return;
248
        }
249
250
        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

250
        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...
251
        self::assertSame($email, $message->getEmail());
252
        self::assertSame($user, $message->getRecipient());
253
        self::assertNull($message->getDateSent());
254
        self::assertSame($subject, $message->getSubject());
255
256
        $variant = $variant ? '-' . $variant : $variant;
257
        $expectedBody = 'tests/data/emails/' . str_replace('_', '-', $type . $variant) . '.html';
258
        $this->assertFile($expectedBody, $message->getBody());
259
    }
260
261
    /**
262
     * Custom assert that will not produce gigantic diff
263
     */
264
    private function assertFile(string $file, string $actual): void
265
    {
266
        // Log actual result for easier comparison with external diff tools
267
        $logFile = 'logs/' . $file;
268
        $dir = dirname($logFile);
269
        @mkdir($dir, 0777, true);
270
        file_put_contents($logFile, $actual);
271
272
        self::assertFileExists($file, 'Expected file must exist on disk, fix it with: cp ' . $logFile . ' ' . $file);
273
        $expected = file_get_contents($file);
274
275
        self::assertTrue($expected === $actual, 'File content does not match, compare with: meld ' . $file . ' ' . $logFile);
276
    }
277
278
    private function createBookable(string $bookableName, Money $periodicPrice): Bookable
279
    {
280
        $bookable = new Bookable();
281
        $bookable->setName($bookableName);
282
        $bookable->setPeriodicPrice($periodicPrice);
283
284
        return $bookable;
285
    }
286
}
287