Passed
Branch master (73f5a3)
by Toni
02:45
created

cancel_WhenEventIsNotScheduled_ShouldThrowException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Adlogix\EventSchedulerTest;
6
7
use DateTime;
8
use DateTimeImmutable;
9
use DateTimeInterface;
10
use PHPUnit\Framework\TestCase;
11
use PHPUnit_Framework_MockObject_MockObject;
12
use Adlogix\EventScheduler\BasicEvent;
13
use Adlogix\EventScheduler\DateRange\DateRange;
14
use Adlogix\EventScheduler\Exception\NotFoundEventOccurrenceException;
15
use Adlogix\EventScheduler\Exception\NotScheduledEventException;
16
use Adlogix\EventScheduler\SchedulableEvent;
17
use Adlogix\EventScheduler\Scheduler;
18
use Adlogix\EventScheduler\TemporalExpression\TemporalExpressionInterface;
19
use Adlogix\EventSchedulerTest\Fixtures\TemporalExpression\AlwaysOccurringTemporalExpression;
20
use Adlogix\EventSchedulerTest\Fixtures\TemporalExpression\NeverOccurringTemporalExpression;
21
use Traversable;
22
23
class SchedulerTest extends TestCase
24
{
25
    /**
26
     * @test
27
     */
28
    public function cancel_WhenEventIsNotScheduled_ShouldThrowException()
29
    {
30
        $anyEvent = new BasicEvent('some_event');
31
        $anyTemporalExpression = $this->getTemporalExpression();
32
        $anySchedulableEvent = new SchedulableEvent($anyEvent, $anyTemporalExpression);
33
        $scheduler = new Scheduler();
34
35
        $this->expectException(NotScheduledEventException::class);
36
        $scheduler->cancel($anySchedulableEvent);
37
    }
38
39
    /**
40
     * @test
41
     */
42
    public function cancel_WhenEventIsScheduled_ShouldNoLongerScheduled()
43
    {
44
        $anyEvent = new BasicEvent('some_event');
45
        $anyTemporalExpression = $this->getTemporalExpression();
46
        $scheduler = new Scheduler();
47
        $schedulableEvent = $scheduler->schedule($anyEvent, $anyTemporalExpression);
48
49
        $scheduler->cancel($schedulableEvent);
50
51
        $this->assertThat($scheduler->isScheduled($anyEvent), $this->isFalse());
52
    }
53
54
    /**
55
     * @test
56
     */
57
    public function isOccurring_WhenEventIsNotScheduled_ShouldReturnFalse()
58
    {
59
        $anyEvent = new BasicEvent('some_event');
60
        $scheduler = new Scheduler();
61
62
        $isOccurring = $scheduler->isOccurring($anyEvent, new DateTime());
63
64
        $this->assertThat($isOccurring, $this->isFalse());
65
    }
66
67
    /**
68
     * @test
69
     */
70
    public function isOccurring_WhenEventIsOccurring_ShouldReturnTrue()
71
    {
72
        $anyEvent = new BasicEvent('some_event');
73
        $anyTemporalExpression = new AlwaysOccurringTemporalExpression();
74
        $scheduler = new Scheduler();
75
        $scheduler->schedule($anyEvent, $anyTemporalExpression);
76
77
        $isOccurring = $scheduler->isOccurring($anyEvent, new DateTime());
78
79
        $this->assertThat($isOccurring, $this->isTrue());
80
    }
81
82
    /**
83
     * @test
84
     */
85
    public function isOccurring_WhenEventIsNotOccurring_ShouldReturnFalse()
86
    {
87
        $anyEvent = new BasicEvent('some_event');
88
        $anyTemporalExpression = new NeverOccurringTemporalExpression();
89
        $scheduler = new Scheduler();
90
        $scheduler->schedule($anyEvent, $anyTemporalExpression);
91
92
        $isOccurring = $scheduler->isOccurring($anyEvent, new DateTime());
93
94
        $this->assertThat($isOccurring, $this->isFalse());
95
    }
96
97
    /**
98
     * @test
99
     */
100
    public function eventsForDate_WhenSomeEventsScheduledAtSameDate_ShouldReturnATraversableWithScheduledEvents()
101
    {
102
        $anyDate = new DateTime();
103
104
        $scheduler = new Scheduler();
105
        $exprStub = $this->getTemporalExpression();
106
        $exprStub
107
            ->method('includes')
0 ignored issues
show
Bug introduced by
The method method() does not exist on Adlogix\EventScheduler\T...oralExpressionInterface. ( Ignorable by Annotation )

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

107
            ->/** @scrutinizer ignore-call */ 
108
              method('includes')

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...
108
            ->will($this->returnValue(true));
109
110
        $events = [];
111
        for ($i = 0; $i < 3; $i++) {
112
            $anyEvent = new BasicEvent('some_event');
113
            $anyTemporalExpression = $this->getTemporalExpression();
114
115
            $scheduler->schedule($anyEvent, $anyTemporalExpression);
116
117
            $events[] = $anyEvent;
118
        }
119
120
        $scheduledEvents = $scheduler->eventsForDate($anyDate);
121
        $this->assertInstanceOf(Traversable::class, $scheduledEvents);
122
123
        foreach ($scheduledEvents as $key => $scheduledEvent) {
124
            $this->assertSame($events[$key], $scheduledEvent);
125
        }
126
    }
127
128
    /**
129
     * @test
130
     */
131
    public function retrieveDates_WhenEventIsOccurringInProvidedRange_ShouldReturnATraversableWithOccurringDates()
132
    {
133
        $anyEvent = new BasicEvent('some_event');
134
135
        $startDate = new DateTimeImmutable('2015-03-01');
136
        $endDate = new DateTimeImmutable('2015-03-30');
137
        $range = new DateRange($startDate, $endDate);
138
139
        $occurringDates = [
140
            new DateTimeImmutable('2015-03-12'),
141
            new DateTimeImmutable('2015-03-15'),
142
        ];
143
144
        $scheduler = new Scheduler();
145
146
        $exprStub = $this->getTemporalExpressionIncludingDates($occurringDates);
147
148
        $scheduler->schedule($anyEvent, $exprStub);
149
150
        $dates = $scheduler->dates($anyEvent, $range);
151
        $this->assertInstanceOf(Traversable::class, $dates);
152
153
        foreach ($dates as $key => $date) {
154
            $this->assertInstanceOf(DateTimeImmutable::class, $date);
155
            $this->assertEquals($occurringDates[$key], $date);
156
        }
157
    }
158
159
    /**
160
     * @test
161
     */
162
    public function retrieveNextEventOccurrence_WhenEventWillOccurAgain_ShouldReturnNextDate()
163
    {
164
        $anyEvent = new BasicEvent('some_event');
165
166
        $occurringDates = [
167
            new DateTime('2015-10-11'),
168
            new DateTime('2015-10-15'),
169
        ];
170
        $expectedDate = new DateTimeImmutable('2015-10-11');
171
172
        $dateRange = new DateRange(
173
            new DateTimeImmutable('2015-09-01'),
174
            new DateTimeImmutable('2015-11-01')
175
        );
176
        $scheduler = new Scheduler();
177
178
        $exprStub = $this->getTemporalExpressionIncludingDates($occurringDates);
179
180
        $scheduler->schedule($anyEvent, $exprStub);
181
182
        $date = $scheduler->nextOccurrence($anyEvent, $dateRange);
183
184
        $this->assertInstanceOf(DateTimeImmutable::class, $date);
185
        $this->assertEquals($expectedDate, $date);
186
    }
187
188
    /**
189
     * @test
190
     */
191
    public function retrieveNextEventOccurrence_WhenEventWillOccurAgain_ShouldThrowException()
192
    {
193
        $anyEvent = new BasicEvent('some_event');
194
195
        $occurringDates = [];
196
197
        $dateRange = new DateRange(
198
            new DateTimeImmutable('2014-03-01'),
199
            new DateTimeImmutable('2014-04-01')
200
        );
201
        $scheduler = new Scheduler();
202
203
        $exprStub = $this->getTemporalExpressionIncludingDates($occurringDates);
204
205
        $scheduler->schedule($anyEvent, $exprStub);
206
207
        $this->expectException(NotFoundEventOccurrenceException::class);
208
        $scheduler->nextOccurrence($anyEvent, $dateRange);
209
    }
210
211
    /**
212
     * @test
213
     */
214
    public function retrieveNextEventOccurrence_WhenThereAreNoNextOccurence_ShouldThrowException()
215
    {
216
        $anyEvent = new BasicEvent('some_event');
217
        $dateRange = new DateRange(
218
            new DateTimeImmutable('2014-03-01'),
219
            new DateTimeImmutable('2014-06-01')
220
        );
221
222
        $scheduler = new Scheduler();
223
224
        $this->expectException(NotFoundEventOccurrenceException::class);
225
        $scheduler->nextOccurrence($anyEvent, $dateRange);
226
    }
227
228
    /**
229
     * @test
230
     */
231
    public function retrievePreviousEventOccurrence_WhenEventHasAlreadyOccurred_ShouldReturnPreviousDate()
232
    {
233
        $anyEvent = new BasicEvent('some_event');
234
235
        $occurringDates = [
236
            new DateTime('2014-10-12'),
237
            new DateTime('2014-10-15'),
238
        ];
239
        $expectedDate = new DateTimeImmutable('2014-10-15');
240
241
        $dateRange = new DateRange(
242
            new DateTimeImmutable('2014-09-01'),
243
            new DateTimeImmutable('2014-11-01')
244
        );
245
        $scheduler = new Scheduler();
246
247
        $exprStub = $this->getTemporalExpressionIncludingDates($occurringDates);
248
249
        $scheduler->schedule($anyEvent, $exprStub);
250
251
        $date = $scheduler->previousOccurrence($anyEvent, $dateRange);
252
253
        $this->assertInstanceOf(DateTimeImmutable::class, $date);
254
        $this->assertEquals($expectedDate, $date);
255
    }
256
257
    /**
258
     * @test
259
     */
260
    public function retrievePreviousEventOccurrence_WhenThereAreNoPreviousOccurence_ShouldThrowException()
261
    {
262
        $anyEvent = new BasicEvent('some_event');
263
264
        $dateRange = new DateRange(
265
            new DateTimeImmutable('2014-03-01'),
266
            new DateTimeImmutable('2014-04-01')
267
        );
268
        $scheduler = new Scheduler();
269
270
        $this->expectException(NotFoundEventOccurrenceException::class);
271
        $scheduler->previousOccurrence($anyEvent, $dateRange);
272
    }
273
274
    /**
275
     * @return PHPUnit_Framework_MockObject_MockObject|TemporalExpressionInterface
276
     */
277
    private function getTemporalExpression(): TemporalExpressionInterface
278
    {
279
        return $this->createMock(TemporalExpressionInterface::class);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->createMock...essionInterface::class) returns the type PHPUnit\Framework\MockObject\MockObject which is incompatible with the type-hinted return Adlogix\EventScheduler\T...oralExpressionInterface.
Loading history...
280
    }
281
282
    /**
283
     * @param $includedDates
284
     * @return PHPUnit_Framework_MockObject_MockObject|TemporalExpressionInterface
285
     */
286
    private function getTemporalExpressionIncludingDates($includedDates): TemporalExpressionInterface
287
    {
288
        $exprStub = $this->getTemporalExpression();
289
        $exprStub
290
            ->method('includes')
291
            ->will($this->returnCallback(function (DateTimeInterface $date) use ($includedDates) {
292
                return in_array($date, $includedDates);
293
            }));
294
295
        return $exprStub;
296
    }
297
}
298