class CRM_Core_CommunityMessages {
const DEFAULT_MESSAGES_URL = 'http://alert.civicrm.org/alert?prot=1&ver={ver}&uf={uf}&sid={sid}';
+ const DEFAULT_PERMISSION = 'administer CiviCRM';
/**
* Default time to wait before retrying
* @param array $components
* @return NULL|array
*/
- public function pick($permChecker, $components) {
- throw new Exception('not implemented');
+ public function pick() {
+ $document = $this->getDocument();
+ $messages = array();
+ foreach ($document['messages'] as $message) {
+ if (!isset($message['perms'])) {
+ $message['perms'] = array(self::DEFAULT_PERMISSION);
+ }
+ if (!CRM_Core_Permission::checkAnyPerm($message['perms'])) {
+ continue;
+ }
+
+ if (isset($message['components'])) {
+ $enabled = array_keys(CRM_Core_Component::getEnabledComponents());
+ if (count(array_intersect($enabled, $message['components'])) == 0) {
+ continue;
+ }
+ }
+
+ $messages[] = $message;
+ }
+ if (empty($messages)) {
+ return NULL;
+ }
+
+ $idx = rand(0, count($messages) - 1);
+ return $messages[$idx];
}
/**
),
))
),
+ 'two-messages' => array(
+ CRM_Utils_HttpClient::STATUS_OK,
+ json_encode(array(
+ 'ttl' => 600,
+ 'retry' => 600,
+ 'messages' => array(
+ array(
+ 'markup' => '<h1>One</h1>',
+ 'components' => array('CiviMail'),
+ ),
+ array(
+ 'markup' => '<h1>Two</h1>',
+ 'components' => array('CiviMail'),
+ ),
+ ),
+ ))
+ ),
+ 'two-messages-halfbadcomp' => array(
+ CRM_Utils_HttpClient::STATUS_OK,
+ json_encode(array(
+ 'ttl' => 600,
+ 'retry' => 600,
+ 'messages' => array(
+ array(
+ 'markup' => '<h1>One</h1>',
+ 'components' => array('NotARealComponent'),
+ ),
+ array(
+ 'markup' => '<h1>Two</h1>',
+ 'components' => array('CiviMail'),
+ ),
+ ),
+ ))
+ ),
);
}
return self::$webResponses;
$this->assertEquals(strtotime('2013-03-01 12:20:02'), $doc4['expires']);
}
+ /**
+ * Randomly pick among two options
+ */
+ public function testPick_rand() {
+ $communityMessages = new CRM_Core_CommunityMessages(
+ $this->cache,
+ $this->expectOneHttpRequest(self::$webResponses['two-messages'])
+ );
+ $doc1 = $communityMessages->getDocument();
+ $this->assertEquals('<h1>One</h1>', $doc1['messages'][0]['markup']);
+ $this->assertEquals('<h1>Two</h1>', $doc1['messages'][1]['markup']);
+
+ // randomly pick many times
+ $trials = 40;
+ $freq = array(); // array($message => $count)
+ for ($i = 0; $i < $trials; $i++) {
+ $message = $communityMessages->pick();
+ $freq[$message['markup']]++;
+ }
+
+ // assert the probabilities
+ $this->assertApproxEquals(0.5, $freq['<h1>One</h1>'] / $trials, 0.2);
+ $this->assertApproxEquals(0.5, $freq['<h1>Two</h1>'] / $trials, 0.2);
+ $this->assertEquals($trials, $freq['<h1>One</h1>'] + $freq['<h1>Two</h1>']);
+ }
+
+ /**
+ * When presented with two options using component filters, always
+ * choose the one which references an active component.
+ */
+ public function testPick_componentFilter() {
+ $communityMessages = new CRM_Core_CommunityMessages(
+ $this->cache,
+ $this->expectOneHttpRequest(self::$webResponses['two-messages-halfbadcomp'])
+ );
+ $doc1 = $communityMessages->getDocument();
+ $this->assertEquals('<h1>One</h1>', $doc1['messages'][0]['markup']);
+ $this->assertEquals('<h1>Two</h1>', $doc1['messages'][1]['markup']);
+
+ // randomly pick many times
+ $trials = 10;
+ $freq = array(); // array($message => $count)
+ for ($i = 0; $i < $trials; $i++) {
+ $message = $communityMessages->pick();
+ $freq[$message['markup']]++;
+ }
+
+ $this->assertEquals($trials, $freq['<h1>Two</h1>']);
+ }
+
/**
* Generate a mock HTTP client with the expectation that it is never called.
*
$this->assertEquals($e, $a);
}
+ /**
+ * Assert that two numbers are approximately equal
+ *
+ * @param int|float $expected
+ * @param int|float $actual
+ * @param int|float $tolerance
+ * @param string $message
+ */
+ function assertApproxEquals($expected, $actual, $tolerance, $message = NULL) {
+ if ($message === NULL) {
+ $message = sprintf("approx-equals: expected=[%.3f] actual=[%.3f] tolerance=[%.3f]", $expected, $actual, $tolerance);
+ }
+ $this->assertTrue(abs($actual - $expected) < $tolerance, $message);
+ }
+
function assertAttributesEquals($expectedValues, $actualValues, $message = NULL) {
foreach ($expectedValues as $paramName => $paramValue) {
if (isset($actualValues[$paramName])) {