From 38019b927b0ee8ebfba11165e860146853c1161d Mon Sep 17 00:00:00 2001 From: eileen Date: Fri, 28 Aug 2020 15:49:22 +1200 Subject: [PATCH] Add line item acl tests --- ext/financialacls/phpunit.xml.dist | 18 +++ .../tests/phpunit/LineItemTest.php | 114 ++++++++++++++++++ ext/financialacls/tests/phpunit/bootstrap.php | 63 ++++++++++ 3 files changed, 195 insertions(+) create mode 100644 ext/financialacls/phpunit.xml.dist create mode 100644 ext/financialacls/tests/phpunit/LineItemTest.php create mode 100644 ext/financialacls/tests/phpunit/bootstrap.php diff --git a/ext/financialacls/phpunit.xml.dist b/ext/financialacls/phpunit.xml.dist new file mode 100644 index 0000000000..fc8f870b72 --- /dev/null +++ b/ext/financialacls/phpunit.xml.dist @@ -0,0 +1,18 @@ + + + + + ./tests/phpunit + + + + + ./ + + + + + + + + diff --git a/ext/financialacls/tests/phpunit/LineItemTest.php b/ext/financialacls/tests/phpunit/LineItemTest.php new file mode 100644 index 0000000000..71eb6380c4 --- /dev/null +++ b/ext/financialacls/tests/phpunit/LineItemTest.php @@ -0,0 +1,114 @@ +installMe(__DIR__) + ->apply(); + } + + /** + * Test api applies permissions on line item actions (delete & get). + */ + public function testLineItemApiPermissions() { + $contact1 = $this->individualCreate(); + $defaultPriceFieldID = $this->getDefaultPriceFieldID(); + $this->callAPISuccess('Order', 'create', [ + 'financial_type_id' => 'Donation', + 'contact_id' => $contact1, + 'line_items' => [ + [ + 'line_item' => [ + [ + 'financial_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Donation'), + 'line_total' => 40, + 'price_field_id' => $defaultPriceFieldID, + 'qty' => 1, + ], + [ + 'financial_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Member Dues'), + 'line_total' => 50, + 'price_field_id' => $defaultPriceFieldID, + 'qty' => 1, + ], + ], + ], + ], + ]); + + $this->setPermissions([ + 'access CiviCRM', + 'access CiviContribute', + 'edit contributions', + 'delete in CiviContribute', + 'view contributions of type Donation', + 'delete contributions of type Donation', + ]); + Civi::settings()->set('acl_financial_type', TRUE); + $this->createLoggedInUser(); + + $lineItems = $this->callAPISuccess('LineItem', 'get', ['sequential' => TRUE])['values']; + $this->assertCount(2, $lineItems); + $this->callAPISuccessGetCount('LineItem', ['check_permissions' => TRUE], 1); + + $this->callAPISuccess('LineItem', 'Delete', ['check_permissions' => TRUE, 'id' => $lineItems[0]['id']]); + $this->callAPIFailure('LineItem', 'Delete', ['check_permissions' => TRUE, 'id' => $lineItems[1]['id']]); + } + + /** + * Set ACL permissions, overwriting any existing ones. + * + * @param array $permissions + * Array of permissions e.g ['access CiviCRM','access CiviContribute'], + */ + protected function setPermissions($permissions) { + CRM_Core_Config::singleton()->userPermissionClass->permissions = $permissions; + if (isset(\Civi::$statics['CRM_Financial_BAO_FinancialType'])) { + unset(\Civi::$statics['CRM_Financial_BAO_FinancialType']); + } + } + + /** + * @return mixed + * @throws \API_Exception + * @throws \Civi\API\Exception\UnauthorizedException + */ + protected function getDefaultPriceFieldID(): int { + return PriceField::get() + ->addWhere('price_set_id:name', '=', 'default_contribution_amount') + ->addWhere('name', '=', 'contribution_amount') + ->addWhere('html_type', '=', 'Text') + ->addSelect('id')->execute()->first()['id']; + } + +} diff --git a/ext/financialacls/tests/phpunit/bootstrap.php b/ext/financialacls/tests/phpunit/bootstrap.php new file mode 100644 index 0000000000..a5b49253c8 --- /dev/null +++ b/ext/financialacls/tests/phpunit/bootstrap.php @@ -0,0 +1,63 @@ +add('CRM_', __DIR__); +$loader->add('Civi\\', __DIR__); +$loader->add('api_', __DIR__); +$loader->add('api\\', __DIR__); +$loader->register(); + +/** + * Call the "cv" command. + * + * @param string $cmd + * The rest of the command to send. + * @param string $decode + * Ex: 'json' or 'phpcode'. + * @return string + * Response output (if the command executed normally). + * @throws \RuntimeException + * If the command terminates abnormally. + */ +function cv($cmd, $decode = 'json') { + $cmd = 'cv ' . $cmd; + $descriptorSpec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => STDERR); + $oldOutput = getenv('CV_OUTPUT'); + putenv("CV_OUTPUT=json"); + + // Execute `cv` in the original folder. This is a work-around for + // phpunit/codeception, which seem to manipulate PWD. + $cmd = sprintf('cd %s; %s', escapeshellarg(getenv('PWD')), $cmd); + + $process = proc_open($cmd, $descriptorSpec, $pipes, __DIR__); + putenv("CV_OUTPUT=$oldOutput"); + fclose($pipes[0]); + $result = stream_get_contents($pipes[1]); + fclose($pipes[1]); + if (proc_close($process) !== 0) { + throw new RuntimeException("Command failed ($cmd):\n$result"); + } + switch ($decode) { + case 'raw': + return $result; + + case 'phpcode': + // If the last output is /*PHPCODE*/, then we managed to complete execution. + if (substr(trim($result), 0, 12) !== "/*BEGINPHP*/" || substr(trim($result), -10) !== "/*ENDPHP*/") { + throw new \RuntimeException("Command failed ($cmd):\n$result"); + } + return $result; + + case 'json': + return json_decode($result, 1); + + default: + throw new RuntimeException("Bad decoder format ($decode)"); + } +} -- 2.25.1