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 testGetLocalTime() |
42
|
|
|
{ |
43
|
|
|
$this->specify('getLocalTime should function correctly', function () { |
44
|
|
|
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"))); |
|
|
|
|
45
|
|
|
expect('getLocalTime should work with a custom timezone', $this->assertEquals($this->time->getLocalTime("UTC"), (new DateTime("now"))->format("Y-m-d H:i:s"))); |
|
|
|
|
46
|
|
|
}); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
public function testConvertLocalToUTC() |
50
|
|
|
{ |
51
|
|
|
$this->specify('convertLocalToUTC should function correctly', function () { |
52
|
|
|
$la_tz = (new DateTime("now", new DateTimeZone("America/Los_Angeles")))->format("Y-m-d H:i:s"); |
53
|
|
|
|
54
|
|
|
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"))); |
|
|
|
|
55
|
|
|
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"))); |
|
|
|
|
56
|
|
|
// with UTC |
57
|
|
|
$this->container->set('common\interfaces\TimeInterface', function () { |
58
|
|
|
return new \common\components\Time('UTC'); |
59
|
|
|
}); |
60
|
|
|
$time = $this->container->get('common\interfaces\TimeInterface'); |
61
|
|
|
|
62
|
|
|
$utc_tz = (new DateTime("now"))->format("Y-m-d H:i:s"); |
63
|
|
|
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"))); |
|
|
|
|
64
|
|
|
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"))); |
|
|
|
|
65
|
|
|
}); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
public function testConvertUTCToLocal() |
69
|
|
|
{ |
70
|
|
|
$this->specify('convertUTCToLocal should function correctly', function () { |
71
|
|
|
$utc_tz = (new DateTime("now"))->format("Y-m-d H:i:s"); |
72
|
|
|
|
73
|
|
|
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))); |
|
|
|
|
74
|
|
|
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"))); |
|
|
|
|
75
|
|
|
|
76
|
|
|
// with UTC |
77
|
|
|
$this->container->set('common\interfaces\TimeInterface', function () { |
78
|
|
|
return new \common\components\Time('UTC'); |
79
|
|
|
}); |
80
|
|
|
$time = $this->container->get('common\interfaces\TimeInterface'); |
81
|
|
|
$utc_tz = (new DateTime("now"))->format("Y-m-d H:i:s"); |
82
|
|
|
|
83
|
|
|
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"))); |
|
|
|
|
84
|
|
|
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"))); |
|
|
|
|
85
|
|
|
}); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
public function testGetLocalDate() |
89
|
|
|
{ |
90
|
|
|
$this->specify('getLocalDate should function correctly', function () { |
91
|
|
|
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"))); |
|
|
|
|
92
|
|
|
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"))); |
|
|
|
|
93
|
|
|
}); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
public function testAlterLocalDate() |
97
|
|
|
{ |
98
|
|
|
$this->specify('alterLocalDate should function correctly', function() { |
99
|
|
|
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"))); |
|
|
|
|
100
|
|
|
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"))); |
|
|
|
|
101
|
|
|
}); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
public function testGetUTCBookends() |
105
|
|
|
{ |
106
|
|
|
$this->specify('getUTCBookends should function correctly', function() { |
107
|
|
|
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'))); |
|
|
|
|
108
|
|
|
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'))); |
|
|
|
|
109
|
|
|
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 '))); |
|
|
|
|
110
|
|
|
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'])); |
|
|
|
|
111
|
|
|
// with UTC |
112
|
|
|
$this->container->set('common\interfaces\TimeInterface', function () { |
113
|
|
|
return new \common\components\Time('UTC'); |
114
|
|
|
}); |
115
|
|
|
$time = $this->container->get('common\interfaces\TimeInterface'); |
116
|
|
|
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'])); |
|
|
|
|
117
|
|
|
}); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
public function testParse() { |
121
|
|
|
$good = new DateTime('2016-05-05', new DateTimeZone('America/Los_Angeles')); |
122
|
|
|
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)); |
|
|
|
|
123
|
|
|
|
124
|
|
|
$observer = $this |
125
|
|
|
->getMockBuilder("common\components\Time") |
126
|
|
|
->setConstructorArgs(['America/Los_Angeles']) |
127
|
|
|
->setMethods(['inBounds']) |
128
|
|
|
->getMock(); |
129
|
|
|
$observer->expects($this->once()) |
130
|
|
|
->method('inBounds') |
131
|
|
|
->with($this->equalTo($good)) |
132
|
|
|
->willReturn(true); |
133
|
|
|
expect('parse should return a \DateTime object if the date is in bounds', $this->assertInstanceOf(DateTime::class, $observer->parse('2016-05-05'))); |
|
|
|
|
134
|
|
|
|
135
|
|
|
$observer2 = $this |
136
|
|
|
->getMockBuilder("common\components\Time") |
137
|
|
|
->setConstructorArgs(['America/Los_Angeles']) |
138
|
|
|
->setMethods(['inBounds']) |
139
|
|
|
->getMock(); |
140
|
|
|
$observer2->expects($this->once()) |
141
|
|
|
->method('inBounds') |
142
|
|
|
->with($this->equalTo($good)) |
143
|
|
|
->willReturn(false); |
144
|
|
|
expect('parse should return false if the date is not in bounds', $this->assertFalse($observer2->parse('2016-05-05'))); |
|
|
|
|
145
|
|
|
|
146
|
|
|
$this->specify('should all return false', function() { |
147
|
|
|
expect('parse should return false if the date itself is empty', $this->assertFalse($this->time->parse(''))); |
|
|
|
|
148
|
|
|
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'))); |
|
|
|
|
149
|
|
|
expect('parse should return false if the date is not in bounds', $this->assertFalse($this->time->parse('aaaa-aa-aa'))); |
|
|
|
|
150
|
|
|
expect('parse should return false if the date itself is nonsensical', $this->assertFalse($this->time->parse('2018-22-44'))); |
|
|
|
|
151
|
|
|
}); |
152
|
|
|
|
153
|
|
|
$this->specify('should still work fine with other timezones', function() { |
154
|
|
|
$this->time->timezone = 'UTC'; |
155
|
|
|
$good = new DateTime('2016-05-05', new DateTimeZone('UTC')); |
156
|
|
|
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)); |
|
|
|
|
157
|
|
|
|
158
|
|
|
expect('parse should return false if the date itself is empty', $this->assertFalse($this->time->parse(''))); |
|
|
|
|
159
|
|
|
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'))); |
|
|
|
|
160
|
|
|
expect('parse should return false if the date is not in bounds', $this->assertFalse($this->time->parse('aaaa-aa-aa'))); |
|
|
|
|
161
|
|
|
expect('parse should return false if the date itself is nonsensical', $this->assertFalse($this->time->parse('2018-22-44'))); |
|
|
|
|
162
|
|
|
}); |
163
|
|
|
|
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
public function testinBounds() { |
167
|
|
|
|
168
|
|
|
$dt = new DateTime('2016-05-05'); |
169
|
|
|
expect('a sensible date should be in bounds', $this->assertTrue($this->time->inBounds($dt))); |
|
|
|
|
170
|
|
|
|
171
|
|
|
$early = '0111-10-01'; |
172
|
|
|
$dt = new DateTime($early); |
173
|
|
|
$this->assertTrue($this->time::EARLIEST_DATE > $early); |
174
|
|
|
expect('a too-early date should be not in bounds', $this->assertFalse($this->time->inBounds($dt))); |
|
|
|
|
175
|
|
|
|
176
|
|
|
$tomorrow = new DateTime("now + 1 day", new DateTimeZone('America/Los_Angeles')); |
177
|
|
|
expect('tomorrow\'s date should be not in bounds', $this->assertFalse($this->time->inBounds($tomorrow))); |
|
|
|
|
178
|
|
|
|
179
|
|
|
$dt = new DateTime('2016-05-05 05:14:22'); |
180
|
|
|
expect('different formats of sensible dates should be in bounds', $this->assertTrue($this->time->inBounds($dt))); |
|
|
|
|
181
|
|
|
} |
182
|
|
|
} |
183
|
|
|
|