From 93afa299d10822c5680b59c2259ca3e14357bcd2 Mon Sep 17 00:00:00 2001 From: Aidan Saunders Date: Fri, 25 Nov 2022 20:42:03 +0000 Subject: [PATCH] Make MessageTemplate.master_id fully joinable Move Calculated Field tests out of BAO tests - they're not BAO Enhance test to check fields of master_id entity are returned. --- .../MessageTemplateSchemaMapSubscriber.php | 51 +++++++++++++++++++ .../MessageTemplateGetSpecProvider.php | 17 +------ .../CRM/Core/BAO/MessageTemplateTest.php | 39 -------------- .../api/v4/Entity/MessageTemplateTest.php | 51 +++++++++++++++++++ 4 files changed, 103 insertions(+), 55 deletions(-) create mode 100644 Civi/Api4/Event/Subscriber/MessageTemplateSchemaMapSubscriber.php diff --git a/Civi/Api4/Event/Subscriber/MessageTemplateSchemaMapSubscriber.php b/Civi/Api4/Event/Subscriber/MessageTemplateSchemaMapSubscriber.php new file mode 100644 index 000000000000..3f218f31c65b --- /dev/null +++ b/Civi/Api4/Event/Subscriber/MessageTemplateSchemaMapSubscriber.php @@ -0,0 +1,51 @@ + 'onSchemaBuild', + ]; + } + + /** + * This creates a joinable which gets exposed and rendered by: + * + * @see \Civi\Api4\Service\Spec\Provider\MessageTemplateGetSpecProvider + * + * @param \Civi\Api4\Event\SchemaMapBuildEvent $event + * + * Condition based on CRM_Admin_Page_MessageTemplates::__construct() + */ + public function onSchemaBuild(SchemaMapBuildEvent $event) { + $schema = $event->getSchemaMap(); + $table = $schema->getTableByName('civicrm_msg_template'); + + $link = new Joinable("civicrm_msg_template", 'id', "master_id"); + $link->setBaseTable('civicrm_msg_template'); + $link->setJoinType(Joinable::JOIN_TYPE_ONE_TO_ONE); + $link->addCondition("`{target_table}`.`id` = + (SELECT `id` FROM `civicrm_msg_template` `orig` + WHERE `{base_table}`.`workflow_name` = `orig`.`workflow_name` AND `orig`.`is_reserved` = 1 AND + ( `{base_table}`.`msg_subject` != `orig`.`msg_subject` OR + `{base_table}`.`msg_text` != `orig`.`msg_text` OR + `{base_table}`.`msg_html` != `orig`.`msg_html` + ))" + ); + $table->addTableLink(NULL, $link); + } + +} diff --git a/Civi/Api4/Service/Spec/Provider/MessageTemplateGetSpecProvider.php b/Civi/Api4/Service/Spec/Provider/MessageTemplateGetSpecProvider.php index ca8714e0e30f..3999d6a00d6a 100644 --- a/Civi/Api4/Service/Spec/Provider/MessageTemplateGetSpecProvider.php +++ b/Civi/Api4/Service/Spec/Provider/MessageTemplateGetSpecProvider.php @@ -23,7 +23,7 @@ public function modifySpec(RequestSpec $spec) { ->setInputType('Select') ->setReadonly(TRUE) ->setFkEntity('MessageTemplate') - ->setSqlRenderer([__CLASS__, 'revertible']); + ->setSqlRenderer(['\Civi\Api4\Service\Schema\Joiner', 'getExtraJoinSql']); $spec->addFieldSpec($field); } @@ -37,19 +37,4 @@ public function applies($entity, $action) { return $entity === 'MessageTemplate' && $action === 'get'; } - /** - * Callback for finding id of template to revert to - * Based on CRM_Admin_Page_MessageTemplates::__construct() - * - * @return string - */ - public static function revertible(): string { - return "(SELECT `id` FROM `civicrm_msg_template` `orig` - WHERE `a`.`workflow_name` = `orig`.`workflow_name` AND `orig`.`is_reserved` = 1 AND - ( `a`.`msg_subject` != `orig`.`msg_subject` OR - `a`.`msg_text` != `orig`.`msg_text` OR - `a`.`msg_html` != `orig`.`msg_html` - ))"; - } - } diff --git a/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php b/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php index eb9780f4fb57..095dd65b1b62 100644 --- a/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php +++ b/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php @@ -341,45 +341,6 @@ public function testCaseActivityCopyTemplate():void { $this->assertStringContainsString('Case ID : 1234', $message); } - /** - * Test APIv4 calculated field master_id - */ - public function testMessageTemplateMasterID() { - CRM_Core_Transaction::create(TRUE)->run(function(CRM_Core_Transaction $tx) { - $tx->rollback(); - - $messageTemplateID = MessageTemplate::get() - ->addWhere('is_default', '=', 1) - ->addWhere('workflow_name', '=', 'contribution_offline_receipt') - ->addSelect('id') - ->execute()->first()['id']; - $messageTemplateIDReserved = MessageTemplate::get() - ->addWhere('is_reserved', '=', 1) - ->addWhere('workflow_name', '=', 'contribution_offline_receipt') - ->addSelect('id') - ->execute()->first()['id']; - $master_id = MessageTemplate::get() - ->addSelect('master_id') - ->addWhere('id', '=', $messageTemplateID) - ->execute()->first()['master_id']; - $this->assertNull($master_id); - - MessageTemplate::update() - ->addWhere('id', '=', $messageTemplateID) - ->setValues([ - 'msg_subject' => 'Hello world', - 'msg_text' => 'Hello world', - 'msg_html' => '

Hello world

', - ]) - ->execute(); - $master_id = MessageTemplate::get() - ->addSelect('master_id') - ->addWhere('id', '=', $messageTemplateID) - ->execute()->first()['master_id']; - $this->assertEquals($master_id, $messageTemplateIDReserved); - }); - } - /** * Test rendering of domain tokens. * diff --git a/tests/phpunit/api/v4/Entity/MessageTemplateTest.php b/tests/phpunit/api/v4/Entity/MessageTemplateTest.php index 1836a7df3073..f6989cc6a645 100644 --- a/tests/phpunit/api/v4/Entity/MessageTemplateTest.php +++ b/tests/phpunit/api/v4/Entity/MessageTemplateTest.php @@ -22,6 +22,7 @@ use Civi\Test\DbTestTrait; use Civi\Test\GenericAssertionsTrait; use Civi\Test\TransactionalInterface; +use Civi\Api4\MessageTemplate; /** * @group headless @@ -134,4 +135,54 @@ public function testSaveNullId() { $this->assertDBQuery('

My body as HTML

', 'SELECT msg_html FROM civicrm_msg_template WHERE id = %1', [1 => [$saved['id'], 'Int']]); } + /** + * Test APIv4 calculated field master_id + */ + public function testMessageTemplateMasterID() { + \CRM_Core_Transaction::create(TRUE)->run(function(\CRM_Core_Transaction $tx) { + $tx->rollback(); + + $messageTemplateID = MessageTemplate::get() + ->addWhere('is_default', '=', 1) + ->addWhere('workflow_name', '=', 'contribution_offline_receipt') + ->addSelect('id') + ->execute()->first()['id']; + $messageTemplateIDReserved = MessageTemplate::get() + ->addWhere('is_reserved', '=', 1) + ->addWhere('workflow_name', '=', 'contribution_offline_receipt') + ->addSelect('id') + ->execute()->first()['id']; + $msgTpl = MessageTemplate::get() + ->addSelect('msg_subject', 'master_id', 'master_id.msg_subject') + ->addWhere('id', '=', $messageTemplateID) + ->execute()->first(); + // confirm subject is set + $this->assertNotNull($msgTpl['msg_subject']); + // message is unchanged from original so both of these should be null + $this->assertNull($msgTpl['master_id']); + $this->assertNull($msgTpl['master_id.msg_subject']); + + MessageTemplate::update() + ->addWhere('id', '=', $messageTemplateID) + ->setValues([ + 'msg_subject' => 'Hello world', + 'msg_text' => 'Hello world', + 'msg_html' => '

Hello world

', + ]) + ->execute(); + $msgTpl = MessageTemplate::get() + ->addSelect('msg_subject', 'master_id', 'master_id.msg_subject') + ->addWhere('id', '=', $messageTemplateID) + ->execute()->first(); + // confirm subject is set + $this->assertNotNull($msgTpl['msg_subject']); + // message is changed so both of these should be set + $this->assertEquals($msgTpl['master_id'], $messageTemplateIDReserved); + $this->assertNotNull($msgTpl['master_id.msg_subject']); + // these should be different + $this->assertNotEquals($msgTpl['msg_subject'], $msgTpl['master_id.msg_subject']); + + }); + } + }