dev/core#3962 Add 'boolean' as a filter for tokens
authorEileen McNaughton <emcnaughton@wikimedia.org>
Tue, 8 Nov 2022 04:45:50 +0000 (17:45 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Wed, 16 Nov 2022 21:16:22 +0000 (10:16 +1300)
Add unit tests leveraging & demo-ing boolean fitler in greetings

Civi/Token/TokenProcessor.php
tests/phpunit/Civi/Token/TokenProcessorTest.php
tests/phpunit/api/v3/JobTest.php

index 87290e4aec6b56aedc2fb6231d23e35c7c3187fd..1ed89df5fc6016b3578505c5656d735d82bcea0d 100644 (file)
@@ -494,6 +494,10 @@ class TokenProcessor {
       case 'lower':
         return mb_strtolower($value);
 
+      case 'boolean':
+        // Cast to 0 or 1 for use in text.
+        return (int) ((bool) $value);
+
       case 'crmDate':
         if ($value instanceof \DateTime) {
           // @todo cludgey.
@@ -505,7 +509,7 @@ class TokenProcessor {
         }
 
       default:
-        throw new \CRM_Core_Exception("Invalid token filter: " . json_encode($filter, JSON_UNESCAPED_SLASHES));
+        throw new \CRM_Core_Exception('Invalid token filter: ' . json_encode($filter, JSON_UNESCAPED_SLASHES));
     }
   }
 
index 92799782883a8b196ae35130d5f0a83bdabc49d8..b606ca4c28b6db82437d7dd357d697720a1a591f 100644 (file)
@@ -341,14 +341,18 @@ class TokenProcessorTest extends \CiviUnitTestCase {
     $this->assertEquals(1, $this->counts['onEvalTokens']);
   }
 
-  public function testFilter() {
+  public function testFilter(): void {
     $exampleTokens['foo_bar']['whiz_bang'] = 'Some Text';
+    $exampleTokens['foo_bar']['whiz_bop'] = '';
     $exampleMessages = [
       'This is {foo_bar.whiz_bang}.' => 'This is Some Text.',
       'This is {foo_bar.whiz_bang|lower}...' => 'This is some text...',
       'This is {foo_bar.whiz_bang|upper}!' => 'This is SOME TEXT!',
+      'This is {foo_bar.whiz_bang|boolean}!' => 'This is 1!',
+      'This is {foo_bar.whiz_bop|boolean}!' => 'This is 0!',
     ];
-    $expectExampleCount = /* {#msgs} x {smarty:on,off} */ 6;
+    // We expect 5 messages to be parsed 2 times each - ie 10 times.
+    $expectExampleCount = 10;
     $actualExampleCount = 0;
 
     foreach ($exampleMessages as $inputMessage => $expectOutput) {
index 419fe607df5c172ebc52159a10c110d09f741695..237a2bad761a878c3c6cbc9d7a364ed2b207e733 100644 (file)
@@ -27,6 +27,15 @@ use Civi\Api4\Contact;
  */
 class api_v3_JobTest extends CiviUnitTestCase {
 
+  /**
+   * Entities to return to their original values during tearDown.
+   *
+   * The array is keyed by EntityName.
+   *
+   * @var array
+   */
+  private $originalValues = [];
+
   /**
    * Set up for tests.
    */
@@ -50,6 +59,12 @@ class api_v3_JobTest extends CiviUnitTestCase {
   public function tearDown(): void {
     $this->quickCleanUpFinancialEntities();
     $this->quickCleanup(['civicrm_contact', 'civicrm_address', 'civicrm_email', 'civicrm_website', 'civicrm_phone', 'civicrm_job', 'civicrm_action_log', 'civicrm_action_schedule', 'civicrm_group', 'civicrm_group_contact'], TRUE);
+    $this->quickCleanup(['civicrm_contact', 'civicrm_address', 'civicrm_email', 'civicrm_website', 'civicrm_phone'], TRUE);
+    foreach ($this->originalValues as $entity => $entities) {
+      foreach ($entities as $values) {
+        $this->callAPISuccess($entity, 'create', $values);
+      }
+    }
     parent::tearDown();
   }
 
@@ -103,6 +118,56 @@ class api_v3_JobTest extends CiviUnitTestCase {
     $this->assertAPIDeleted('Job', $createResult['id']);
   }
 
+  /**
+   * Test processing strings with boolean's in them.
+   *
+   * e.g {if {contact.first_name|boolean}
+   *
+   * @dataProvider dataProviderNamesAndGreetings
+   */
+  public function testUpdateGreetingBooleanToken($params, $expectedEmailGreeting): void {
+    $this->setEmailGreetingTemplateToConditional();
+    $contactID = $this->individualCreate($params);
+    $this->assertEquals($expectedEmailGreeting, Contact::get()->addSelect('email_greeting_display')->addWhere('id', '=', $contactID)->execute()->first()['email_greeting_display']);
+  }
+
+  /**
+   * Data provider for testing email greeting template.
+   */
+  public function dataProviderNamesAndGreetings(): array {
+    return [
+      [
+        'params' => ['first_name' => 'Anthony'],
+        'expected' => 'Dear Anthony',
+      ],
+      [
+        'params' => ['first_name' => ''],
+        'expected' => 'Dear Friend',
+      ],
+      [
+        // This isn't really an issue with the |boolean provider
+        // but it would be without it - https://lab.civicrm.org/dev/core/-/issues/3962
+        'params' => ['first_name' => "O'Shea"],
+        'expected' => "Dear O'Shea",
+      ],
+    ];
+  }
+
+  /**
+   * Set the Individual email template to use {if {contact.first_name|boolean}.
+   */
+  protected function setEmailGreetingTemplateToConditional(): void {
+    $this->originalValues['OptionValue']['email'] = reset($this->callAPISuccess('OptionValue', 'get', [
+      'option_group_id' => 'email_greeting',
+      'is_default' => TRUE,
+      'filter' => 1,
+    ])['values']);
+    $this->callAPISuccess('OptionValue', 'create', [
+      'id' => $this->originalValues['OptionValue']['email']['id'],
+      'label' => '{if {contact.first_name|boolean}}Dear {contact.first_name}{else}Dear Friend{/if}',
+    ]);
+  }
+
   /**
    * Test greeting update job.
    *