Failed Conditions
Push — master ( b089ad...aace03 )
by Adrien
07:24
created

MailerTest   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 187
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 103
dl 0
loc 187
rs 10
c 0
b 0
f 0
wmc 16

14 Methods

Rating   Name   Duplication   Size   Complexity  
A queueInvoice() 0 16 2
A testQueueInvoicePositive() 0 7 1
A createMockUserMinimal() 0 12 1
A testQueueUnregister() 0 8 1
A createMockUserAdmin() 0 12 1
A testSendMessage() 0 9 1
A testQueueInvoiceNegative() 0 9 1
A testQueueRegister() 0 7 1
A assertMessage() 0 11 2
A assertFile() 0 12 1
A createMockUser() 0 15 1
A createMockMailer() 0 19 1
A testQueueResetPassword() 0 7 1
A creatTransactionLine() 0 9 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\Transaction;
12
use Application\Model\TransactionLine;
13
use Application\Model\User;
14
use Application\Service\Mailer;
15
use Doctrine\ORM\EntityManager;
16
use Prophecy\Argument;
17
use Zend\Mail\Transport\InMemory;
18
use Zend\View\Renderer\RendererInterface;
19
20
class MailerTest extends \PHPUnit\Framework\TestCase
21
{
22
    private function createMockMailer(): Mailer
23
    {
24
        global $container;
25
26
        $entityManager = $this->createMock(EntityManager::class);
27
        $renderer = $container->get(RendererInterface::class);
28
        $transport = new InMemory();
29
30
        $mailer = new Mailer(
31
            $entityManager,
32
            $transport,
33
            $renderer,
34
            'my-ichtus.lan',
35
            null,
36
            '[email protected]',
37
            '/user/bin/php'
38
        );
39
40
        return $mailer;
41
    }
42
43
    public function testQueueRegister(): void
44
    {
45
        $user = $this->createMockUserMinimal();
46
        $mailer = $this->createMockMailer();
47
        $message = $mailer->queueRegister($user);
48
49
        $this->assertMessage($message, $user, '[email protected]', MessageTypeType::REGISTER, 'Demande de création de compte au Club Nautique Ichtus');
50
    }
51
52
    public function testQueueUnregister(): void
53
    {
54
        $unregisteredUser = $this->createMockUser();
55
        $admin = $this->createMockUserAdmin();
56
        $mailer = $this->createMockMailer();
57
        $message = $mailer->queueUnregister($admin, $unregisteredUser);
58
59
        $this->assertMessage($message, $admin, '[email protected]', MessageTypeType::UNREGISTER, 'Démission');
60
    }
61
62
    public function testQueueResetPassword(): void
63
    {
64
        $user = $this->createMockUser();
65
        $mailer = $this->createMockMailer();
66
        $message = $mailer->queueResetPassword($user, '[email protected]');
67
68
        $this->assertMessage($message, $user, '[email protected]', MessageTypeType::RESET_PASSWORD, 'Demande de modification de mot de passe');
69
    }
70
71
    public function testQueueInvoicePositive(): void
72
    {
73
        $transaction = new Transaction();
74
        $this->creatTransactionLine($transaction, 'Cotisation', '90.00');
75
        $this->creatTransactionLine($transaction, 'Fonds de réparation interne', '10.00');
76
77
        $this->queueInvoice($transaction, 'positive');
78
    }
79
80
    public function testQueueInvoiceNegative(): void
81
    {
82
        $transaction = new Transaction();
83
        $this->creatTransactionLine($transaction, 'Cotisation', '90.00');
84
        $this->creatTransactionLine($transaction, 'Fonds de réparation interne', '10.00');
85
        $this->creatTransactionLine($transaction, 'Casier 1012', '20.00');
86
        $this->creatTransactionLine($transaction, 'Casier 1014', '20.00');
87
88
        $this->queueInvoice($transaction, 'negative');
89
    }
90
91
    private function queueInvoice(Transaction $transaction, string $variant): void
92
    {
93
        $user = new User();
94
        $user->setLogin('john.doe');
95
        $user->setFirstName('John');
96
        $user->setLastName('Doe');
97
        $user->setEmail('[email protected]');
98
99
        $account = new Account();
100
        $account->setBalance($variant === 'positive' ? '25.00' : '-45.00');
101
        $account->setOwner($user);
102
103
        $mailer = $this->createMockMailer();
104
        $message = $mailer->queueInvoice($user, $transaction);
105
106
        $this->assertMessage($message, $user, '[email protected]', MessageTypeType::INVOICE, 'Débit de compte', $variant);
107
    }
108
109
    public function testSendMessage(): void
110
    {
111
        $mailer = $this->createMockMailer();
112
        $message = new Message();
113
        $message->setEmail('[email protected]');
114
115
        $this->expectOutputRegex('~email sent to: john\.doe@example\.com~');
116
        $mailer->sendMessage($message);
117
        self::assertNotNull($message->getDateSent());
118
    }
119
120
    private function createMockUser(): User
121
    {
122
        $prophecy = $this->prophesize(User::class);
123
        $prophecy->getId()->willReturn(123);
124
        $prophecy->getLogin()->willReturn('john.doe');
125
        $prophecy->getFirstName()->willReturn('John');
126
        $prophecy->getLastName()->willReturn('Doe');
127
        $prophecy->getName()->willReturn('John Doe');
128
        $prophecy->getEmail()->willReturn('[email protected]');
129
        $prophecy->createToken()->willReturn(str_repeat('X', 32));
130
        $prophecy->messageAdded(Argument::type(Message::class));
131
132
        $user = $prophecy->reveal();
133
134
        return $user;
135
    }
136
137
    private function createMockUserAdmin(): User
138
    {
139
        $prophecy = $this->prophesize(User::class);
140
        $prophecy->getLogin()->willReturn('admin');
141
        $prophecy->getFirstName()->willReturn('Admin');
142
        $prophecy->getLastName()->willReturn('Istrator');
143
        $prophecy->getEmail()->willReturn('[email protected]');
144
        $prophecy->messageAdded(Argument::type(Message::class));
145
146
        $user = $prophecy->reveal();
147
148
        return $user;
149
    }
150
151
    private function createMockUserMinimal(): User
152
    {
153
        $prophecy = $this->prophesize(User::class);
154
        $prophecy->getLogin();
155
        $prophecy->getFirstName();
156
        $prophecy->getLastName();
157
        $prophecy->getEmail()->willReturn('[email protected]');
158
        $prophecy->createToken()->willReturn(str_repeat('X', 32));
159
        $prophecy->messageAdded(Argument::type(Message::class));
160
        $user = $prophecy->reveal();
161
162
        return $user;
163
    }
164
165
    private function assertMessage(Message $message, ?User $user, string $email, string $type, string $subject, ?string $variant = null): void
166
    {
167
        self::assertSame($type, $message->getType());
168
        self::assertSame($email, $message->getEmail());
169
        self::assertSame($user, $message->getRecipient());
170
        self::assertNull($message->getDateSent());
171
        self::assertSame($subject, $message->getSubject());
172
173
        $variant = $variant ? '-' . $variant : $variant;
174
        $expectedBody = 'tests/data/emails/' . str_replace('_', '-', $type . $variant) . '.html';
175
        $this->assertFile($expectedBody, $message->getBody());
176
    }
177
178
    /**
179
     * Custom assert that will not produce gigantic diff
180
     *
181
     * @param string $file
182
     * @param string $actual
183
     */
184
    private function assertFile(string $file, string $actual): void
185
    {
186
        // Log actual result for easier comparison with external diff tools
187
        $logFile = 'logs/' . $file;
188
        $dir = dirname($logFile);
189
        @mkdir($dir, 0777, true);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition for mkdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

189
        /** @scrutinizer ignore-unhandled */ @mkdir($dir, 0777, true);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
190
        file_put_contents($logFile, $actual);
191
192
        self::assertFileExists($file, 'Expected file must exist on disk, fix it with: cp ' . $logFile . ' ' . $file);
193
        $expected = file_get_contents($file);
194
195
        self::assertTrue($expected === $actual, 'File content does not match, compare with: meld ' . $file . ' ' . $logFile);
196
    }
197
198
    private function creatTransactionLine(Transaction $transaction, string $bookableName, string $balance): void
199
    {
200
        $bookable = new Bookable();
201
        $bookable->setName($bookableName);
202
203
        $transactionLine = new TransactionLine();
204
        $transactionLine->setTransaction($transaction);
205
        $transactionLine->setBookable($bookable);
206
        $transactionLine->setBalance($balance);
207
    }
208
}
209