dev/core#2832 Add test for legacy membership tokens, add support for preferred tokens
authorEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 13 Sep 2021 05:34:34 +0000 (17:34 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 13 Sep 2021 05:34:41 +0000 (17:34 +1200)
There is only one place that calls this code. With cover of the legacy tokens
I can ensure it is the same as the processor tokens. I've fixed it
to support the preferred unambiguous tokens because that means that
we don't have to deal with reports of them not working while calls
to it are phased out of extensions. Working through that
also allowed me to remove some code now

CRM/Utils/Token.php
tests/phpunit/CRM/Utils/TokenConsistencyTest.php

index 46990bed095f7fdeb8f1c2517d915b13e05d22ff..c3aa61b9294c5ac4f23ffb48f2eb30e298348906 100644 (file)
@@ -1534,21 +1534,6 @@ class CRM_Utils_Token {
     self::$_tokens[$key] = Civi::$statics[__CLASS__][__FUNCTION__][$key];
   }
 
-  /**
-   * Store membership tokens on the static _tokens array.
-   */
-  protected static function _buildMembershipTokens() {
-    $key = 'membership';
-    if (!isset(self::$_tokens[$key]) || self::$_tokens[$key] == NULL) {
-      $membershipTokens = [];
-      $tokens = CRM_Core_SelectValues::membershipTokens();
-      foreach ($tokens as $token => $dontCare) {
-        $membershipTokens[] = substr($token, (strpos($token, '.') + 1), -1);
-      }
-      self::$_tokens[$key] = $membershipTokens;
-    }
-  }
-
   /**
    * Replace tokens for an entity.
    * @param string $entity
@@ -1705,6 +1690,14 @@ class CRM_Utils_Token {
   /**
    * Get replacement strings for any membership tokens (only a small number of tokens are implemnted in the first instance
    * - this is used by the pdfLetter task from membership search
+   *
+   * This is called via replaceEntityTokens.
+   *
+   * In the near term it will not be called at all from core as
+   * the pdf letter task is updated to use the processor.
+   *
+   * @deprecated
+   *
    * @param string $entity
    *   should always be "membership"
    * @param string $token
@@ -1714,13 +1707,29 @@ class CRM_Utils_Token {
    * @return string token replacement
    */
   public static function getMembershipTokenReplacement($entity, $token, $membership) {
-    self::_buildMembershipTokens();
+    $supportedTokens = [
+      'id',
+      'status',
+      'status_id',
+      'type',
+      'membership_type_id',
+      'start_date',
+      'join_date',
+      'end_date',
+      'fee',
+    ];
     switch ($token) {
       case 'type':
+        // membership_type_id would only be requested if the calling
+        // class is mapping it to '{membership:membership_type_id:label'}
+      case 'membership_type_id':
         $value = $membership['membership_name'];
         break;
 
       case 'status':
+        // status_id would only be requested if the calling
+        // class is mapping it to '{membership:status_id:label'}
+      case 'status_id':
         $statuses = CRM_Member_BAO_Membership::buildOptions('status_id');
         $value = $statuses[$membership['status_id']];
         break;
@@ -1741,7 +1750,7 @@ class CRM_Utils_Token {
         break;
 
       default:
-        if (in_array($token, self::$_tokens[$entity])) {
+        if (in_array($token, $supportedTokens)) {
           $value = $membership[$token];
           if (CRM_Utils_String::endsWith($token, '_date')) {
             $value = CRM_Utils_Date::customFormat($value);
index d6d9e3274d76a0d26291cd80341a731215a66fc7..ee3bf2d2998f5d6b33d7da253f9b89a43d02a341 100644 (file)
@@ -357,4 +357,72 @@ Check
 Check';
   }
 
+  /**
+   * Test that membership tokens are consistently rendered.
+   *
+   * @throws \API_Exception
+   */
+  public function testMembershipTokenConsistency(): void {
+    $this->createLoggedInUser();
+    $this->restoreMembershipTypes();
+    $this->createCustomGroupWithFieldOfType(['extends' => 'Membership']);
+    $tokens = CRM_Core_SelectValues::membershipTokens();
+    $this->assertEquals($this->getMembershipTokens(), $tokens);
+    $newStyleTokens = "\n{membership.status_id:label}\n{membership.membership_type_id:label}\n";
+    $tokenString = $newStyleTokens . implode("\n", array_keys($this->getMembershipTokens()));
+    $memberships = CRM_Utils_Token::getMembershipTokenDetails([$this->getMembershipID()]);
+    $messageToken = CRM_Utils_Token::getTokens($tokenString);
+    $tokenHtml = CRM_Utils_Token::replaceEntityTokens('membership', $memberships[$this->getMembershipID()], $tokenString, $messageToken);
+    $this->assertEquals($this->getExpectedMembershipTokenOutput(), $tokenHtml);
+  }
+
+  /**
+   * Get declared membership tokens.
+   *
+   * @return string[]
+   */
+  public function getMembershipTokens(): array {
+    return [
+      '{membership.id}' => 'Membership ID',
+      '{membership.status}' => 'Membership Status',
+      '{membership.type}' => 'Membership Type',
+      '{membership.start_date}' => 'Membership Start Date',
+      '{membership.join_date}' => 'Membership Join Date',
+      '{membership.end_date}' => 'Membership End Date',
+      '{membership.fee}' => 'Membership Fee',
+    ];
+  }
+
+  /**
+   * Get case ID.
+   *
+   * @return int
+   */
+  protected function getMembershipID(): int {
+    if (!isset($this->ids['Membership'][0])) {
+      $this->ids['Membership'][0] = $this->contactMembershipCreate(
+        ['contact_id' => $this->getContactID()]
+      );
+    }
+    return $this->ids['Membership'][0];
+  }
+
+  /**
+   * Get expected output from token parsing.
+   *
+   * @return string
+   */
+  protected function getExpectedMembershipTokenOutput(): string {
+    return '
+Expired
+General
+1
+Expired
+General
+January 21st, 2007
+January 21st, 2007
+December 21st, 2007
+100.00';
+  }
+
 }