|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace common\tests\unit\components; |
|
4
|
|
|
|
|
5
|
|
|
use \DateTime; |
|
6
|
|
|
use \DateTimeZone; |
|
7
|
|
|
use Yii; |
|
8
|
|
|
use common\components\Time; |
|
9
|
|
|
|
|
10
|
|
|
date_default_timezone_set('UTC'); |
|
11
|
|
|
|
|
12
|
|
|
/** |
|
13
|
|
|
* Time test |
|
14
|
|
|
*/ |
|
15
|
|
|
|
|
16
|
|
|
class TimeTest extends \Codeception\Test\Unit |
|
17
|
|
|
{ |
|
18
|
|
|
use \Codeception\Specify; |
|
19
|
|
|
|
|
20
|
|
|
public function setUp() |
|
21
|
|
|
{ |
|
22
|
|
|
$this->container = new \yii\di\Container; |
|
|
|
|
|
|
23
|
|
|
$this->container->set('common\interfaces\UserInterface', '\site\tests\_support\MockUser'); |
|
24
|
|
|
$this->container->set('common\interfaces\UserBehaviorInterface', '\site\tests\_support\MockUserBehavior'); |
|
25
|
|
|
$this->container->set('common\interfaces\QuestionInterface', '\site\tests\_support\MockQuestion'); |
|
26
|
|
|
|
|
27
|
|
|
$this->container->set('common\interfaces\TimeInterface', function () { |
|
28
|
|
|
return new \common\components\Time('America/Los_Angeles'); |
|
29
|
|
|
}); |
|
30
|
|
|
|
|
31
|
|
|
$this->time = $this->container->get('common\interfaces\TimeInterface'); |
|
|
|
|
|
|
32
|
|
|
|
|
33
|
|
|
parent::setUp(); |
|
34
|
|
|
} |
|
35
|
|
|
|
|
36
|
|
|
protected function tearDown() |
|
37
|
|
|
{ |
|
38
|
|
|
parent::tearDown(); |
|
39
|
|
|
} |
|
40
|
|
|
|
|
41
|
|
|
public function testNow() |
|
42
|
|
|
{ |
|
43
|
|
|
expect('now should return a \DateTime object', $this->assertInstanceOf(\DateTime::class, $this->time->now())); |
|
|
|
|
|
|
44
|
|
|
expect('now should return a \DateTime object with the correct timezone', $this->assertEquals('America/Los_Angeles', $this->time->now()->getTimezone()->getName())); |
|
|
|
|
|
|
45
|
|
|
expect('now should return a \DateTime object with the current date', $this->assertEquals($this->time->getLocalDate(), $this->time->now()->format('Y-m-d'))); |
|
|
|
|
|
|
46
|
|
|
} |
|
47
|
|
|
|
|
48
|
|
|
public function testGetLocalTime() |
|
49
|
|
|
{ |
|
50
|
|
|
$this->specify('getLocalTime should function correctly', function () { |
|
51
|
|
|
expect("getLocalTime should work with user's set time", $this->assertEquals($this->time->getLocalTime(), (new DateTime("now", new DateTimeZone("America/Los_Angeles")))->format("Y-m-d H:i:s"))); |
|
|
|
|
|
|
52
|
|
|
expect('getLocalTime should work with a custom timezone', $this->assertEquals($this->time->getLocalTime("UTC"), (new DateTime("now"))->format("Y-m-d H:i:s"))); |
|
|
|
|
|
|
53
|
|
|
}); |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
|
|
public function testConvertLocalToUTC() |
|
57
|
|
|
{ |
|
58
|
|
|
$this->specify('convertLocalToUTC should function correctly', function () { |
|
59
|
|
|
$la_tz = (new DateTime("now", new DateTimeZone("America/Los_Angeles")))->format("Y-m-d H:i:s"); |
|
60
|
|
|
|
|
61
|
|
|
expect('convertLocalToUTC should convert a Los Angeles tz to UTC with the included time', $this->assertEquals($this->time->convertLocalToUTC($la_tz), (new DateTime("now"))->format("Y-m-d H:i:s"))); |
|
|
|
|
|
|
62
|
|
|
expect('convertLocalToUTC should convert a Los Angeles tz to UTC without the included time', $this->assertEquals($this->time->convertLocalToUTC($la_tz, false), (new DateTime("now"))->format("Y-m-d"))); |
|
|
|
|
|
|
63
|
|
|
// with UTC |
|
64
|
|
|
$this->container->set('common\interfaces\TimeInterface', function () { |
|
65
|
|
|
return new \common\components\Time('UTC'); |
|
66
|
|
|
}); |
|
67
|
|
|
$time = $this->container->get('common\interfaces\TimeInterface'); |
|
68
|
|
|
|
|
69
|
|
|
$utc_tz = (new DateTime("now"))->format("Y-m-d H:i:s"); |
|
70
|
|
|
expect('convertLocalToUTC should convert a UTC tz correctly with the included time', $this->assertEquals($time->convertLocalToUTC($utc_tz), (new DateTime("now"))->format("Y-m-d H:i:s"))); |
|
|
|
|
|
|
71
|
|
|
expect('convertLocalToUTC should convert a UTC tz correctly without the included time', $this->assertEquals($time->convertLocalToUTC($utc_tz, false), (new DateTime("now"))->format("Y-m-d"))); |
|
|
|
|
|
|
72
|
|
|
}); |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
public function testConvertUTCToLocal() |
|
76
|
|
|
{ |
|
77
|
|
|
$this->specify('convertUTCToLocal should function correctly', function () { |
|
78
|
|
|
$utc_tz = (new DateTime("now"))->format("Y-m-d H:i:s"); |
|
79
|
|
|
|
|
80
|
|
|
expect('convertUTCToLocal should convert a UTC tz to Los Angeles with the included timezone', $this->assertEquals((new DateTime("now", new DateTimeZone("America/Los_Angeles")))->format(DateTime::ATOM), $this->time->convertUTCToLocal($utc_tz))); |
|
|
|
|
|
|
81
|
|
|
expect('convertUTCToLocal should convert a UTC tz to Los Angeles without the included timezone', $this->assertEquals($this->time->convertUTCToLocal($utc_tz, false), (new DateTime("now", new DateTimeZone("America/Los_Angeles")))->format("Y-m-d H:i:s"))); |
|
|
|
|
|
|
82
|
|
|
|
|
83
|
|
|
// with UTC |
|
84
|
|
|
$this->container->set('common\interfaces\TimeInterface', function () { |
|
85
|
|
|
return new \common\components\Time('UTC'); |
|
86
|
|
|
}); |
|
87
|
|
|
$time = $this->container->get('common\interfaces\TimeInterface'); |
|
88
|
|
|
$utc_tz = (new DateTime("now"))->format("Y-m-d H:i:s"); |
|
89
|
|
|
|
|
90
|
|
|
expect('convertLocalToUTC should convert a UTC tz correctly with the included time', $this->assertEquals($time->convertLocalToUTC($utc_tz), (new DateTime("now"))->format("Y-m-d H:i:s"))); |
|
|
|
|
|
|
91
|
|
|
expect('convertLocalToUTC should convert a UTC tz correctly without the included time', $this->assertEquals($time->convertLocalToUTC($utc_tz, false), (new DateTime("now"))->format("Y-m-d"))); |
|
|
|
|
|
|
92
|
|
|
}); |
|
93
|
|
|
} |
|
94
|
|
|
|
|
95
|
|
|
public function testGetLocalDate() |
|
96
|
|
|
{ |
|
97
|
|
|
$this->specify('getLocalDate should function correctly', function () { |
|
98
|
|
|
expect("getLocalDate should correctly get the user's local date", $this->assertEquals($this->time->getLocalDate(), (new DateTime("now", new DateTimeZone("America/Los_Angeles")))->format("Y-m-d"))); |
|
|
|
|
|
|
99
|
|
|
expect("getLocalDate should correctly get the local date of a specified timezone", $this->assertEquals($this->time->getLocalDate("UTC"), (new DateTime("now", new DateTimeZone("UTC")))->format("Y-m-d"))); |
|
|
|
|
|
|
100
|
|
|
}); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
public function testAlterLocalDate() |
|
104
|
|
|
{ |
|
105
|
|
|
$this->specify('alterLocalDate should function correctly', function() { |
|
106
|
|
|
expect('alterLocalDate should add one day to the local time', $this->assertEquals($this->time->alterLocalDate('2016-05-01 00:00:00', '+1 day'), (new DateTime("2016-05-01 00:00:00 +1 day"))->format("Y-m-d"))); |
|
|
|
|
|
|
107
|
|
|
expect('alterLocalDate should subtract one week to the local time and change the year correctly', $this->assertEquals($this->time->alterLocalDate('2016-01-01 04:03:00', '-1 week'), (new DateTime("2016-01-01 04:03:00 -1 week"))->format("Y-m-d"))); |
|
|
|
|
|
|
108
|
|
|
}); |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
public function testGetUTCBookends() |
|
112
|
|
|
{ |
|
113
|
|
|
$this->specify('getUTCBookends should function correctly', function() { |
|
114
|
|
|
expect('getUTCBookends should return false if there is a space in the time string', $this->assertFalse($this->time->getUTCBookends('2016-05-30 00:00:00'))); |
|
|
|
|
|
|
115
|
|
|
expect('getUTCBookends should return false if there is a space at the start of the time string', $this->assertFalse($this->time->getUTCBookends(' 2016-05-30 00:00:00'))); |
|
|
|
|
|
|
116
|
|
|
expect('getUTCBookends should return false if there is a space at the end of the time string', $this->assertFalse($this->time->getUTCBookends('2016-05-30 00:00:00 '))); |
|
|
|
|
|
|
117
|
|
|
expect('getUTCBookends should return UTC bookend times from the Los_Angeles tz', $this->assertEquals($this->time->getUTCBookends('2016-05-30'), ['2016-05-30 07:00:00', '2016-05-31 06:59:59'])); |
|
|
|
|
|
|
118
|
|
|
// with UTC |
|
119
|
|
|
$this->container->set('common\interfaces\TimeInterface', function () { |
|
120
|
|
|
return new \common\components\Time('UTC'); |
|
121
|
|
|
}); |
|
122
|
|
|
$time = $this->container->get('common\interfaces\TimeInterface'); |
|
123
|
|
|
expect('getUTCBookends should return UTC bookend times from UTC tz', $this->assertEquals($time->getUTCBookends('2016-05-30'), ['2016-05-30 00:00:00', '2016-05-30 23:59:59'])); |
|
|
|
|
|
|
124
|
|
|
}); |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
public function testParse() { |
|
128
|
|
|
$good = new DateTime('2016-05-05', new DateTimeZone('America/Los_Angeles')); |
|
129
|
|
|
expect('parse should accept a String time and verify it is in YYYY-MM-DD format, then return it as a \DateTime', $this->assertEquals($this->time->parse('2016-05-05'), $good)); |
|
|
|
|
|
|
130
|
|
|
|
|
131
|
|
|
$observer = $this |
|
132
|
|
|
->getMockBuilder("common\components\Time") |
|
133
|
|
|
->setConstructorArgs(['America/Los_Angeles']) |
|
134
|
|
|
->setMethods(['inBounds']) |
|
135
|
|
|
->getMock(); |
|
136
|
|
|
$observer->expects($this->once()) |
|
137
|
|
|
->method('inBounds') |
|
138
|
|
|
->with($this->equalTo($good)) |
|
139
|
|
|
->willReturn(true); |
|
140
|
|
|
expect('parse should return a \DateTime object if the date is in bounds', $this->assertInstanceOf(DateTime::class, $observer->parse('2016-05-05'))); |
|
|
|
|
|
|
141
|
|
|
expect('parse should return the default value (false) if the date itself is null', $this->assertFalse($this->time->parse(null))); |
|
|
|
|
|
|
142
|
|
|
|
|
143
|
|
|
$observer2 = $this |
|
144
|
|
|
->getMockBuilder("common\components\Time") |
|
145
|
|
|
->setConstructorArgs(['America/Los_Angeles']) |
|
146
|
|
|
->setMethods(['inBounds']) |
|
147
|
|
|
->getMock(); |
|
148
|
|
|
$observer2->expects($this->exactly(2)) |
|
149
|
|
|
->method('inBounds') |
|
150
|
|
|
->with($this->equalTo($good)) |
|
151
|
|
|
->willReturn(false); |
|
152
|
|
|
expect('parse should return the default value (false) if the date is not in bounds', $this->assertFalse($observer2->parse('2016-05-05'))); |
|
|
|
|
|
|
153
|
|
|
expect('parse should return the default value if the date is not in bounds', $this->assertEquals($observer2->now()->format('Y-m-d'), $observer2->parse('2016-05-05', $observer2->now())->format('Y-m-d'))); |
|
|
|
|
|
|
154
|
|
|
|
|
155
|
|
|
$this->specify('should all return false', function() { |
|
156
|
|
|
expect('parse should return false if the date itself is empty', $this->assertFalse($this->time->parse(''))); |
|
|
|
|
|
|
157
|
|
|
expect('parse should return false if the date itself is unacceptable or is in an unacceptable format', $this->assertFalse($this->time->parse('aaaa-aa-aa'))); |
|
|
|
|
|
|
158
|
|
|
expect('parse should return false if the date is not in bounds', $this->assertFalse($this->time->parse('aaaa-aa-aa'))); |
|
|
|
|
|
|
159
|
|
|
expect('parse should return false if the date itself is nonsensical', $this->assertFalse($this->time->parse('2018-22-44'))); |
|
|
|
|
|
|
160
|
|
|
}); |
|
161
|
|
|
|
|
162
|
|
|
$this->specify('should still work fine with other timezones', function() { |
|
163
|
|
|
$this->time->timezone = 'UTC'; |
|
164
|
|
|
$good = new DateTime('2016-05-05', new DateTimeZone('UTC')); |
|
165
|
|
|
expect('parse should accept a String time and verify it is in YYYY-MM-DD format, then return it as a \DateTime', $this->assertEquals($this->time->parse('2016-05-05'), $good)); |
|
|
|
|
|
|
166
|
|
|
|
|
167
|
|
|
expect('parse should return false if the date itself is empty', $this->assertFalse($this->time->parse(''))); |
|
|
|
|
|
|
168
|
|
|
expect('parse should return false if the date itself is unacceptable or is in an unacceptable format', $this->assertFalse($this->time->parse('aaaa-aa-aa'))); |
|
|
|
|
|
|
169
|
|
|
expect('parse should return false if the date is not in bounds', $this->assertFalse($this->time->parse('aaaa-aa-aa'))); |
|
|
|
|
|
|
170
|
|
|
expect('parse should return false if the date itself is nonsensical', $this->assertFalse($this->time->parse('2018-22-44'))); |
|
|
|
|
|
|
171
|
|
|
}); |
|
172
|
|
|
|
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
public function testInBounds() { |
|
176
|
|
|
|
|
177
|
|
|
$dt = new DateTime('2016-05-05'); |
|
178
|
|
|
expect('a sensible date should be in bounds', $this->assertTrue($this->time->inBounds($dt))); |
|
|
|
|
|
|
179
|
|
|
|
|
180
|
|
|
$early = '0111-10-01'; |
|
181
|
|
|
$dt = new DateTime($early); |
|
182
|
|
|
$this->assertTrue($this->time::EARLIEST_DATE > $early); |
|
183
|
|
|
expect('a too-early date should be not in bounds', $this->assertFalse($this->time->inBounds($dt))); |
|
|
|
|
|
|
184
|
|
|
|
|
185
|
|
|
$tomorrow = new DateTime("now + 1 day", new DateTimeZone('America/Los_Angeles')); |
|
186
|
|
|
expect('tomorrow\'s date should be not in bounds', $this->assertFalse($this->time->inBounds($tomorrow))); |
|
|
|
|
|
|
187
|
|
|
|
|
188
|
|
|
$dt = new DateTime('2016-05-05 05:14:22'); |
|
189
|
|
|
expect('different formats of sensible dates should be in bounds', $this->assertTrue($this->time->inBounds($dt))); |
|
|
|
|
|
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
public function testValidate() { |
|
193
|
|
|
expect('validate should return the local date by default', $this->assertEquals($this->time->validate(), $this->time->now()->format('Y-m-d'))); |
|
|
|
|
|
|
194
|
|
|
expect('validate should return same date string if given a valid format', $this->assertEquals($this->time->validate('2015-02-02'), '2015-02-02')); |
|
|
|
|
|
|
195
|
|
|
expect('validate should return the local date if given an invalid format', $this->assertEquals($this->time->validate('definitelynotadate9000'), $this->time->now()->format('Y-m-d'))); |
|
|
|
|
|
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
public function testGetDateTimesInPeriod() { |
|
199
|
|
|
expect('getDateTImesInPeriod should return an a \DatePeriod', $this->assertInstanceOf(\DatePeriod::class, $this->time->getDateTimesInPeriod())); |
|
|
|
|
|
|
200
|
|
|
expect('getDateTimesInPeriod should return a 30 day period by default', $this->assertCount(30, $this->time->getDateTimesInPeriod())); |
|
|
|
|
|
|
201
|
|
|
expect('getDateTimesInPeriod should return an arbitrary period length if supplied', $this->assertCount(42, $this->time->getDateTimesInPeriod(42))); |
|
|
|
|
|
|
202
|
|
|
} |
|
203
|
|
|
} |
|
204
|
|
|
|