CRM-12193 - Validate JSON documents
authorTim Otten <totten@civicrm.org>
Sat, 30 Mar 2013 01:06:10 +0000 (21:06 -0400)
committerTim Otten <totten@civicrm.org>
Sat, 30 Mar 2013 01:06:10 +0000 (21:06 -0400)
----------------------------------------
* CRM-12193: In-app fundraising for CiviCRM
  http://issues.civicrm.org/jira/browse/CRM-12193

CRM/Core/CommunityMessages.php
tests/phpunit/CRM/Core/CommunityMessagesTest.php

index e0efd96a20bee92913ab7acb467e9240439feed6..21b3dc73449d048ba5ebbcd812a1cd55a2e4511d 100644 (file)
@@ -92,7 +92,7 @@ class CRM_Core_CommunityMessages {
 
     if ($document['expires'] <= CRM_Utils_Time::getTimeRaw()) {
       $newDocument = $this->fetchDocument($this->messagesUrl);
-      if ($newDocument) {
+      if ($newDocument && $this->validateDocument($newDocument)) {
         $document = $newDocument;
         $document['expires'] = CRM_Utils_Time::getTimeRaw() + $document['ttl'];
       }
@@ -146,4 +146,27 @@ class CRM_Core_CommunityMessages {
     throw new Exception('not implemented');
   }
 
+  /**
+   * Ensure that a document is well-formed
+   *
+   * @param array $document
+   * @return bool
+   */
+  public function validateDocument($document) {
+    if (!isset($document['ttl']) || !is_integer($document['ttl'])) {
+      return FALSE;
+    }
+    if (!isset($document['retry']) || !is_integer($document['retry'])) {
+      return FALSE;
+    }
+    if (!isset($document['messages']) || !is_array($document['messages'])) {
+      return FALSE;
+    }
+    foreach ($document['messages'] as $message) {
+      // TODO validate $message['markup']
+    }
+
+    return TRUE;
+  }
+
 }
index f4d154fc48e03cff53ce31718a66d85bbcc851b4..778ba9b4decbc55c508fc2537c45dc5327896e46 100644 (file)
@@ -54,6 +54,18 @@ class CRM_Core_CommunityMessagesTest extends CiviUnitTestCase {
         CRM_Utils_HttpClient::STATUS_OK,
         '<html>this is not json!</html>'
       ),
+      'invalid-ttl-document' => array(
+        CRM_Utils_HttpClient::STATUS_OK,
+        json_encode(array(
+          'ttl' => 'z', // not an integer!
+          'retry' => 'z', // not an integer!
+          'messages' => array(
+            array(
+              'markup' => '<h1>Invalid document</h1>',
+            ),
+          ),
+        ))
+      ),
       'hello-world' => array(
         CRM_Utils_HttpClient::STATUS_OK,
         json_encode(array(
@@ -237,6 +249,28 @@ class CRM_Core_CommunityMessagesTest extends CiviUnitTestCase {
     $this->assertEquals(strtotime('2013-03-01 12:10:02'), $doc2['expires']);
   }
 
+  public function testGetDocument_NewOK_UpdateInvalidDoc() {
+    // first try, good response
+    CRM_Utils_Time::setTime('2013-03-01 10:00:00');
+    $communityMessages = new CRM_Core_CommunityMessages(
+      $this->cache,
+      $this->expectOneHttpRequest($this->webResponses['hello-world'])
+    );
+    $doc1 = $communityMessages->getDocument();
+    $this->assertEquals('<h1>Hello world</h1>', $doc1['messages'][0]['markup']);
+    $this->assertEquals(strtotime('2013-03-01 10:10:00'), $doc1['expires']);
+
+    // second try, $doc1 has expired; bad response; keep old data
+    CRM_Utils_Time::setTime('2013-03-01 12:00:02'); // more than 2 hours later (DEFAULT_RETRY)
+    $communityMessages = new CRM_Core_CommunityMessages(
+      $this->cache,
+      $this->expectOneHttpRequest($this->webResponses['invalid-ttl-document'])
+    );
+    $doc2 = $communityMessages->getDocument();
+    $this->assertEquals('<h1>Hello world</h1>', $doc2['messages'][0]['markup']);
+    $this->assertEquals(strtotime('2013-03-01 12:10:02'), $doc2['expires']);
+  }
+
   /**
    * Generate a mock HTTP client with the expectation that it is never called.
    *