* @copyright CiviCRM LLC https://civicrm.org/licensing
*/
-
namespace api\v4\Entity;
+use api\v4\Service\TestCreationParameterProvider;
use api\v4\Traits\CheckAccessTrait;
use api\v4\Traits\OptionCleanupTrait;
use api\v4\Traits\TableDropperTrait;
use Civi\Api4\Event\ValidateValuesEvent;
use Civi\Api4\Service\Spec\CustomFieldSpec;
use Civi\Api4\Service\Spec\FieldSpec;
+use Civi\Api4\Service\Spec\SpecGatherer;
use Civi\Api4\Utils\CoreUtil;
use Civi\Core\Event\PostEvent;
use Civi\Core\Event\PreEvent;
/**
* Set up baseline for testing
+ *
+ * @throws \CRM_Core_Exception
*/
public function setUp(): void {
// Enable all components
$this->setUpOptionCleanup();
$this->loadDataSet('CaseType');
$this->loadDataSet('ConformanceTest');
- $this->creationParamProvider = \Civi::container()->get('test.param_provider');
+ $gatherer = new SpecGatherer();
+ $this->creationParamProvider = new TestCreationParameterProvider($gatherer);
parent::setUp();
$this->resetCheckAccess();
}
* @return array
*
* @throws \API_Exception
- * @throws \Civi\API\Exception\UnauthorizedException
+ * @throws \CRM_Core_Exception
*/
- public function getEntitiesHitech() {
+ public function getEntitiesHitech(): array {
// Ensure all components are enabled so their entities show up
foreach (array_keys(\CRM_Core_Component::getComponents()) as $component) {
\CRM_Core_BAO_ConfigSetting::enableComponent($component);
*
* @return array
*/
- public function getEntitiesLotech() {
+ public function getEntitiesLotech(): array {
$manual['add'] = [];
$manual['remove'] = ['CustomValue'];
$manual['transform'] = ['CiviCase' => 'Case'];
* Ensure that "getEntitiesLotech()" (which is the 'dataProvider') is up to date
* with "getEntitiesHitech()" (which is a live feed available entities).
*/
- public function testEntitiesProvider() {
+ public function testEntitiesProvider(): void {
$this->assertEquals($this->getEntitiesHitech(), $this->getEntitiesLotech(), "The lo-tech list of entities does not match the hi-tech list. You probably need to update getEntitiesLotech().");
}
/**
* @param string $entity
* @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
- *
- * @return mixed
*/
- protected function checkCreationDenied($entity, $entityClass) {
+ protected function checkCreationDenied(string $entity, $entityClass): void {
$this->setCheckAccessGrants(["{$entity}::create" => FALSE]);
$this->assertEquals(0, $this->checkAccessCounts["{$entity}::create"]);
* @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
* @param int $id
*/
- protected function checkUpdateFailsFromCreate($entityClass, $id): void {
+ protected function checkUpdateFailsFromCreate($entityClass, int $id): void {
$exceptionThrown = '';
try {
$entityClass::create(FALSE)
* @param int $id
* @param string $entity
*/
- protected function checkGet($entityClass, $id, $entity) {
+ protected function checkGet($entityClass, int $id, string $entity): void {
$getResult = $entityClass::get(FALSE)
->addWhere('id', '=', $id)
->execute();
}
/**
- * @param $entity
+ * Get the required fields for the api entity + action.
+ *
+ * @param string $entity
*
* @return array
+ * @throws \API_Exception
*/
- public function getRequired($entity) {
- $createSpec = $this->gatherer->getSpec($entity, 'create', FALSE);
- $requiredFields = array_merge($createSpec->getRequiredFields(), $createSpec->getConditionalRequiredFields());
+ public function getRequired(string $entity) {
+ $requiredFields = civicrm_api4($entity, 'getfields', [
+ 'action' => 'create',
+ 'loadOptions' => TRUE,
+ 'where' => [
+ ['OR', [['required', '=', TRUE], ['required_if', 'IS NOT EMPTY']]],
+ ],
+ ], 'name');
$requiredParams = [];
- foreach ($requiredFields as $requiredField) {
- $requiredParams[$requiredField->getName()] = $this->getRequiredValue($requiredField);
+ foreach ($requiredFields as $fieldName => $requiredField) {
+ $requiredParams[$fieldName] = $this->getRequiredValue($requiredField);
}
// This is a ruthless hack to avoid peculiar constraints - but
* Attempt to get a value using field option, defaults, FKEntity, or a random
* value based on the data type.
*
- * @param \Civi\Api4\Service\Spec\FieldSpec $field
+ * @param array $field
*
* @return mixed
* @throws \Exception
*/
- private function getRequiredValue(FieldSpec $field) {
+ private function getRequiredValue(array $field) {
- if ($field->getOptions()) {
- return $this->getOption($field);
+ if (!empty($field['options'])) {
+ return key($field['options']);
}
- elseif ($field->getFkEntity()) {
- return $this->getFkID($field, $field->getFkEntity());
+ if (!empty($field['fk_entity'])) {
+ return $this->getFkID($field['fk_entity']);
}
- elseif ($field->getDefaultValue()) {
- return $field->getDefaultValue();
+ if (isset($field['default_value'])) {
+ return $field['default_value'];
}
- elseif ($field->getName() === 'contact_id') {
- return $this->getFkID($field, 'Contact');
+ if ($field['name'] === 'contact_id') {
+ return $this->getFkID('Contact');
}
- elseif ($field->getName() === 'entity_id') {
+ if ($field['name'] === 'entity_id') {
// What could possibly go wrong with this?
- switch ($field->getTableName()) {
+ switch ($field['table_name']) {
case 'civicrm_financial_item':
- return $this->getFkID($field, FinancialItemCreationSpecProvider::DEFAULT_ENTITY);
+ return $this->getFkID(FinancialItemCreationSpecProvider::DEFAULT_ENTITY);
default:
- return $this->getFkID($field, 'Contact');
+ return $this->getFkID('Contact');
}
}
- $randomValue = $this->getRandomValue($field->getDataType());
+ $randomValue = $this->getRandomValue($field['data_type']);
if ($randomValue) {
return $randomValue;
}
- throw new \Exception('Could not provide default value');
+ throw new \API_Exception('Could not provide default value');
}
/**
}
/**
- * @param \Civi\Api4\Service\Spec\FieldSpec $field
+ * Get an ID for the appropriate entity.
+ *
* @param string $fkEntity
*
* @return mixed
- * @throws \Exception
+ *
+ * @throws \API_Exception
*/
- private function getFkID(FieldSpec $field, $fkEntity) {
+ private function getFkID(string $fkEntity) {
$params = ['checkPermissions' => FALSE];
// Be predictable about what type of contact we select
if ($fkEntity === 'Contact') {
$entityList = civicrm_api4($fkEntity, 'get', $params);
if ($entityList->count() < 1) {
$msg = sprintf('At least one %s is required in test', $fkEntity);
- throw new \Exception($msg);
+ throw new \API_Exception($msg);
}
return $entityList->last()['id'];
return TRUE;
case 'Integer':
- return rand(1, 2000);
+ return random_int(1, 2000);
case 'String':
return \CRM_Utils_String::createRandom(10, implode('', range('a', 'z')));