CRM-12193 - Validate JSON documents
[civicrm-core.git] / tests / phpunit / CRM / Core / CommunityMessagesTest.php
CommitLineData
ecbe1139
TO
1<?php
2
3/*
4 +--------------------------------------------------------------------+
5 | CiviCRM version 4.3 |
6 +--------------------------------------------------------------------+
7 | Copyright CiviCRM LLC (c) 2004-2013 |
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
10 | |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public |
21 | License and the CiviCRM Licensing Exception along |
22 | with this program; if not, contact CiviCRM LLC |
23 | at info[AT]civicrm[DOT]org. If you have questions about the |
24 | GNU Affero General Public License or the licensing of CiviCRM, |
25 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
26 +--------------------------------------------------------------------+
27*/
28
29
30require_once 'CiviTest/CiviUnitTestCase.php';
31class CRM_Core_CommunityMessagesTest extends CiviUnitTestCase {
32
33 /**
34 * @var CRM_Utils_Cache_Interface
35 */
36 protected $cache;
37
38 /**
39 * @var array list of possible web responses
40 */
41 protected $webResponses;
42
43 public function setUp() {
44 parent::setUp();
45
46 $this->cache = new CRM_Utils_Cache_Arraycache(array());
47
48 $this->webResponses = array(
49 'http-error' => array(
50 CRM_Utils_HttpClient::STATUS_DL_ERROR,
51 NULL
52 ),
53 'bad-json' => array(
54 CRM_Utils_HttpClient::STATUS_OK,
55 '<html>this is not json!</html>'
56 ),
8bfc3cb1
TO
57 'invalid-ttl-document' => array(
58 CRM_Utils_HttpClient::STATUS_OK,
59 json_encode(array(
60 'ttl' => 'z', // not an integer!
61 'retry' => 'z', // not an integer!
62 'messages' => array(
63 array(
64 'markup' => '<h1>Invalid document</h1>',
65 ),
66 ),
67 ))
68 ),
ecbe1139
TO
69 'hello-world' => array(
70 CRM_Utils_HttpClient::STATUS_OK,
71 json_encode(array(
72 'ttl' => 600,
73 'retry' => 600,
74 'messages' => array(
75 array(
76 'markup' => '<h1>Hello world</h1>',
77 ),
78 ),
79 ))
80 ),
81 'salut-a-tout' => array(
82 CRM_Utils_HttpClient::STATUS_OK,
83 json_encode(array(
84 'ttl' => 600,
85 'retry' => 600,
86 'messages' => array(
87 array(
88 'markup' => '<h1>Salut a tout</h1>',
89 ),
90 ),
91 ))
92 ),
93 );
94 }
95
96 public function tearDown() {
97 parent::tearDown();
98 CRM_Utils_Time::resetTime();
99 }
100
e8977170
TO
101 public function testGetDocument_disabled() {
102 $communityMessages = new CRM_Core_CommunityMessages(
103 $this->cache,
104 $this->expectNoHttpRequest(),
105 FALSE
106 );
107 $doc = $communityMessages->getDocument();
108 $this->assertTrue(NULL === $doc);
109 }
110
ecbe1139
TO
111 /**
112 * Download a document; after the set expiration period, download again.
113 */
e8977170 114 public function testGetDocument_NewOK_CacheOK_UpdateOK() {
ecbe1139
TO
115 // first try, good response
116 CRM_Utils_Time::setTime('2013-03-01 10:00:00');
117 $communityMessages = new CRM_Core_CommunityMessages(
118 $this->cache,
119 $this->expectOneHttpRequest($this->webResponses['hello-world'])
120 );
121 $doc1 = $communityMessages->getDocument();
122 $this->assertEquals('<h1>Hello world</h1>', $doc1['messages'][0]['markup']);
123 $this->assertEquals(strtotime('2013-03-01 10:10:00'), $doc1['expires']);
124
125 // second try, $doc1 hasn't expired yet, so still use it
126 CRM_Utils_Time::setTime('2013-03-01 10:09:00');
127 $communityMessages = new CRM_Core_CommunityMessages(
128 $this->cache,
129 $this->expectNoHttpRequest()
130 );
131 $doc2 = $communityMessages->getDocument();
132 $this->assertEquals('<h1>Hello world</h1>', $doc2['messages'][0]['markup']);
133 $this->assertEquals(strtotime('2013-03-01 10:10:00'), $doc2['expires']);
134
135 // third try, $doc1 expired, update it
136 CRM_Utils_Time::setTime('2013-03-01 12:00:02'); // more than 2 hours later (DEFAULT_RETRY)
137 $communityMessages = new CRM_Core_CommunityMessages(
138 $this->cache,
139 $this->expectOneHttpRequest($this->webResponses['salut-a-tout'])
140 );
141 $doc3 = $communityMessages->getDocument();
142 $this->assertEquals('<h1>Salut a tout</h1>', $doc3['messages'][0]['markup']);
143 $this->assertEquals(strtotime('2013-03-01 12:10:02'), $doc3['expires']);
144 }
145
146 /**
147 * First download attempt fails. Store the NACK and retry after
148 * the default time period (DEFAULT_RETRY).
149 */
e8977170 150 public function testGetDocument_NewFailure_CacheOK_UpdateOK() {
ecbe1139
TO
151 // first try, bad response
152 CRM_Utils_Time::setTime('2013-03-01 10:00:00');
153 $communityMessages = new CRM_Core_CommunityMessages(
154 $this->cache,
155 $this->expectOneHttpRequest($this->webResponses['http-error'])
156 );
157 $doc1 = $communityMessages->getDocument();
158 $this->assertEquals(array(), $doc1['messages']);
159 $this->assertTrue($doc1['expires'] > CRM_Utils_Time::getTimeRaw());
160
161 // second try, $doc1 hasn't expired yet, so still use it
162 CRM_Utils_Time::setTime('2013-03-01 10:09:00');
163 $communityMessages = new CRM_Core_CommunityMessages(
164 $this->cache,
165 $this->expectNoHttpRequest()
166 );
167 $doc2 = $communityMessages->getDocument();
168 $this->assertEquals(array(), $doc2['messages']);
169 $this->assertEquals($doc1['expires'], $doc2['expires']);
170
171 // third try, $doc1 expired, try again, get a good response
172 CRM_Utils_Time::setTime('2013-03-01 12:00:02'); // more than 2 hours later (DEFAULT_RETRY)
173 $communityMessages = new CRM_Core_CommunityMessages(
174 $this->cache,
175 $this->expectOneHttpRequest($this->webResponses['hello-world'])
176 );
177 $doc3 = $communityMessages->getDocument();
178 $this->assertEquals('<h1>Hello world</h1>', $doc3['messages'][0]['markup']);
179 $this->assertTrue($doc3['expires'] > CRM_Utils_Time::getTimeRaw());
180 }
181
182 /**
183 * First download of new doc is OK.
184 * The update fails.
185 * The failure cached.
186 * The failure eventually expires and new update succeeds.
187 */
e8977170 188 public function testGetDocument_NewOK_UpdateFailure_CacheOK_UpdateOK() {
ecbe1139
TO
189 // first try, good response
190 CRM_Utils_Time::setTime('2013-03-01 10:00:00');
191 $communityMessages = new CRM_Core_CommunityMessages(
192 $this->cache,
193 $this->expectOneHttpRequest($this->webResponses['hello-world'])
194 );
195 $doc1 = $communityMessages->getDocument();
196 $this->assertEquals('<h1>Hello world</h1>', $doc1['messages'][0]['markup']);
197 $this->assertEquals(strtotime('2013-03-01 10:10:00'), $doc1['expires']);
198
199 // second try, $doc1 has expired; bad response; keep old data
200 CRM_Utils_Time::setTime('2013-03-01 12:00:02'); // more than 2 hours later (DEFAULT_RETRY)
201 $communityMessages = new CRM_Core_CommunityMessages(
202 $this->cache,
203 $this->expectOneHttpRequest($this->webResponses['http-error'])
204 );
205 $doc2 = $communityMessages->getDocument();
206 $this->assertEquals('<h1>Hello world</h1>', $doc2['messages'][0]['markup']);
207 $this->assertTrue($doc2['expires'] > CRM_Utils_Time::getTimeRaw());
208
209 // third try, $doc2 hasn't expired yet; no request; keep old data
210 CRM_Utils_Time::setTime('2013-03-01 12:09:00');
211 $communityMessages = new CRM_Core_CommunityMessages(
212 $this->cache,
213 $this->expectNoHttpRequest()
214 );
215 $doc3 = $communityMessages->getDocument();
216 $this->assertEquals('<h1>Hello world</h1>', $doc3['messages'][0]['markup']);
217 $this->assertEquals($doc2['expires'], $doc3['expires']);
218
219 // fourth try, $doc2 has expired yet; new request; replace data
220 CRM_Utils_Time::setTime('2013-03-01 12:10:02');
221 $communityMessages = new CRM_Core_CommunityMessages(
222 $this->cache,
223 $this->expectOneHttpRequest($this->webResponses['salut-a-tout'])
224 );
225 $doc4 = $communityMessages->getDocument();
226 $this->assertEquals('<h1>Salut a tout</h1>', $doc4['messages'][0]['markup']);
227 $this->assertEquals(strtotime('2013-03-01 12:20:02'), $doc4['expires']);
228 }
229
e8977170 230 public function testGetDocument_NewOK_UpdateParseError() {
ecbe1139
TO
231 // first try, good response
232 CRM_Utils_Time::setTime('2013-03-01 10:00:00');
233 $communityMessages = new CRM_Core_CommunityMessages(
234 $this->cache,
235 $this->expectOneHttpRequest($this->webResponses['hello-world'])
236 );
237 $doc1 = $communityMessages->getDocument();
238 $this->assertEquals('<h1>Hello world</h1>', $doc1['messages'][0]['markup']);
239 $this->assertEquals(strtotime('2013-03-01 10:10:00'), $doc1['expires']);
240
241 // second try, $doc1 has expired; bad response; keep old data
242 CRM_Utils_Time::setTime('2013-03-01 12:00:02'); // more than 2 hours later (DEFAULT_RETRY)
243 $communityMessages = new CRM_Core_CommunityMessages(
244 $this->cache,
245 $this->expectOneHttpRequest($this->webResponses['bad-json'])
246 );
247 $doc2 = $communityMessages->getDocument();
248 $this->assertEquals('<h1>Hello world</h1>', $doc2['messages'][0]['markup']);
249 $this->assertEquals(strtotime('2013-03-01 12:10:02'), $doc2['expires']);
250 }
251
8bfc3cb1
TO
252 public function testGetDocument_NewOK_UpdateInvalidDoc() {
253 // first try, good response
254 CRM_Utils_Time::setTime('2013-03-01 10:00:00');
255 $communityMessages = new CRM_Core_CommunityMessages(
256 $this->cache,
257 $this->expectOneHttpRequest($this->webResponses['hello-world'])
258 );
259 $doc1 = $communityMessages->getDocument();
260 $this->assertEquals('<h1>Hello world</h1>', $doc1['messages'][0]['markup']);
261 $this->assertEquals(strtotime('2013-03-01 10:10:00'), $doc1['expires']);
262
263 // second try, $doc1 has expired; bad response; keep old data
264 CRM_Utils_Time::setTime('2013-03-01 12:00:02'); // more than 2 hours later (DEFAULT_RETRY)
265 $communityMessages = new CRM_Core_CommunityMessages(
266 $this->cache,
267 $this->expectOneHttpRequest($this->webResponses['invalid-ttl-document'])
268 );
269 $doc2 = $communityMessages->getDocument();
270 $this->assertEquals('<h1>Hello world</h1>', $doc2['messages'][0]['markup']);
271 $this->assertEquals(strtotime('2013-03-01 12:10:02'), $doc2['expires']);
272 }
273
ecbe1139
TO
274 /**
275 * Generate a mock HTTP client with the expectation that it is never called.
276 *
277 * @return CRM_Utils_HttpClient|PHPUnit_Framework_MockObject_MockObject
278 */
279 protected function expectNoHttpRequest() {
280 $client = $this->getMock('CRM_Utils_HttpClient');
281 $client->expects($this->never())
282 ->method('get');
283 return $client;
284 }
285
286 /**
287 * Generate a mock HTTP client with the expectation that it is called once.
288 *
289 * @return CRM_Utils_HttpClient|PHPUnit_Framework_MockObject_MockObject
290 */
291 protected function expectOneHttpRequest($response) {
292 $client = $this->getMock('CRM_Utils_HttpClient');
293 $client->expects($this->once())
294 ->method('get')
295 ->will($this->returnValue($response));
296 return $client;
297 }
298}