From 0636f0c893ff26fa958b56cd490e5f4c7dd32166 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Thu, 19 May 2022 18:23:37 +1200 Subject: [PATCH] Add unit tests to cover date field imports --- CRM/Contact/Import/Parser/Contact.php | 41 ++++++----- .../Form/data/individual_dates_type1.csv | 8 +++ .../CRM/Contact/Import/Parser/ContactTest.php | 69 ++++++++++++++++++- 3 files changed, 97 insertions(+), 21 deletions(-) create mode 100644 tests/phpunit/CRM/Contact/Import/Form/data/individual_dates_type1.csv diff --git a/CRM/Contact/Import/Parser/Contact.php b/CRM/Contact/Import/Parser/Contact.php index afbe76f890..8f5418f95a 100644 --- a/CRM/Contact/Import/Parser/Contact.php +++ b/CRM/Contact/Import/Parser/Contact.php @@ -120,14 +120,13 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { * @param $customFieldID * @param array $customFields * @param array $params - * @param array $addressCustomFields * @param $value * @param string $key * @param $dateType * * @return ?string */ - private function validateCustomField($customFieldID, array $customFields, array $params, array $addressCustomFields, $value, string $key, $dateType): ?string { + private function validateCustomField($customFieldID, array $customFields, array $params, $value, string $key, $dateType): ?string { if (!array_key_exists($customFieldID, $customFields)) { return ts('field ID'); } @@ -136,11 +135,6 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { return $customFields[$customFieldID]['label'] . '::' . $customFields[$customFieldID]['groupTitle']; } - //For address custom fields, we do get actual custom field value as an inner array of - //values so need to modify - if (array_key_exists($customFieldID, $addressCustomFields)) { - $value = $value[0][$key]; - } /* validate the data against the CF type */ if ($value) { @@ -148,15 +142,10 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { $htmlType = $customFields[$customFieldID]['html_type']; $isSerialized = CRM_Core_BAO_CustomField::isSerialized($customFields[$customFieldID]); if ($dataType == 'Date') { - if (array_key_exists($customFieldID, $addressCustomFields) && CRM_Utils_Date::convertToDefaultDate($params[$key][0], $dateType, $key)) { - $value = $params[$key][0][$key]; - } - elseif (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) { - $value = $params[$key]; - } - else { - return $customFields[$customFieldID]['label']; + if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) { + return NULL; } + return $customFields[$customFieldID]['label']; } elseif ($dataType == 'Boolean') { if (CRM_Utils_String::strtoboolstr($value) === FALSE) { @@ -1225,12 +1214,26 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { } $addressCustomFields = CRM_Core_BAO_CustomField::getFields('Address'); - $customFields = $customFields + $addressCustomFields; + $parser = new CRM_Contact_Import_Parser_Contact(); foreach ($params as $key => $value) { if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) { - /* check if it's a valid custom field id */ - $parser = new CRM_Contact_Import_Parser_Contact(); - $errors[] = $parser->validateCustomField($customFieldID, $customFields, $params, $addressCustomFields, $value, $key, $dateType); + //For address custom fields, we do get actual custom field value as an inner array of + //values so need to modify + if (array_key_exists($customFieldID, $addressCustomFields)) { + $value = $value[0][$key]; + $dataType = $addressCustomFields[$customFieldID]['data_type']; + if ($dataType === 'Date') { + $input = ['custom_' . $customFieldID => $value]; + } + else { + $input = $params; + } + $errors[] = $parser->validateCustomField($customFieldID, $addressCustomFields, $input, $value, $key, $dateType); + } + else { + /* check if it's a valid custom field id */ + $errors[] = $parser->validateCustomField($customFieldID, $customFields, $params, $value, $key, $dateType); + } } elseif (is_array($params[$key]) && isset($params[$key]["contact_type"])) { //CRM-5125 diff --git a/tests/phpunit/CRM/Contact/Import/Form/data/individual_dates_type1.csv b/tests/phpunit/CRM/Contact/Import/Form/data/individual_dates_type1.csv new file mode 100644 index 0000000000..f0e0ce17c6 --- /dev/null +++ b/tests/phpunit/CRM/Contact/Import/Form/data/individual_dates_type1.csv @@ -0,0 +1,8 @@ +first_name,Last Name,Birth Date,Deceased Date,Custom Date One,Custom Date Two,Street Address,Type,expected +Joe,1,2008-09-01,2008-09-01,2008-09-01,2008-09-01,10 Downing St,1,Valid +Joe,2,20080901,20080901,20080901,20080901,11 Downing St,1,Valid +Joe,3,2008-9-1 ,2008-9-1 ,2008-9-1 ,2008-9-1 ,12 Downing St,1,Valid +Joe,3,2008-25-1 ,2008-9-1 ,2008-9-1 ,2008-9-1 ,12 Downing St,1,Invalid +Joe,3,2008-9-1 ,2008-25-1 ,2008-9-1 ,2008-9-1 ,12 Downing St,1,Invalid +Joe,3,2008-9-1 ,2008-9-1 ,2008-25-1 ,2008-9-1 ,12 Downing St,1,Invalid +Joe,3,2008-9-1 ,2008-9-1 ,2008-9-1 ,2008-25-1 ,12 Downing St,1,Invalid diff --git a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php index b4d263bb6e..c0dae22d37 100644 --- a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php +++ b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php @@ -14,6 +14,7 @@ * File for the CRM_Contact_Imports_Parser_ContactTest class. */ +use Civi\Api4\Address; use Civi\Api4\Contact; use Civi\Api4\RelationshipType; use Civi\Api4\UserJob; @@ -850,7 +851,7 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { * Test the determination of whether a custom field is valid. */ public function testCustomFieldValidation(): void { - $errorMessage = []; + $errorMessage = ''; $customGroup = $this->customGroupCreate([ 'extends' => 'Contact', 'title' => 'ABC', @@ -860,7 +861,7 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { 'custom_' . $customField['id'] => 'Label1|Label2', ]; CRM_Contact_Import_Parser_Contact::isErrorInCustomData($params, $errorMessage); - $this->assertEquals([], $errorMessage); + $this->assertEquals(NULL, $errorMessage); } /** @@ -1037,6 +1038,40 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { $this->assertCount(8, $contacts); } + /** + * @throws \Civi\API\Exception\UnauthorizedException + * @throws \API_Exception + * @throws \CRM_Core_Exception + */ + public function testValidateDateData(): void { + $addressCustomGroupID = $this->createCustomGroup(['extends' => 'Address', 'name' => 'Address']); + $contactCustomGroupID = $this->createCustomGroup(['extends' => 'Contact', 'name' => 'Contact']); + $addressCustomFieldID = $this->createDateCustomField(['custom_group_id' => $addressCustomGroupID])['id']; + $contactCustomFieldID = $this->createDateCustomField(['custom_group_id' => $contactCustomGroupID])['id']; + $csv = 'individual_dates_type1.csv'; + $dateType = CRM_Core_Form_Date::DATE_yyyy_mm_dd; + $mapper = [ + ['first_name'], + ['last_name'], + ['birth_date'], + ['deceased_date'], + ['custom_' . $contactCustomFieldID], + ['custom_' . $addressCustomFieldID, 1], + ['street_address', 1], + ['do_not_import'], + ]; + // Date types should be picked up from submitted values but still some clean up to do. + CRM_Core_Session::singleton()->set('dateTypes', $dateType); + $this->validateMultiRowCsv($csv, $mapper, 'custom_' . $addressCustomFieldID, ['dateFormats' => $dateType]); + $fields = ['contact_id.birth_date', 'contact_id.deceased_date', 'contact_id.custom_' . $contactCustomFieldID, $addressCustomFieldID]; + $contacts = Address::get()->addWhere('contact_id.first_name', '=', 'Joe')->setSelect($fields)->execute(); + foreach ($contacts as $contact) { + foreach ($fields as $field) { + $this->assertEquals('2008-09-01', $contact[$field]); + } + } + } + /** * Test that setting duplicate action to fill doesn't blow away data * that exists, but does fill in where it's empty. @@ -1519,4 +1554,34 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { $form->postProcess(); } + /** + * @param string $csv + * @param array $mapper + * @param string $field + * @param array $submittedValues + * Values submitted in the form process. + * + * @throws \API_Exception + * @throws \CRM_Core_Exception + * @throws \Civi\API\Exception\UnauthorizedException + */ + private function validateMultiRowCsv(string $csv, array $mapper, string $field, $submittedValues): void { + /* @var CRM_Import_DataSource_CSV $dataSource */ + /* @var \CRM_Contact_Import_Parser_Contact $parser */ + [$dataSource, $parser] = $this->getDataSourceAndParser($csv, $mapper, $submittedValues); + while ($values = $dataSource->getRow()) { + try { + $parser->validateValues(array_values($values)); + if ($values['expected'] !== 'Valid') { + $this->fail($values[$field] . ' should not have been valid'); + } + } + catch (CRM_Core_Exception $e) { + if ($values['expected'] !== 'Invalid') { + $this->fail($values[$field] . ' should have been valid'); + } + } + } + } + } -- 2.25.1