CRM-17951 Add function to safe-add option values in upgrade
authoreileen <emcnaughton@wikimedia.org>
Wed, 3 Feb 2016 09:54:28 +0000 (22:54 +1300)
committereileen <emcnaughton@wikimedia.org>
Wed, 3 Feb 2016 10:42:15 +0000 (23:42 +1300)
CRM/Core/BAO/OptionValue.php
tests/phpunit/CRM/Core/BAO/OptionValueTest.php [new file with mode: 0644]

index 04b0e382377a7d3f7e2618f3507ffb0142b56bcf..0e3bb21dc5e37d313b0d2059c1d5726ab70c4d96 100644 (file)
@@ -169,7 +169,7 @@ class CRM_Core_BAO_OptionValue extends CRM_Core_DAO_OptionValue {
    *
    * @return CRM_Core_DAO_OptionValue
    */
-  public static function add(&$params, &$ids) {
+  public static function add(&$params, $ids) {
     // CRM-10921: do not reset attributes to default if this is an update
     //@todo consider if defaults are being set in the right place. 'dumb' defaults like
     // these would be usefully set @ the api layer so they are visible to api users
@@ -519,4 +519,22 @@ class CRM_Core_BAO_OptionValue extends CRM_Core_DAO_OptionValue {
     return $options;
   }
 
+  /**
+   * Ensure an option value exists.
+   *
+   * This function is intended to be called from the upgrade script to ensure
+   * that an option value exists, without hitting an error if it already exists.
+   *
+   * This is sympathetic to sites who might pre-add it.
+   */
+  public static function ensureOptionValueExists($params) {
+    $existingValues = civicrm_api3('OptionValue', 'get', array(
+      'option_group_name' => $params['option_group_id'],
+      'name' => $params['name'],
+    ));
+    if (!$existingValues['count']) {
+      civicrm_api3('OptionValue', 'create', $params);
+    }
+  }
+
 }
diff --git a/tests/phpunit/CRM/Core/BAO/OptionValueTest.php b/tests/phpunit/CRM/Core/BAO/OptionValueTest.php
new file mode 100644 (file)
index 0000000..fe385b7
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.7                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+ */
+
+require_once 'CiviTest/CiviUnitTestCase.php';
+
+/**
+ * Class CRM_Core_BAO_SchemaHandlerTest.
+ *
+ * These tests create and drop indexes on the civicrm_uf_join table. The indexes
+ * being added and dropped we assume will never exist.
+ */
+class CRM_Core_BAO_OptionValueTest extends CiviUnitTestCase {
+
+  /**
+   * Test setup for every test.
+   */
+  public function setUp() {
+    parent::setUp();
+    $this->useTransaction(TRUE);
+  }
+
+  /**
+   * Ensure only one option value exists after calling ensureOptionValueExists.
+   */
+  public function testEnsureOptionValueExistsExistingValue() {
+    CRM_Core_BAO_OptionValue::ensureOptionValueExists(array('name' => 'Completed', 'option_group_id' => 'contribution_status'));
+    $this->callAPISuccessGetSingle('OptionValue', array('name' => 'Completed', 'option_group_id' => 'contribution_status'));
+  }
+
+  /**
+   * Ensure only one option value exists adds a new value.
+   */
+  public function testEnsureOptionValueExistsNewValue() {
+    CRM_Core_BAO_OptionValue::ensureOptionValueExists(array('name' => 'Bombed', 'option_group_id' => 'contribution_status'));
+    $optionValues = $this->callAPISuccess('OptionValue', 'get', array('option_group_id' => 'contribution_status'));
+    foreach ($optionValues['values'] as $value) {
+      if ($value['name'] == 'Bombed') {
+        return;
+      }
+    }
+    $this->fail('Should not have gotten this far');
+  }
+
+
+  /**
+   * Ensure only one option value copes with disabled.
+   *
+   * (Our expectation is no change - ie. currently we are respecting 'someone's
+   * decision to disable it & leaving it in that state.
+   */
+  public function testEnsureOptionValueExistsDisabled() {
+    CRM_Core_BAO_OptionValue::ensureOptionValueExists(array('name' => 'Crashed', 'option_group_id' => 'contribution_status', 'is_active' => 0));
+    $value = $this->callAPISuccessGetSingle('OptionValue', array('name' => 'Crashed', 'option_group_id' => 'contribution_status'));
+    $this->assertEquals(0, $value['is_active']);
+    CRM_Core_BAO_OptionValue::ensureOptionValueExists(array('name' => 'Crashed', 'option_group_id' => 'contribution_status'));
+    $value = $this->callAPISuccessGetSingle('OptionValue', array('name' => 'Crashed', 'option_group_id' => 'contribution_status'));
+    $this->assertEquals(0, $value['is_active']);
+  }
+
+}