From 5e559a23afa0e5b9bcb6ae6bf9fd47d2b8c07039 Mon Sep 17 00:00:00 2001 From: eileen Date: Fri, 2 Oct 2020 14:32:56 +1300 Subject: [PATCH] dev/core#2046 Fix blockDelete to delete while ensuring is_primary is valid The del function on each of the location DAO ensures that after a delete at least one phone (etc) is marked is_primary. This blockDelete does not do that & per the test it's possible to call this in such a way that no addresses are primary. Whether this actually happens is a bit unknown. However, this cleans up block delete in a way where we can demonstrate the tests work --- CRM/Core/BAO/Block.php | 11 +-- .../CRM/Contact/Import/Parser/ContactTest.php | 88 +++++++++++++++++++ 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/CRM/Core/BAO/Block.php b/CRM/Core/BAO/Block.php index 898b88360a..10cff14b3f 100644 --- a/CRM/Core/BAO/Block.php +++ b/CRM/Core/BAO/Block.php @@ -337,15 +337,8 @@ class CRM_Core_BAO_Block { $name = 'OpenID'; } - $baoString = 'CRM_Core_DAO_' . $name; - $block = new $baoString(); - - $block->copyValues($params); - - // CRM-11006 add call to pre and post hook for delete action - CRM_Utils_Hook::pre('delete', $name, $block->id, CRM_Core_DAO::$_nullArray); - $block->delete(); - CRM_Utils_Hook::post('delete', $name, $block->id, $block); + $baoString = 'CRM_Core_BAO_' . $name; + $baoString::del($params['id']); } /** diff --git a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php index d6e4ea58a2..fbfa8f9990 100644 --- a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php +++ b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php @@ -255,6 +255,94 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { $this->callAPISuccess('Contact', 'delete', ['id' => $contact['id']]); } + /** + * Test that the not-really-encouraged way of creating locations via contact.create doesn't mess up primaries. + */ + public function testContactLocationBlockHandling() { + $id = $this->individualCreate([ + 'phone' => [ + 1 => [ + 'location_type_id' => 1, + 'phone' => '987654321', + ], + 2 => [ + 'location_type_id' => 2, + 'phone' => '456-7890', + ], + ], + 'im' => [ + 1 => [ + 'location_type_id' => 1, + 'name' => 'bob', + ], + 2 => [ + 'location_type_id' => 2, + 'name' => 'fred', + ], + ], + 'openid' => [ + 1 => [ + 'location_type_id' => 1, + 'openid' => 'bob', + ], + 2 => [ + 'location_type_id' => 2, + 'openid' => 'fred', + ], + ], + 'email' => [ + 1 => [ + 'location_type_id' => 1, + 'email' => 'bob@example.com', + ], + 2 => [ + 'location_type_id' => 2, + 'email' => 'fred@example.com', + ], + ], + ]); + $phones = $this->callAPISuccess('Phone', 'get', ['contact_id' => $id])['values']; + $emails = $this->callAPISuccess('Email', 'get', ['contact_id' => $id])['values']; + $openIDs = $this->callAPISuccess('OpenID', 'get', ['contact_id' => $id])['values']; + $ims = $this->callAPISuccess('IM', 'get', ['contact_id' => $id])['values']; + $this->assertCount(2, $phones); + $this->assertCount(2, $emails); + $this->assertCount(2, $ims); + $this->assertCount(2, $openIDs); + + $this->assertLocationValidity(); + $this->callAPISuccess('Contact', 'create', [ + 'id' => $id, + // This is secret code for 'delete this phone'. + 'updateBlankLocInfo' => TRUE, + 'phone' => [ + 1 => [ + 'id' => key($phones), + ], + ], + 'email' => [ + 1 => [ + 'id' => key($emails), + ], + ], + 'im' => [ + 1 => [ + 'id' => key($ims), + ], + ], + 'openid' => [ + 1 => [ + 'id' => key($openIDs), + ], + ], + ]); + $this->assertLocationValidity(); + $this->callAPISuccessGetCount('Phone', ['contact_id' => $id], 1); + $this->callAPISuccessGetCount('Email', ['contact_id' => $id], 1); + $this->callAPISuccessGetCount('OpenID', ['contact_id' => $id], 1); + $this->callAPISuccessGetCount('IM', ['contact_id' => $id], 1); + } + /** * Test that the import parser adds the address to the primary location. * -- 2.25.1