Failed Conditions
Push — master ( cbed7a...eb0d0f )
by Michel
03:05 queued 10s
created

testExceptionThrownOnUserNotFound()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace TogglJiraTest\Service;
5
6
use AJT\Toggl\TogglClient;
7
use DateTimeImmutable;
8
use Mockery\Exception;
9
use Mockery\MockInterface;
10
use PHPUnit\Framework\TestCase;
11
use Psr\Log\LoggerInterface;
12
use RuntimeException;
13
use TogglJira\Entity\WorkLogEntry;
14
use TogglJira\Hydrator\WorkLogHydrator;
15
use TogglJira\Jira\Api;
16
use TogglJira\Service\SyncService;
17
18
class SyncServiceTest extends TestCase
19
{
20
    /**
21
     * @var MockInterface
22
     */
23
    private $apiMock;
24
25
    /**
26
     * @var MockInterface
27
     */
28
    private $togglClientMock;
29
30
    /**
31
     * @var MockInterface
32
     */
33
    private $hydratorMock;
34
35
    /**
36
     * @var MockInterface
37
     */
38
    private $loggerMock;
39
40
    /**
41
     * @var SyncService
42
     */
43
    private $service;
44
45
    /**
46
     * @return void
47
     */
48
    public function setUp(): void
49
    {
50
       \ Mockery::getConfiguration()->allowMockingNonExistentMethods(true);
51
52
        $this->apiMock = \Mockery::mock(Api::class);
53
        $this->togglClientMock = \Mockery::mock(TogglClient::class);
54
        $this->hydratorMock = \Mockery::mock(WorkLogHydrator::class);
55
        $this->loggerMock = \Mockery::mock(LoggerInterface::class);
56
57
        $this->service = new SyncService($this->apiMock, $this->togglClientMock, $this->hydratorMock, 'D-Va');
58
59
        $this->service->setLogger($this->loggerMock);
60
    }
61
62
    /**
63
     * @return void
64
     * @throws \Exception
65
     */
66
    public function testSync(): void
67
    {
68
        $dateTime = '2017-04-15T23:35:00.000+0200';
69
70
        $timeEntries = [
71
            [
72
                'description' => 'SLR-76 Soldier 76',
73
                'duration' => 76,
74
                'comment' => 'Soldier 76, reporting for duty',
75
                'start' => '2018-02-15'
76
            ],
77
            [
78
                'description' => 'DVA-76 D-Va',
79
                'duration' => 42,
80
                'comment' => 'Nerf this!',
81
                'start' => '2018-02-15'
82
            ],
83
        ];
84
85
        $this->togglClientMock->shouldReceive('getTimeEntries')
86
            ->with(['start_date' => $dateTime])
87
            ->andReturn($timeEntries);
88
89
        $workLogEntry = new WorkLogEntry();
90
        $workLogEntry->setIssueID('SLR-76');
91
        $workLogEntry->setSpentOn(new DateTimeImmutable($dateTime));
92
        $workLogEntry->setComment('SLR-76');
93
        $workLogEntry->setTimeSpent(76);
94
95
        $this->hydratorMock->shouldReceive('hydrate')->andReturn($workLogEntry);
96
97
        $user = [
98
            'accountId' => 'D-Va'
99
        ];
100
101
        $this->apiMock->shouldReceive('getUser')->andReturn($user);
102
103
        $this->apiMock->shouldReceive('addWorkLogEntry')->with(
104
            $workLogEntry->getIssueID(),
105
            $workLogEntry->getTimeSpent(),
106
            'D-Va',
107
            $workLogEntry->getComment(),
108
            $dateTime
109
        );
110
111
        $this->apiMock->shouldReceive('addWorkLogEntry')->with(
112
            $workLogEntry->getIssueID(),
113
            $workLogEntry->getTimeSpent() * 2,
114
            'D-Va',
115
            $workLogEntry->getComment(),
116
            $dateTime
117
        );
118
119
        $this->loggerMock
120
            ->shouldReceive('info')
121
            ->with("Found time entry for issue {$workLogEntry->getIssueID()}");
122
123
        $this->loggerMock
124
            ->shouldReceive('info')
125
            ->with("Saved worklog entry for issue {$workLogEntry->getIssueID()}");
126
127
        $this->loggerMock
128
            ->shouldReceive('info')
129
            ->with("Added time spent for issue {$workLogEntry->getIssueID()}");
130
131
        $this->loggerMock->shouldReceive('info')->with('All done for today, time to go home!');
132
133
        $this->service->sync($dateTime);
134
    }
135
136
    /**
137
     * @return void
138
     * @throws \Exception
139
     */
140
    public function testExceptionOnTogglError(): void
141
    {
142
        $dateTime = '2017-04-15T23:35:00+02:00';
143
144
        $user = [
145
            'accountId' => 'D-Va'
146
        ];
147
148
        $this->apiMock->shouldReceive('getUser')->andReturn($user);
149
150
        $this->togglClientMock->shouldReceive('getTimeEntries')
151
            ->with(['start_date' => $dateTime])
152
            ->andThrow(\Exception::class, 'Nerf this!');
153
154
        $this->loggerMock->shouldReceive('error')
155
            ->with('Failed to get time entries from Toggl: Nerf this!', \Mockery::any());
156
157
        $this->service->sync($dateTime);
158
    }
159
160
    /**
161
     * @return void
162
     * @throws \Exception
163
     */
164
    public function testSyncWithInvalidTimeEntries(): void
165
    {
166
        $dateTime = '2017-04-15T23:35:00+02:00';
167
168
        $timeEntries = [
169
            [
170
                'description' => 'SLR76 Soldier 76',
171
                'duration' => 76,
172
                'comment' => 'Soldier 76, not reporting for duty',
173
                'start' => '2018-02-15'
174
            ],
175
            [
176
                'description' => 'SLR-76 Soldier 76',
177
                'duration' => -1,
178
                'comment' => 'Soldier 76, not reporting for duty',
179
                'start' => '2018-02-15'
180
            ],
181
        ];
182
183
        $this->togglClientMock->shouldReceive('getTimeEntries')
184
            ->with(['start_date' => $dateTime])
185
            ->andReturn($timeEntries);
186
187
        $user = [
188
            'accountId' => 'D-Va'
189
        ];
190
191
        $this->apiMock->shouldReceive('getUser')->andReturn($user);
192
193
        $this->loggerMock->shouldReceive('warning'
194
        )->with('Could not parse issue string, cannot link to Jira');
195
196
        $this->loggerMock->shouldReceive('info')
197
            ->with('0 seconds, or timer still running for SLR-76, skipping');
198
199
        $this->loggerMock->shouldReceive('info')->with('All done for today, time to go home!');
200
201
        $this->service->sync($dateTime);
202
    }
203
204
    /**
205
     * @return void
206
     * @throws \Exception
207
     */
208
    public function testSyncJiraException(): void
209
    {
210
        $dateTime = '2017-04-15T23:35:00.000+0200';
211
212
        $user = [
213
            'accountId' => 'D-Va'
214
        ];
215
216
        $this->apiMock->shouldReceive('getUser')->andReturn($user);
217
218
        $timeEntries = [
219
            [
220
                'description' => 'SLR-76 Soldier 76',
221
                'duration' => 76,
222
                'comment' => 'Soldier 76, reporting for duty',
223
                'start' => '2018-02-15'
224
            ],
225
            [
226
                'description' => 'DVA-76 D-Va',
227
                'duration' => 42,
228
                'comment' => 'Nerf this!',
229
                'start' => '2018-02-15'
230
            ],
231
        ];
232
233
        $this->togglClientMock->shouldReceive('getTimeEntries')
234
            ->with(['start_date' => $dateTime])
235
            ->andReturn($timeEntries);
236
237
        $workLogEntry = new WorkLogEntry();
238
        $workLogEntry->setIssueID('SLR-76');
239
        $workLogEntry->setSpentOn(new DateTimeImmutable($dateTime));
240
        $workLogEntry->setComment('SLR-76');
241
        $workLogEntry->setTimeSpent(76);
242
243
        $this->hydratorMock->shouldReceive('hydrate')->andReturn($workLogEntry);
244
245
        $this->apiMock->shouldReceive('addWorkLogEntry')->with(
246
            $workLogEntry->getIssueID(),
247
            $workLogEntry->getTimeSpent() * 2,
248
            'D-Va',
249
            $workLogEntry->getComment(),
250
            $dateTime
251
        )->andThrow(\Exception::class, 'Nerf this!');
252
253
        $this->loggerMock
254
            ->shouldReceive('info')
255
            ->with("Found time entry for issue {$workLogEntry->getIssueID()}");
256
257
        $this->loggerMock
258
            ->shouldReceive('error')
259
            ->with("Could not add worklog entry: Nerf this!", \Mockery::any());
260
261
        $this->loggerMock
262
            ->shouldReceive('info')
263
            ->with("Added time spent for issue {$workLogEntry->getIssueID()}");
264
265
        $this->loggerMock->shouldReceive('info')->with('All done for today, time to go home!');
266
267
        $this->service->sync($dateTime);
268
    }
269
270
    /**
271
     * @expectedException RuntimeException
272
     * @expectedExceptionMessage User with username D-Va not found
273
     * @return void
274
     */
275
    public function testExceptionThrownOnUserNotFound(): void
276
    {
277
        $dateTime = '2017-04-15T23:35:00.000+0200';
278
        $this->apiMock->shouldReceive('getUser')->andReturn([]);
279
280
        $this->service->sync($dateTime);
281
    }
282
283
    public function tearDown()/* The :void return type declaration that should be here would cause a BC issue */
284
    {
285
        if ($container = \Mockery::getContainer()) {
286
            $this->addToAssertionCount($container->mockery_getExpectationCount());
287
        }
288
    }
289
}
290