From f04b3586a06ee505bfb11761219590cbfdc3e0e0 Mon Sep 17 00:00:00 2001 From: eileen Date: Wed, 16 Sep 2020 11:48:49 +1200 Subject: [PATCH] Add check to ensure all have a primary address, fix identified but in IM.add --- CRM/Core/BAO/IM.php | 8 +- tests/phpunit/CRM/Export/BAO/ExportTest.php | 7 ++ tests/phpunit/CiviTest/CiviUnitTestCase.php | 123 +++++++++++++++++++- 3 files changed, 135 insertions(+), 3 deletions(-) diff --git a/CRM/Core/BAO/IM.php b/CRM/Core/BAO/IM.php index 3a950122dd..cdab960f65 100644 --- a/CRM/Core/BAO/IM.php +++ b/CRM/Core/BAO/IM.php @@ -24,9 +24,15 @@ class CRM_Core_BAO_IM extends CRM_Core_DAO_IM { * Create or update IM record. * * @param array $params - * @return CRM_Core_DAO_IM + * + * @return \CRM_Core_DAO|\CRM_Core_DAO_IM + * @throws \CRM_Core_Exception + * @throws \API_Exception */ public static function add($params) { + if (empty($params['id']) || is_numeric($params['is_primary'] ?? NULL)) { + CRM_Core_BAO_Block::handlePrimary($params, __CLASS__); + } return self::writeRecord($params); } diff --git a/tests/phpunit/CRM/Export/BAO/ExportTest.php b/tests/phpunit/CRM/Export/BAO/ExportTest.php index 3db128633f..7d21e3cfc0 100644 --- a/tests/phpunit/CRM/Export/BAO/ExportTest.php +++ b/tests/phpunit/CRM/Export/BAO/ExportTest.php @@ -47,6 +47,13 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase { protected $locationTypes = []; + /** + * Should location types be checked to ensure primary addresses are correctly assigned after each test. + * + * @var bool + */ + protected $isLocationTypesOnPostAssert = TRUE; + /** * Processor generated in test. * diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index 0930fb4f1e..e2b1b4d65e 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -144,6 +144,13 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase { */ protected $isValidateFinancialsOnPostAssert = FALSE; + /** + * Should location types be checked to ensure primary addresses are correctly assigned after each test. + * + * @var bool + */ + protected $isLocationTypesOnPostAssert = FALSE; + /** * Class used for hooks during tests. * @@ -495,6 +502,9 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase { * @throws \CRM_Core_Exception */ protected function assertPostConditions() { + if ($this->isLocationTypesOnPostAssert) { + $this->assertLocationValidity(); + } if (!$this->isValidateFinancialsOnPostAssert) { return; } @@ -3662,8 +3672,117 @@ VALUES 'activity_details' => '', ]; $form = new CRM_Case_Form_Case(); - $caseObj = $form->testSubmit($caseParams, "OpenCase", $loggedInUser, "standalone"); - return $caseObj; + return $form->testSubmit($caseParams, 'OpenCase', $loggedInUser, 'standalone'); + } + + /** + * Validate that all location entities have exactly one primary. + * + * This query takes about 2 minutes on a DB with 10s of millions of contacts. + */ + public function assertLocationValidity() { + $this->assertEquals(0, CRM_Core_DAO::singleValueQuery('SELECT COUNT(*) FROM + +(SELECT a1.contact_id +FROM civicrm_address a1 + LEFT JOIN civicrm_address a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE + a1.is_primary = 1 + AND a2.id IS NOT NULL + AND a1.contact_id IS NOT NULL +UNION +SELECT a1.contact_id +FROM civicrm_address a1 + LEFT JOIN civicrm_address a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE a1.is_primary = 0 + AND a2.id IS NULL + AND a1.contact_id IS NOT NULL + +UNION + +SELECT a1.contact_id +FROM civicrm_email a1 + LEFT JOIN civicrm_email a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE + a1.is_primary = 1 + AND a2.id IS NOT NULL + AND a1.contact_id IS NOT NULL +UNION +SELECT a1.contact_id +FROM civicrm_email a1 + LEFT JOIN civicrm_email a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE a1.is_primary = 0 + AND a2.id IS NULL + AND a1.contact_id IS NOT NULL + +UNION + +SELECT a1.contact_id +FROM civicrm_phone a1 + LEFT JOIN civicrm_phone a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE + a1.is_primary = 1 + AND a2.id IS NOT NULL + AND a1.contact_id IS NOT NULL +UNION +SELECT a1.contact_id +FROM civicrm_phone a1 + LEFT JOIN civicrm_phone a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE a1.is_primary = 0 + AND a2.id IS NULL + AND a1.contact_id IS NOT NULL + +UNION + +SELECT a1.contact_id +FROM civicrm_im a1 + LEFT JOIN civicrm_im a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE + a1.is_primary = 1 + AND a2.id IS NOT NULL + AND a1.contact_id IS NOT NULL +UNION +SELECT a1.contact_id +FROM civicrm_im a1 + LEFT JOIN civicrm_im a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE a1.is_primary = 0 + AND a2.id IS NULL + AND a1.contact_id IS NOT NULL + +UNION + +SELECT a1.contact_id +FROM civicrm_openid a1 + LEFT JOIN civicrm_openid a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE (a1.is_primary = 1 AND a2.id IS NOT NULL) +UNION + +SELECT a1.contact_id +FROM civicrm_openid a1 + LEFT JOIN civicrm_openid a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE + a1.is_primary = 1 + AND a2.id IS NOT NULL + AND a1.contact_id IS NOT NULL +UNION +SELECT a1.contact_id +FROM civicrm_openid a1 + LEFT JOIN civicrm_openid a2 ON a1.id <> a2.id AND a2.is_primary = 1 + AND a1.contact_id = a2.contact_id +WHERE a1.is_primary = 0 + AND a2.id IS NULL + AND a1.contact_id IS NOT NULL) as primary_descrepancies + ')); } } -- 2.25.1