From bdd382ff64b9fb9fc58e4502d50caf0ff626ae72 Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Mon, 17 May 2021 12:45:14 +1000 Subject: [PATCH] Add in unit test of the submit action and re-work as per feedback from coleman --- .../Civi/Afform/Event/AfformSubmitEvent.php | 26 ++++++++- .../core/{CRM => Civi}/Afform/Utils.php | 28 +++++---- .../core/Civi/Api4/Action/Afform/Submit.php | 37 +++++++----- .../tests/phpunit/CRM/Afform/UtilTest.php | 19 +++---- .../tests/phpunit/api/v4/AfformUsageTest.php | 57 +++++++++++++++++++ 5 files changed, 130 insertions(+), 37 deletions(-) rename ext/afform/core/{CRM => Civi}/Afform/Utils.php (66%) diff --git a/ext/afform/core/Civi/Afform/Event/AfformSubmitEvent.php b/ext/afform/core/Civi/Afform/Event/AfformSubmitEvent.php index c4f968c1b9..4aa1fa4f05 100644 --- a/ext/afform/core/Civi/Afform/Event/AfformSubmitEvent.php +++ b/ext/afform/core/Civi/Afform/Event/AfformSubmitEvent.php @@ -55,7 +55,7 @@ class AfformSubmitEvent extends AfformBaseEvent { * @param string $entityName * @param array $entityIds */ - public function __construct(array $afform, FormDataModel $formDataModel, Submit $apiRequest, $values, string $entityType, string $entityName, array $entityIds) { + public function __construct(array $afform, FormDataModel $formDataModel, Submit $apiRequest, $values, string $entityType, string $entityName, array &$entityIds) { parent::__construct($afform, $formDataModel, $apiRequest); $this->values = $values; $this->entityType = $entityType; @@ -63,4 +63,28 @@ class AfformSubmitEvent extends AfformBaseEvent { $this->entityIds = $entityIds; } + /** + * Set the entity type associated with this event + * @param string $entityType + */ + public function setEntityType(string $entityType): void { + $this->entityType = $entityType; + } + + /** + * Set the values associated with this event + * @param array $values + */ + public function setValues(array $values): void { + $this->values = $values; + } + + /** + * Set the entity name associated with this event + * @param string $entityName + */ + public function setEntityName(string $entityName): void { + $this->entityName = $entityName; + } + } diff --git a/ext/afform/core/CRM/Afform/Utils.php b/ext/afform/core/Civi/Afform/Utils.php similarity index 66% rename from ext/afform/core/CRM/Afform/Utils.php rename to ext/afform/core/Civi/Afform/Utils.php index 4b2d3ec659..c1fe8fff1d 100644 --- a/ext/afform/core/CRM/Afform/Utils.php +++ b/ext/afform/core/Civi/Afform/Utils.php @@ -10,29 +10,33 @@ +--------------------------------------------------------------------+ */ +namespace Civi\Afform; + /** * - * @package CRM + * @package Civi\Afform * @copyright CiviCRM LLC https://civicrm.org/licensing */ -class CRM_Afform_Utils { +class Utils { - public static function getEntityWeights($formEntities, $entityValues) { + public static function getEntityWeights($formEntities, $entityValues) { $entityWeights = $entityMapping = $entitiesToBeProcessed = []; foreach ($formEntities as $entityName => $entity) { $entityWeights[$entityName] = 1; $entityMapping[$entityName] = $entity['type']; - foreach ($entityValues[$entity['type']][$entityName] as $index => $vals) { - foreach ($vals as $field => $value) { - if (array_key_exists($value, $entityWeights)) { - $entityWeights[$entityName] = max((int) $entityWeights[$entityName], (int) ($entityWeights[$value] + 1)); - } - else { - if (!array_key_exists($value, $entitiesToBeProcessed)) { - $entitiesToBeProcessed[$value] = [$entityName]; + foreach ($entityValues[$entity['type']][$entityName] as $record) { + foreach ($record as $index => $vals) { + foreach ($vals as $field => $value) { + if (array_key_exists($value, $entityWeights)) { + $entityWeights[$entityName] = max((int) $entityWeights[$entityName], (int) ($entityWeights[$value] + 1)); } else { - $entitiesToBeProcessed[$value][] = $entityName; + if (!array_key_exists($value, $entitiesToBeProcessed)) { + $entitiesToBeProcessed[$value] = [$entityName]; + } + else { + $entitiesToBeProcessed[$value][] = $entityName; + } } } } diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Submit.php b/ext/afform/core/Civi/Api4/Action/Afform/Submit.php index ddfefa5917..f639dcc0b1 100644 --- a/ext/afform/core/Civi/Api4/Action/Afform/Submit.php +++ b/ext/afform/core/Civi/Api4/Action/Afform/Submit.php @@ -20,9 +20,10 @@ class Submit extends AbstractProcessor { protected $values; protected function processForm() { - $entityValues = $entityIds = []; + $entityValues = $entityIds = $entityMapping = []; foreach ($this->_formDataModel->getEntities() as $entityName => $entity) { $entityIds[$entityName] = NULL; + $entityMapping[$entityName] = $entity['type']; foreach ($this->values[$entityName] ?? [] as $values) { $entityValues[$entity['type']][$entityName][] = $values + ['fields' => []]; // Predetermined values override submitted values @@ -33,13 +34,27 @@ class Submit extends AbstractProcessor { } } } - $entityWeights = \CRM_Afform_Utils::getEntityWeights($this->_formDataModel->getEntities(), $entityValues); + $entityWeights = \Civi\Afform\Utils::getEntityWeights($this->_formDataModel->getEntities(), $entityValues); + $event = new AfformSubmitEvent($this->_afform, $this->_formDataModel, $this, [], '', '', $entityIds); foreach ($entityWeights as $entity => $weight) { - $values = $entityValues[$entityMapping[$entity]][$entity]; - $event = new AfformSubmitEvent($this->_afform, $this->_formDataModel, $this, $values, $entityMapping[$entity], $entity, $entityIds); - \Civi::dispatcher()->dispatch(self::EVENT_NAME, $event); + $eValues = $entityValues[$entityMapping[$entity]][$entity]; + // Replace Entity reference fields that reference other form based entities with their created ids. + foreach ($eValues as $key => $record) { + foreach ($record as $k => $v) { + foreach ($v as $field => $value) { + if (array_key_exists($value, $event->entityIds) && !empty($event->entityIds[$value])) { + $eValues[$key][$k][$field] = $event->entityIds[$value]; + } + } + } + $event->setValues($eValues[$key]); + $event->setEntityName($entity); + $event->setEntityType($entityMapping[$entity]); + \Civi::dispatcher()->dispatch(self::EVENT_NAME, $event); + } + unset($entityValues[$entityMapping[$entity]][$entity]); } - foreach ($event->entityValues as $entityType => $entities) { + foreach ($entityValues as $entityType => $entities) { if (!empty($entities)) { throw new \API_Exception(sprintf("Failed to process entities (type=%s; name=%s)", $entityType, implode(',', array_keys($entities)))); } @@ -76,15 +91,9 @@ class Submit extends AbstractProcessor { } $entityName = $event->entityName; $api4 = $event->formDataModel->getSecureApi4($event->entityName); - // Replace Entity reference fields that reference other form based entities with their created ids. - foreach ($record['fields'] as $field => $value) { - if (array_key_exists($value, $event->entityIds) && !empty($event->entityIds[$value])) { - $record['fields'][$field] = $event->entityIds[$value]; - } - } - $saved = $api4($entityType, 'save', ['records' => [$event->values['fields']]])->first(); + $saved = $api4($event->entityType, 'save', ['records' => [$event->values['fields']]])->first(); $event->entityIds[$entityName] = $saved['id']; - self::saveJoins($entityType, $saved['id'], $event->values['joins'] ?? []); + self::saveJoins($event->entityType, $saved['id'], $event->values['joins'] ?? []); } protected static function saveJoins($mainEntityName, $entityId, $joins) { diff --git a/ext/afform/core/tests/phpunit/CRM/Afform/UtilTest.php b/ext/afform/core/tests/phpunit/CRM/Afform/UtilTest.php index 7715d9d0d8..6eb2609e98 100644 --- a/ext/afform/core/tests/phpunit/CRM/Afform/UtilTest.php +++ b/ext/afform/core/tests/phpunit/CRM/Afform/UtilTest.php @@ -61,7 +61,6 @@ class CRM_Afform_UtilTest extends \PHPUnit\Framework\TestCase implements Headles $this->assertEquals($expected, $actual); } - public function formEntityWeightExampls() { $exs = []; $exs[] = [ @@ -70,8 +69,8 @@ class CRM_Afform_UtilTest extends \PHPUnit\Framework\TestCase implements Headles 'Activity1' => ['type' => 'Activity', ['fields' => ['source_contact_id']]], ], [ - 'Contact' => ['Individual1' => ['fields' => ['first_name' => 'Test', 'last_name' => 'Contact']]], - 'Activity' => ['Activity1' => ['fields' => ['source_contact_id' => 'Individual1']]], + 'Contact' => ['Individual1' => [['fields' => ['first_name' => 'Test', 'last_name' => 'Contact']]]], + 'Activity' => ['Activity1' => [['fields' => ['source_contact_id' => 'Individual1']]]], ], [ 'Individual1' => 1, @@ -85,9 +84,9 @@ class CRM_Afform_UtilTest extends \PHPUnit\Framework\TestCase implements Headles 'LocBlock1' => ['type' => 'LocBlock', ['fields' => ['event_id']]], ], [ - 'Contact' => ['Individual1' => ['fields' => ['first_name' => 'Test', 'last_name' => 'Contact']]], - 'Event' => ['Event1' => ['fields' => ['created_id' => 'Individual1']]], - 'LocBlock' => ['LocBlock1' => ['fields' => ['event_id' => 'Event1']]], + 'Contact' => ['Individual1' => [['fields' => ['first_name' => 'Test', 'last_name' => 'Contact']]]], + 'Event' => ['Event1' => [['fields' => ['created_id' => 'Individual1']]]], + 'LocBlock' => ['LocBlock1' => [['fields' => ['event_id' => 'Event1']]]], ], [ 'Individual1' => 1, @@ -102,9 +101,9 @@ class CRM_Afform_UtilTest extends \PHPUnit\Framework\TestCase implements Headles 'Event1' => ['type' => 'Event', ['fields' => ['created_id']]], ], [ - 'Contact' => ['Individual1' => ['fields' => ['first_name' => 'Test', 'last_name' => 'Contact']]], - 'LocBlock' => ['LocBlock1' => ['fields' => ['event_id' => 'Event1']]], - 'Event' => ['Event1' => ['fields' => ['created_id' => 'Individual1']]], + 'Contact' => ['Individual1' => [['fields' => ['first_name' => 'Test', 'last_name' => 'Contact']]]], + 'LocBlock' => ['LocBlock1' => [['fields' => ['event_id' => 'Event1']]]], + 'Event' => ['Event1' => [['fields' => ['created_id' => 'Individual1']]]], ], [ 'Individual1' => 1, @@ -119,7 +118,7 @@ class CRM_Afform_UtilTest extends \PHPUnit\Framework\TestCase implements Headles * @dataProvider formEntityWeightExampls */ public function testEntityWeights($formEntities, $entityValues, $expectedWeights) { - $this->assertEquals($expectedWeights, CRM_Afform_Utils::getEntityWeights($formEntities, $entityValues)); + $this->assertEquals($expectedWeights, \Civi\Afform\Utils::getEntityWeights($formEntities, $entityValues)); } } diff --git a/ext/afform/mock/tests/phpunit/api/v4/AfformUsageTest.php b/ext/afform/mock/tests/phpunit/api/v4/AfformUsageTest.php index f13d6fa55d..6c39003d46 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/AfformUsageTest.php +++ b/ext/afform/mock/tests/phpunit/api/v4/AfformUsageTest.php @@ -23,6 +23,20 @@ class api_v4_AfformUsageTest extends api_v4_AfformTestCase { +EOHTML; + self::$layouts['registerSite'] = << + + +
+ + +
+
+ Activity 1 + +
+ EOHTML; } @@ -71,6 +85,49 @@ EOHTML; $this->assertEquals('Lasty', $contact['last_name']); } + public function testRegisterSite(): void { + $this->useValues([ + 'layout' => self::$layouts['registerSite'], + 'permission' => CRM_Core_Permission::ALWAYS_ALLOW_PERMISSION, + ]); + + CRM_Core_Config::singleton()->userPermissionTemp = new CRM_Core_Permission_Temp(); + + $values = [ + 'Individual1' => [ + [ + 'fields' => [ + 'first_name' => 'Test Register', + 'last_name' => 'site', + 'source' => 'test source', + ], + ], + ], + 'Activity1' => [ + [ + 'fields' => [ + 'subject' => 'Test Register Site Form Submission', + ], + ], + ], + ]; + Civi\Api4\Afform::submit() + ->setName($this->formName) + ->setArgs([]) + ->setValues($values) + ->execute(); + // Check that Activity was submitted correctly. + $activity = \Civi\Api4\Activity::get()->setCheckPermissions(FALSE)->execute()->first(); + $this->assertEquals('Test Register Site Form Submission', $activity['subject']); + $contact = \Civi\Api4\Contact::get()->addWhere('first_name', '=', 'Test Register')->execute()->first(); + $this->assertEquals('site', $contact['last_name']); + // Check that the data overrides form submsision + $this->assertEquals('Register A site', $contact['source']); + // Check that the contact and the activity were correctly linked up as per the form. + $this->callAPISuccess('ActivityContact', 'get', ['contact_id' => $contact['id'], 'activity_id' => $activity['id']]); + + } + public function testAboutMeForbidden(): void { $this->useValues([ 'layout' => self::$layouts['aboutMe'], -- 2.25.1