(dev/core#4147) Add scenario testTokensIndividually
authorTim Otten <totten@civicrm.org>
Wed, 1 Mar 2023 09:12:49 +0000 (01:12 -0800)
committerTim Otten <totten@civicrm.org>
Wed, 1 Mar 2023 09:23:39 +0000 (01:23 -0800)
tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php

index 4baada93f66ae95293220491c2d60128041e0a69..3132858ad3016994ac39ec97911fe2b53f8e3038 100644 (file)
@@ -485,6 +485,52 @@ emo
     $this->assertEquals($expected_parts[2], $returned_parts[2]);
   }
 
+  /**
+   * Assuming that `testContactTokens()` has asserted tokens work en masse, we have another
+   * question -- do the tokens work the same when evaluated en-masse and individually?
+   */
+  public function testTokensIndividually() {
+    // Freeze the time at the start of the test, so checksums don't suffer from second rollovers.
+    $restoreTime = $this->useFrozenTime();
+
+    $this->hookClass->setHook('civicrm_tokenValues', [$this, 'hookTokenValues']);
+    $this->hookClass->setHook('civicrm_tokens', [$this, 'hookTokens']);
+
+    $this->createCustomGroupWithFieldsOfAllTypes([]);
+    $tokenData = $this->getOldContactTokens();
+    $this->setupContactFromTokeData($tokenData);
+
+    $ctx = ['contactId' => $tokenData['contact_id']];
+    $render = function (string $templateText) use ($ctx, $tokenData) {
+      try {
+        return CRM_Core_TokenSmarty::render(['text' => $templateText], $ctx)['text'];
+      }
+      catch (\Throwable $t) {
+        return "EXCEPTION:" . $t->getMessage();
+      }
+    };
+
+    // Build $tokenLines, a list of expressions like 'contact.display_name:{contact.display_name}'
+    $tokenLines = [];
+    $tokenNames = array_keys($this->getAdvertisedTokens());
+    foreach ($tokenNames as $tokenName) {
+      $tokenLines[] = trim($tokenName, '{}') . ':' . $tokenName;
+    }
+    foreach (array_keys($tokenData) as $key) {
+      $tokenLines[] .= "contact.$key:{contact.$key}";
+    }
+    $tokenLines = array_unique($tokenLines);
+    sort($tokenLines);
+
+    // Evaluate all these token lines
+    $oneByOne = array_map($render, $tokenLines);
+    $allAtOnce = $render(implode("\n", $tokenLines));
+    $this->assertEquals($allAtOnce, implode("\n", $oneByOne));
+
+    $emptyLines = preg_grep('/:$/', $oneByOne);
+    $this->assertEquals([], $emptyLines, "All tokens should have data.");
+  }
+
   /**
    * Test that old contact tokens still work, as we add new-style support.
    *