APIv4 - Simplify entity creation in test suite
authorColeman Watts <coleman@civicrm.org>
Wed, 11 May 2022 11:19:29 +0000 (07:19 -0400)
committerColeman Watts <coleman@civicrm.org>
Wed, 11 May 2022 13:57:47 +0000 (09:57 -0400)
Removes the old v3 creation and hardcoded sample data in favor of
new `createTestRecord` and `saveTestRecords` methods which automatically
handle cleanup during tearDown.

29 files changed:
CRM/Core/BAO/CustomGroup.php
Civi/Api4/Service/Spec/Provider/CustomGroupSpecProvider.php
Civi/Api4/Service/Spec/Provider/MembershipTypeCreationSpecProvider.php [new file with mode: 0644]
tests/phpunit/CRM/Core/BAO/ActionScheduleTest.php
tests/phpunit/api/v4/Action/ComplexQueryTest.php [deleted file]
tests/phpunit/api/v4/Action/ContactGetTest.php
tests/phpunit/api/v4/Action/FkJoinTest.php
tests/phpunit/api/v4/Action/IsPrimaryTest.php
tests/phpunit/api/v4/Api4TestBase.php
tests/phpunit/api/v4/Custom/CreateCustomValueTest.php
tests/phpunit/api/v4/Custom/CustomFieldAlterTest.php
tests/phpunit/api/v4/Custom/PseudoconstantTest.php
tests/phpunit/api/v4/DataSets/CaseType.json [deleted file]
tests/phpunit/api/v4/DataSets/ConformanceTest.json [deleted file]
tests/phpunit/api/v4/DataSets/DefaultDataSet.json [deleted file]
tests/phpunit/api/v4/DataSets/MultiContactMultiEmail.json [deleted file]
tests/phpunit/api/v4/DataSets/SingleContact.json [deleted file]
tests/phpunit/api/v4/Entity/CaseTest.php
tests/phpunit/api/v4/Entity/ConformanceTest.php
tests/phpunit/api/v4/Entity/ContactJoinTest.php
tests/phpunit/api/v4/Entity/GroupContactTest.php
tests/phpunit/api/v4/Entity/NoteTest.php
tests/phpunit/api/v4/Entity/ParticipantTest.php
tests/phpunit/api/v4/Entity/ValidateValuesTest.php
tests/phpunit/api/v4/Query/Api4SelectQueryTest.php
tests/phpunit/api/v4/Query/OptionValueJoinTest.php
tests/phpunit/api/v4/Query/SelectQueryMultiJoinTest.php
tests/phpunit/api/v4/Service/TestCreationParameterProvider.php [deleted file]
tests/phpunit/api/v4/Traits/TestDataLoaderTrait.php [deleted file]

index d53aac1c700910425733caa42fa0c0efe12eed24..3b6e9269cf801a4c1f94599bd010b6e1ba246427 100644 (file)
@@ -40,6 +40,8 @@ class CRM_Core_BAO_CustomGroup extends CRM_Core_DAO_CustomGroup implements \Civi
    * @throws \Exception
    */
   public static function create(&$params) {
+    // This is the database default
+    $params += ['extends' => 'Contact'];
     // create custom group dao, populate fields and then save.
     $group = new CRM_Core_DAO_CustomGroup();
     if (isset($params['title'])) {
index 86498fc6fe64f6261d429bc758781faa2ce45435..a49febd215f2d9c355913cbd453ed91d137cc3a8 100644 (file)
@@ -23,7 +23,6 @@ class CustomGroupSpecProvider implements Generic\SpecProviderInterface {
     $action = $spec->getAction();
 
     $spec->getFieldByName('extends')
-      ->setRequired($action === 'create')
       ->setSuffixes(['name', 'label', 'grouping']);
   }
 
diff --git a/Civi/Api4/Service/Spec/Provider/MembershipTypeCreationSpecProvider.php b/Civi/Api4/Service/Spec/Provider/MembershipTypeCreationSpecProvider.php
new file mode 100644 (file)
index 0000000..617d707
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved.                        |
+ |                                                                    |
+ | This work is published under the GNU AGPLv3 license with some      |
+ | permitted exceptions and without any warranty. For full license    |
+ | and copyright information, see https://civicrm.org/licensing       |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Api4\Service\Spec\Provider;
+
+use Civi\Api4\Service\Spec\RequestSpec;
+
+class MembershipTypeCreationSpecProvider implements Generic\SpecProviderInterface {
+
+  /**
+   * @param \Civi\Api4\Service\Spec\RequestSpec $spec
+   */
+  public function modifySpec(RequestSpec $spec): void {
+    $spec->getFieldByName('duration_interval')->setDefaultValue(1);
+  }
+
+  /**
+   * When does this apply.
+   *
+   * @param string $entity
+   * @param string $action
+   *
+   * @return bool
+   */
+  public function applies($entity, $action): bool {
+    return $entity === 'MembershipType' && $action === 'create';
+  }
+
+}
index 71efdb46f8146bd6a192b8afa13e727384850abf..afaa596115005c30e65e478224e6018e6abc8bfd 100644 (file)
@@ -889,7 +889,7 @@ class CRM_Core_BAO_ActionScheduleTest extends CiviUnitTestCase {
           'period_type' => 'rolling',
           'member_of_contact_id' => 1,
           'financial_type_id:name' => 'Member Dues',
-          'duration_unit' => 1,
+          'duration_unit' => 'month',
         ]
       )->execute()->first()['id'];
     }
diff --git a/tests/phpunit/api/v4/Action/ComplexQueryTest.php b/tests/phpunit/api/v4/Action/ComplexQueryTest.php
deleted file mode 100644 (file)
index 9553773..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-
-/*
- +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC. All rights reserved.                        |
- |                                                                    |
- | This work is published under the GNU AGPLv3 license with some      |
- | permitted exceptions and without any warranty. For full license    |
- | and copyright information, see https://civicrm.org/licensing       |
- +--------------------------------------------------------------------+
- */
-
-/**
- *
- * @package CRM
- * @copyright CiviCRM LLC https://civicrm.org/licensing
- */
-
-
-namespace api\v4\Action;
-
-use api\v4\Api4TestBase;
-use Civi\Api4\Activity;
-use Civi\Api4\Contact;
-use Civi\Test\CiviEnvBuilder;
-use Civi\Test\TransactionalInterface;
-
-/**
- * @group headless
- *
- * This class tests a series of complex query situations described in the
- * initial APIv4 specification
- */
-class ComplexQueryTest extends Api4TestBase implements TransactionalInterface {
-
-  public function setUpHeadless(): CiviEnvBuilder {
-    $this->loadDataSet('DefaultDataSet');
-    return parent::setUpHeadless();
-  }
-
-  public function tearDown(): void {
-    $relatedTables = [
-      'civicrm_activity',
-      'civicrm_activity_contact',
-    ];
-    $this->cleanup(['tablesToTruncate' => $relatedTables]);
-    parent::tearDown();
-  }
-
-  /**
-   * Fetch all phone call activities
-   * Expects at least one activity loaded from the data set.
-   *
-   * @throws \API_Exception
-   */
-  public function testGetAllHousingSupportActivities(): void {
-    $results = Activity::get(FALSE)
-      ->addWhere('activity_type_id:name', '=', 'Phone Call')
-      ->execute();
-
-    $this->assertGreaterThan(0, count($results));
-  }
-
-  /**
-   *
-   */
-  public function testGetWithCount() {
-    $myName = uniqid('count');
-    for ($i = 1; $i <= 20; ++$i) {
-      Contact::create()
-        ->addValue('first_name', "Contact $i")
-        ->addValue('last_name', $myName)
-        ->setCheckPermissions(FALSE)->execute();
-    }
-
-    $get1 = Contact::get()
-      ->addWhere('last_name', '=', $myName)
-      ->selectRowCount()
-      ->addSelect('first_name')
-      ->setLimit(10)
-      ->setDebug(TRUE)
-      ->setCheckPermissions(FALSE)->execute();
-
-    $this->assertEquals(20, $get1->count());
-    $this->assertCount(10, (array) $get1);
-
-  }
-
-  /**
-   * Fetch contacts named 'Bob' and all of their blue activities
-   */
-  public function testGetAllBlueActivitiesForBobs() {
-
-  }
-
-  /**
-   * Get all contacts in a zipcode and return their Home or Work email addresses
-   */
-  public function testGetHomeOrWorkEmailsForContactsWithZipcode() {
-
-  }
-
-  /**
-   * Fetch all activities where Bob is the assignee or source
-   */
-  public function testGetActivitiesWithBobAsAssigneeOrSource() {
-
-  }
-
-  /**
-   * Get all contacts which
-   * (a) have address in zipcode 94117 or 94118 or in city "San Francisco","LA"
-   * and
-   * (b) are not deceased and
-   * (c) have a custom-field "most_important_issue=Environment".
-   */
-  public function testAWholeLotOfConditions() {
-
-  }
-
-  /**
-   * Get participants who attended CiviCon 2012 but not CiviCon 2013.
-   * Return their name and email.
-   */
-  public function testGettingNameAndEmailOfAttendeesOfCiviCon2012Only() {
-
-  }
-
-}
index e02827bf50f0baa039f827dc570139144a5e5a7b..6e4a72298586a0fb78980d1a6c0414053990359d 100644 (file)
@@ -330,9 +330,7 @@ class ContactGetTest extends Api4TestBase implements TransactionalInterface {
       ['first_name' => 'abc', 'last_name' => $lastName, 'birth_date' => 'now - 1 year - 1 month'],
       ['first_name' => 'def', 'last_name' => $lastName, 'birth_date' => 'now - 21 year - 6 month'],
     ];
-    Contact::save(FALSE)
-      ->setRecords($sampleData)
-      ->execute();
+    $this->saveTestRecords('Contact', ['records' => $sampleData]);
 
     $result = Contact::get(FALSE)
       ->addWhere('last_name', '=', $lastName)
@@ -347,4 +345,28 @@ class ContactGetTest extends Api4TestBase implements TransactionalInterface {
       ->execute()->single();
   }
 
+  /**
+   *
+   */
+  public function testGetWithCount() {
+    $myName = uniqid('count');
+    for ($i = 1; $i <= 20; ++$i) {
+      $this->createTestRecord('Contact', [
+        'first_name' => "Contact $i",
+        'last_name' => $myName,
+      ]);
+    }
+
+    $get1 = Contact::get(FALSE)
+      ->addWhere('last_name', '=', $myName)
+      ->selectRowCount()
+      ->addSelect('first_name')
+      ->setLimit(10)
+      ->execute();
+
+    $this->assertEquals(20, $get1->count());
+    $this->assertCount(10, (array) $get1);
+
+  }
+
 }
index bde62072da6cdccb14997e13846368af1c9fa029..74a79473c5279deed64cab081a9bfbd0bcd0a09a 100644 (file)
@@ -21,11 +21,9 @@ namespace api\v4\Action;
 
 use api\v4\Api4TestBase;
 use Civi\Api4\Activity;
-use Civi\Api4\CiviCase;
 use Civi\Api4\Contact;
 use Civi\Api4\Email;
 use Civi\Api4\EntityTag;
-use Civi\Api4\Phone;
 use Civi\Api4\Relationship;
 use Civi\Api4\Tag;
 use Civi\Test\TransactionalInterface;
@@ -35,12 +33,6 @@ use Civi\Test\TransactionalInterface;
  */
 class FkJoinTest extends Api4TestBase implements TransactionalInterface {
 
-  public function setUpHeadless() {
-    $this->loadDataSet('DefaultDataSet');
-
-    return parent::setUpHeadless();
-  }
-
   public function tearDown(): void {
     $relatedTables = [
       'civicrm_activity',
@@ -60,6 +52,10 @@ class FkJoinTest extends Api4TestBase implements TransactionalInterface {
    * loaded from the data set.
    */
   public function testThreeLevelJoin() {
+    $this->createTestRecord('Activity', [
+      'activity_type_id:name' => 'Phone Call',
+    ]);
+
     $results = Activity::get(FALSE)
       ->addWhere('activity_type_id:name', '=', 'Phone Call')
       ->execute();
@@ -68,50 +64,80 @@ class FkJoinTest extends Api4TestBase implements TransactionalInterface {
   }
 
   public function testOptionalJoin() {
-    // DefaultDataSet includes 2 phones for contact 1, 0 for contact 2.
+    $contact1 = $this->createTestRecord('Contact');
+    $contact2 = $this->createTestRecord('Contact');
+
+    $this->createTestRecord('Phone', [
+      'location_type_id:name' => 'Home',
+      'contact_id' => $contact1['id'],
+    ]);
+    $this->createTestRecord('Phone', [
+      'location_type_id:name' => 'Work',
+      'contact_id' => $contact1['id'],
+    ]);
+
     // We'll add one for contact 2 as a red herring to make sure we only get back the correct ones.
-    Phone::create(FALSE)
-      ->setValues(['contact_id' => $this->getReference('test_contact_2')['id'], 'phone' => '123456'])
-      ->execute();
+    $this->createTestRecord('Phone', [
+      'contact_id' => $contact2['id'],
+    ]);
     $contacts = Contact::get(FALSE)
       ->addJoin('Phone', FALSE)
       ->addSelect('id', 'phone.phone')
-      ->addWhere('id', 'IN', [$this->getReference('test_contact_1')['id']])
+      ->addWhere('id', 'IN', [$contact1['id']])
       ->addOrderBy('phone.id')
       ->execute();
     $this->assertCount(2, $contacts);
-    $this->assertEquals($this->getReference('test_contact_1')['id'], $contacts[0]['id']);
-    $this->assertEquals($this->getReference('test_contact_1')['id'], $contacts[1]['id']);
+    $this->assertEquals($contact1['id'], $contacts[0]['id']);
+    $this->assertEquals($contact1['id'], $contacts[1]['id']);
   }
 
   public function testRequiredJoin() {
+    $contact1 = $this->createTestRecord('Contact');
+    $contact2 = $this->createTestRecord('Contact');
+
+    $this->createTestRecord('Phone', [
+      'location_type_id:name' => 'Home',
+      'contact_id' => $contact1['id'],
+      'phone' => '+35355439483',
+    ]);
+    $this->createTestRecord('Phone', [
+      'location_type_id:name' => 'Work',
+      'contact_id' => $contact1['id'],
+    ]);
+
     // Joining with no condition
     $contacts = Contact::get(FALSE)
       ->addSelect('id', 'phone.phone')
       ->addJoin('Phone', TRUE)
-      ->addWhere('id', 'IN', [$this->getReference('test_contact_1')['id'], $this->getReference('test_contact_2')['id']])
+      ->addWhere('id', 'IN', [$contact1['id'], $contact2['id']])
       ->addOrderBy('phone.id')
       ->execute();
     $this->assertCount(2, $contacts);
-    $this->assertEquals($this->getReference('test_contact_1')['id'], $contacts[0]['id']);
-    $this->assertEquals($this->getReference('test_contact_1')['id'], $contacts[1]['id']);
+    $this->assertEquals($contact1['id'], $contacts[0]['id']);
+    $this->assertEquals($contact1['id'], $contacts[1]['id']);
 
     // Add is_primary condition, should result in only one record
     $contacts = Contact::get(FALSE)
       ->addSelect('id', 'phone.phone', 'phone.location_type_id')
       ->addJoin('Phone', TRUE, ['phone.is_primary', '=', TRUE])
-      ->addWhere('id', 'IN', [$this->getReference('test_contact_1')['id'], $this->getReference('test_contact_2')['id']])
+      ->addWhere('id', 'IN', [$contact1['id'], $contact2['id']])
       ->addOrderBy('phone.id')
       ->execute();
     $this->assertCount(1, $contacts);
-    $this->assertEquals($this->getReference('test_contact_1')['id'], $contacts[0]['id']);
+    $this->assertEquals($contact1['id'], $contacts[0]['id']);
     $this->assertEquals('+35355439483', $contacts[0]['phone.phone']);
     $this->assertEquals('1', $contacts[0]['phone.location_type_id']);
   }
 
   public function testImplicitJoinOnExplicitJoin() {
+    $contact1 = $this->createTestRecord('Contact');
+    $this->createTestRecord('Address', [
+      'contact_id' => $contact1['id'],
+      'country_id' => 1228,
+    ]);
+
     $contacts = Contact::get(FALSE)
-      ->addWhere('id', '=', $this->getReference('test_contact_1')['id'])
+      ->addWhere('id', '=', $contact1['id'])
       ->addJoin('Address AS address', TRUE, ['id', '=', 'address.contact_id'], ['address.location_type_id', '=', 1])
       ->addSelect('id', 'address.country_id.iso_code')
       ->execute();
@@ -120,11 +146,16 @@ class FkJoinTest extends Api4TestBase implements TransactionalInterface {
   }
 
   public function testExcludeJoin() {
+    $contact1 = $this->createTestRecord('Contact');
+    $this->createTestRecord('Address', [
+      'contact_id' => $contact1['id'],
+      'country_id' => 1228,
+    ]);
     $contacts = Contact::get(FALSE)
       ->addJoin('Address AS address', 'EXCLUDE', ['id', '=', 'address.contact_id'], ['address.location_type_id', '=', 1])
       ->addSelect('id')
       ->execute()->column('id');
-    $this->assertNotContains($this->getReference('test_contact_1')['id'], $contacts);
+    $this->assertNotContains($contact1['id'], $contacts);
   }
 
   public function testInvalidJoinAlias() {
@@ -433,36 +464,39 @@ class FkJoinTest extends Api4TestBase implements TransactionalInterface {
   }
 
   public function testJoinWithExpression() {
-    Phone::create(FALSE)
-      ->setValues(['contact_id' => $this->getReference('test_contact_1')['id'], 'phone' => '654321'])
-      ->execute();
+
+    $contact1 = $this->createTestRecord('Contact');
+    $contact2 = $this->createTestRecord('Contact');
+    $this->createTestRecord('Phone', [
+      'contact_id' => $contact1['id'],
+      'phone' => '654321',
+    ]);
+
     $contacts = Contact::get(FALSE)
       ->addSelect('id', 'phone.phone')
       ->addJoin('Phone', 'INNER', ['LOWER(phone.phone)', '=', "CONCAT('6', '5', '4', '3', '2', '1')"])
-      ->addWhere('id', 'IN', [$this->getReference('test_contact_1')['id'], $this->getReference('test_contact_2')['id']])
+      ->addWhere('id', 'IN', [$contact1['id'], $contact2['id']])
       ->addOrderBy('phone.id')
       ->execute();
     $this->assertCount(1, $contacts);
-    $this->assertEquals($this->getReference('test_contact_1')['id'], $contacts[0]['id']);
+    $this->assertEquals($contact1['id'], $contacts[0]['id']);
     $this->assertEquals('654321', $contacts[0]['phone.phone']);
   }
 
   public function testJoinCaseRoles() {
     \CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase');
-    $this->loadDataSet('CaseType');
 
-    $contactID = $this->createEntity(['type' => 'Individual'])['id'];
-    $managerID = $this->createEntity(['type' => 'Individual'])['id'];
+    $contactID = $this->createTestRecord('Contact')['id'];
+    $managerID = $this->createTestRecord('Contact')['id'];
 
-    $case = CiviCase::create(FALSE)
-      ->addValue('case_type_id', $this->getReference('test_case_type_1')['id'])
-      ->addValue('status_id', 1)
-      ->addValue('creator_id', $managerID)
-      ->addValue('contact_id', $contactID)
-      ->execute()
-      ->first();
+    $caseType = $this->createTestRecord('CaseType');
+    $case = $this->createTestRecord('Case', [
+      'creator_id' => $managerID,
+      'contact_id' => $contactID,
+      'case_type_id' => $caseType['id'],
+    ]);
 
-    $contacts = \Civi\Api4\Contact::get()
+    $contacts = Contact::get(FALSE)
       ->addSelect('*', 'case.*')
       ->addJoin('Case AS case', 'INNER', 'RelationshipCache', ['id', '=', 'case.far_contact_id'], ['case.far_relation', '=', '"Parent of"'])
       ->addWhere('case.id', '=', $case['id'])
index a2dae2075d997010ec88dcadeef788acab39b569..66551102a03ab634b289544d832b30342403f764 100644 (file)
@@ -36,7 +36,7 @@ class IsPrimaryTest extends Api4TestBase implements TransactionalInterface {
    * Test that creating a location entity or deleting one re-assigns is_primary correctly.
    */
   public function testPrimaryHandling() {
-    $contactID = self::createEntity(['type' => 'Individual'])['id'];
+    $contactID = $this->createTestRecord('Contact')['id'];
     // Create an entity of each type.
     Email::create()->setValues(['email' => 'b@example.com', 'contact_id' => $contactID])->execute();
     Phone::create()->setValues(['phone' => '123', 'contact_id' => $contactID])->execute();
index 707889513359754b56554c2a60d6a338dd5e0d1b..07a1e6f22e8e55512f07833c49eee432243714ea 100644 (file)
@@ -19,8 +19,8 @@
 
 namespace api\v4;
 
-use api\v4\Traits\TestDataLoaderTrait;
 use Civi\Api4\UFMatch;
+use Civi\Api4\Utils\CoreUtil;
 use Civi\Test\HeadlessInterface;
 
 require_once 'api/Exception.php';
@@ -30,7 +30,12 @@ require_once 'api/Exception.php';
  */
 class Api4TestBase extends \PHPUnit\Framework\TestCase implements HeadlessInterface {
 
-  use TestDataLoaderTrait;
+  /**
+   * Records created which will be deleted during tearDown
+   *
+   * @var array
+   */
+  public $testRecords = [];
 
   /**
    * @see CiviUnitTestCase
@@ -48,6 +53,15 @@ class Api4TestBase extends \PHPUnit\Framework\TestCase implements HeadlessInterf
     return \Civi\Test::headless()->apply();
   }
 
+  /**
+   */
+  public function tearDown(): void {
+    // Delete all test records in reverse order to prevent fk constraints
+    foreach (array_reverse($this->testRecords) as $record) {
+      civicrm_api4($record[0], 'delete', ['checkPermissions' => FALSE, 'where' => $record[1]]);
+    }
+  }
+
   /**
    * Quick clean by emptying tables created for the test.
    *
@@ -66,17 +80,6 @@ class Api4TestBase extends \PHPUnit\Framework\TestCase implements HeadlessInterf
     \CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 1;");
   }
 
-  /**
-   * Quick record counter
-   *
-   * @param string $table_name
-   * @returns int record count
-   */
-  public function getRowCount($table_name) {
-    $sql = "SELECT count(id) FROM $table_name";
-    return (int) \CRM_Core_DAO::singleValueQuery($sql);
-  }
-
   /**
    * Emulate a logged in user since certain functions use that.
    * value to store a record in the DB (like activity)
@@ -86,13 +89,13 @@ class Api4TestBase extends \PHPUnit\Framework\TestCase implements HeadlessInterf
    *   Contact ID of the created user.
    */
   public function createLoggedInUser() {
-    $contactID = $this->createEntity(['type' => 'Individual'])['id'];
+    $contactID = $this->createTestRecord('Contact')['id'];
     UFMatch::delete(FALSE)->addWhere('uf_id', '=', 6)->execute();
-    UFMatch::create(FALSE)->setValues([
+    $this->createTestRecord('UFMatch', [
       'contact_id' => $contactID,
       'uf_name' => 'superman',
       'uf_id' => 6,
-    ])->execute();
+    ]);
 
     $session = \CRM_Core_Session::singleton();
     $session->set('userID', $contactID);
@@ -100,177 +103,260 @@ class Api4TestBase extends \PHPUnit\Framework\TestCase implements HeadlessInterf
   }
 
   /**
-   * Create sample entities (using V3 for now).
+   * Inserts a test record, supplying all required values if not provided.
    *
-   * @param array $params
-   *   (type, seq, overrides, count)
-   * @return array
-   *   (either single, or array of array if count >1)
-   * @throws \CiviCRM_API3_Exception
-   * @throws \Exception
+   * Test records will be automatically deleted during tearDown.
+   *
+   * @param string $entityName
+   * @param array $values
+   * @return array|null
+   * @throws \API_Exception
+   * @throws \Civi\API\Exception\NotImplementedException
    */
-  public static function createEntity($params) {
-    $params += [
-      'count' => 1,
-      'seq' => 0,
+  public function createTestRecord(string $entityName, array $values = []) {
+    return $this->saveTestRecords($entityName, ['records' => [$values]])->first();
+  }
+
+  /**
+   * Saves one or more test records, supplying default values.
+   *
+   * Test records will be automatically deleted during tearDown.
+   *
+   * @param string $entityName
+   * @param array $saveParams
+   * @return \Civi\Api4\Generic\Result
+   * @throws \API_Exception
+   * @throws \Civi\API\Exception\NotImplementedException
+   */
+  public function saveTestRecords(string $entityName, array $saveParams) {
+    $saveParams += [
+      'checkPermissions' => FALSE,
+      'defaults' => [],
     ];
-    $entities = [];
-    $entity = NULL;
-    for ($i = 0; $i < $params['count']; $i++) {
-      $params['seq']++;
-      $data = self::sample($params);
-      $api_params = ['sequential' => 1] + $data['sample_params'];
-      $result = civicrm_api3($data['entity'], 'create', $api_params);
-      if ($result['is_error']) {
-        throw new \Exception("creating $data[entity] failed");
-      }
-      $entity = $result['values'][0];
-      if (!($entity['id'] > 0)) {
-        throw new \Exception("created entity is malformed");
+    $idField = CoreUtil::getIdFieldName($entityName);
+    foreach ($saveParams['records'] as &$record) {
+      $record += $saveParams['defaults'];
+      if (empty($record[$idField])) {
+        $this->getRequiredValuesToCreate($entityName, $record);
       }
-      $entities[] = $entity;
     }
-    return $params['count'] == 1 ? $entity : $entities;
+    $saved = civicrm_api4($entityName, 'save', $saveParams);
+    foreach ($saved as $item) {
+      $this->testRecords[] = [$entityName, [[$idField, '=', $item[$idField]]]];
+    }
+    return $saved;
   }
 
   /**
-   * Helper function for creating sample entities.
-   *
-   * Depending on the supplied sequence integer, plucks values from the dummy data.
-   * Constructs a foreign entity when an ID is required but isn't supplied in the overrides.
+   * Get the required fields for the api entity + action.
    *
-   * Inspired by CiviUnitTestCase::
-   * @todo - extract this function to own class and share with CiviUnitTestCase?
-   * @param array $params
-   * - type: string roughly matching entity type
-   * - seq: (optional) int sequence number for the values of this type
-   * - overrides: (optional) array of fill in parameters
+   * @param string $entity
+   * @param array $values
    *
    * @return array
-   *   - entity: string API entity type (usually the type supplied except for contact subtypes)
-   *   - sample_params: array API sample_params properties of sample entity
+   * @throws \API_Exception
    */
-  public static function sample($params) {
-    $params += [
-      'seq' => 0,
-      'overrides' => [],
-    ];
-    $type = $params['type'];
-    // sample data - if field is array then chosed based on `seq`
-    $sample_params = [];
-    if (in_array($type, ['Individual', 'Organization', 'Household'])) {
-      $sample_params['contact_type'] = $type;
-      $entity = 'Contact';
+  public function getRequiredValuesToCreate(string $entity, &$values = []) {
+    $requiredFields = civicrm_api4($entity, 'getfields', [
+      'action' => 'create',
+      'loadOptions' => TRUE,
+      'where' => [
+        ['type', 'IN', ['Field', 'Extra']],
+        ['OR',
+          [
+            ['required', '=', TRUE],
+            // Include contitionally-required fields only if they don't create a circular FK reference
+            ['AND', [['required_if', 'IS NOT EMPTY'], ['fk_entity', '!=', $entity]]],
+          ],
+        ],
+        ['default_value', 'IS EMPTY'],
+        ['readonly', 'IS EMPTY'],
+      ],
+    ], 'name');
+
+    $extraValues = [];
+    foreach ($requiredFields as $fieldName => $requiredField) {
+      if (!isset($values[$fieldName])) {
+        $extraValues[$fieldName] = $this->getRequiredValue($requiredField);
+      }
     }
-    else {
-      $entity = $type;
+
+    // Hack in some extra per-entity values that couldn't be determined by metadata.
+    // Try to keep this to a minimum and improve metadata as a first-resort.
+
+    switch ($entity) {
+      case 'UFField':
+        $extraValues['field_name'] = 'activity_campaign_id';
+        break;
+
+      case 'Translation':
+        $extraValues['entity_table'] = 'civicrm_event';
+        $extraValues['entity_field'] = 'description';
+        $extraValues['entity_id'] = $this->getFkID('Event');
+        break;
+
+      case 'Case':
+        $extraValues['creator_id'] = $this->getFkID('Contact');
+        break;
+
+      case 'CaseContact':
+        // Prevent "already exists" error from using an existing contact id
+        $extraValues['contact_id'] = $this->createTestRecord('Contact')['id'];
+        break;
+
+      case 'CaseType':
+        $extraValues['definition'] = [
+          "activityTypes" => [
+            [
+              "name" => "Open Case",
+              "max_instances" => "1",
+            ],
+            [
+              "name" => "Follow up",
+            ],
+          ],
+          "activitySets" => [
+            [
+              "name" => "standard_timeline",
+              "label" => "Standard Timeline",
+              "timeline" => 1,
+              "activityTypes" => [
+                [
+                  "name" => "Open Case",
+                  "status" => "Completed",
+                ],
+                [
+                  "name" => "Follow up",
+                  "reference_activity" => "Open Case",
+                  "reference_offset" => "3",
+                  "reference_select" => "newest",
+                ],
+              ],
+            ],
+          ],
+          "timelineActivityTypes" => [
+            [
+              "name" => "Open Case",
+              "status" => "Completed",
+            ],
+            [
+              "name" => "Follow up",
+              "reference_activity" => "Open Case",
+              "reference_offset" => "3",
+              "reference_select" => "newest",
+            ],
+          ],
+          "caseRoles" => [
+            [
+              "name" => "Parent of",
+              "creator" => "1",
+              "manager" => "1",
+            ],
+          ],
+        ];
+        break;
     }
-    // use the seq to pluck a set of params out
-    foreach (self::sampleData($type) as $key => $value) {
-      if (is_array($value)) {
-        $sample_params[$key] = $value[$params['seq'] % count($value)];
-      }
-      else {
-        $sample_params[$key] = $value;
-      }
+
+    $values += $extraValues;
+    return $values;
+  }
+
+  /**
+   * Attempt to get a value using field option, defaults, FKEntity, or a random
+   * value based on the data type.
+   *
+   * @param array $field
+   *
+   * @return mixed
+   * @throws \Exception
+   */
+  private function getRequiredValue(array $field) {
+    if (!empty($field['options'])) {
+      return key($field['options']);
+    }
+    if (!empty($field['fk_entity'])) {
+      return $this->getFkID($field['fk_entity']);
     }
-    if ($type == 'Individual') {
-      $sample_params['email'] = strtolower(
-        $sample_params['first_name'] . '_' . $sample_params['last_name'] . '@civicrm.org'
-      );
-      $sample_params['prefix_id'] = 3;
-      $sample_params['suffix_id'] = 3;
+    if (isset($field['default_value'])) {
+      return $field['default_value'];
     }
-    if (!count($sample_params)) {
-      throw new \Exception("unknown sample type: $type");
+    if ($field['name'] === 'contact_id') {
+      return $this->getFkID('Contact');
     }
-    $sample_params = $params['overrides'] + $sample_params;
-    // make foreign enitiies if they haven't been supplied
-    foreach ($sample_params as $key => $value) {
-      if (substr($value, 0, 6) === 'dummy.') {
-        $foreign_entity = self::createEntity([
-          'type' => substr($value, 6),
-          'seq' => $params['seq'],
-        ]);
-        $sample_params[$key] = $foreign_entity['id'];
+    if ($field['name'] === 'entity_id') {
+      // What could possibly go wrong with this?
+      switch ($field['table_name'] ?? NULL) {
+        case 'civicrm_financial_item':
+          return $this->getFkID(\Civi\Api4\Service\Spec\Provider\FinancialItemCreationSpecProvider::DEFAULT_ENTITY);
+
+        default:
+          return $this->getFkID('Contact');
       }
     }
-    return compact("entity", "sample_params");
+
+    $randomValue = $this->getRandomValue($field['data_type']);
+
+    if ($randomValue) {
+      return $randomValue;
+    }
+
+    throw new \API_Exception('Could not provide default value');
   }
 
   /**
-   * Provider of sample data.
+   * Get an ID for the appropriate entity.
    *
-   * @return array
-   *   Array values represent a set of allowable items.
-   *   Strings in the form "dummy.Entity" require creating a foreign entity first.
+   * @param string $fkEntity
+   *
+   * @return int
+   *
+   * @throws \API_Exception
    */
-  public static function sampleData($type) {
-    $data = [
-      'Individual' => [
-        // The number of values in each list need to be coprime numbers to not have duplicates
-        'first_name' => ['Anthony', 'Joe', 'Terrence', 'Lucie', 'Albert', 'Bill', 'Kim'],
-        'middle_name' => ['J.', 'M.', 'P', 'L.', 'K.', 'A.', 'B.', 'C.', 'D', 'E.', 'Z.'],
-        'last_name' => ['Anderson', 'Miller', 'Smith', 'Collins', 'Peterson'],
-        'contact_type' => 'Individual',
-      ],
-      'Organization' => [
-        'organization_name' => [
-          'Unit Test Organization',
-          'Acme',
-          'Roberts and Sons',
-          'Cryo Space Labs',
-          'Sharper Pens',
-        ],
-      ],
-      'Household' => [
-        'household_name' => ['Unit Test household'],
-      ],
-      'Event' => [
-        'title' => 'Annual CiviCRM meet',
-        'summary' => 'If you have any CiviCRM related issues or want to track where CiviCRM is heading, Sign up now',
-        'description' => 'This event is intended to give brief idea about progess of CiviCRM and giving solutions to common user issues',
-        'event_type_id' => 1,
-        'is_public' => 1,
-        'start_date' => 20081021,
-        'end_date' => 20081023,
-        'is_online_registration' => 1,
-        'registration_start_date' => 20080601,
-        'registration_end_date' => 20081015,
-        'max_participants' => 100,
-        'event_full_text' => 'Sorry! We are already full',
-        'is_monetary' => 0,
-        'is_active' => 1,
-        'is_show_location' => 0,
-      ],
-      'Participant' => [
-        'event_id' => 'dummy.Event',
-        'contact_id' => 'dummy.Individual',
-        'status_id' => 2,
-        'role_id' => 1,
-        'register_date' => 20070219,
-        'source' => 'Wimbeldon',
-        'event_level' => 'Payment',
-      ],
-      'Contribution' => [
-        'contact_id' => 'dummy.Individual',
-        // donation, 2 = member, 3 = campaign contribution, 4=event
-        'financial_type_id' => 1,
-        'total_amount' => 7.3,
-      ],
-      'Activity' => [
-        //'activity_type_id' => 1,
-        'subject' => 'unit testing',
-        'source_contact_id' => 'dummy.Individual',
-      ],
-      'Group' => [
-        'title' => 'unit testing',
-      ],
-    ];
-    if ($type == 'Contact') {
-      $type = 'Individual';
+  private function getFkID(string $fkEntity) {
+    $params = ['checkPermissions' => FALSE];
+    // Be predictable about what type of contact we select
+    if ($fkEntity === 'Contact') {
+      $params['where'] = [['contact_type', '=', 'Individual']];
     }
-    return $data[$type];
+    $entityList = civicrm_api4($fkEntity, 'get', $params);
+    // If no existing entities, create one
+    if ($entityList->count() < 1) {
+      return $this->createTestRecord($fkEntity)['id'];
+    }
+
+    return $entityList->last()['id'];
+  }
+
+  /**
+   * @param $dataType
+   *
+   * @return int|null|string
+   */
+  private function getRandomValue($dataType) {
+    switch ($dataType) {
+      case 'Boolean':
+        return TRUE;
+
+      case 'Integer':
+        return random_int(1, 2000);
+
+      case 'String':
+        return \CRM_Utils_String::createRandom(10, implode('', range('a', 'z')));
+
+      case 'Text':
+        return \CRM_Utils_String::createRandom(100, implode('', range('a', 'z')));
+
+      case 'Money':
+        return sprintf('%d.%2d', rand(0, 2000), rand(10, 99));
+
+      case 'Date':
+        return '20100102';
+
+      case 'Timestamp':
+        return 'now';
+    }
+
+    return NULL;
   }
 
 }
index 4407e8ca1433a6d96c49edb49dc787b31baf21a5..56b5fff6ab632dce1a1fd97ed2a66fd521296b8e 100644 (file)
@@ -104,7 +104,7 @@ class CreateCustomValueTest extends CustomTestBase {
       ->addValue('time_format', 2)
       ->execute();
 
-    $contactID = $this->createEntity(['type' => 'Individual'])['id'];
+    $contactID = $this->createTestRecord('Contact')['id'];
 
     CustomValue::create('MyContactDateFields', FALSE)
       ->addValue('date_field', '2022-02-02')
index 1faabe10be6873295f4cf954096af4fe1885a952..7d681b3b406a6e200e876dccc297b40576acc9d2 100644 (file)
@@ -29,7 +29,7 @@ use Civi\Api4\CustomGroup;
 class CustomFieldAlterTest extends CustomTestBase {
 
   public function testChangeSerialize() {
-    $contact = $this->createEntity(['type' => 'Individual']);
+    $contact = $this->createTestRecord('Contact');
 
     $customGroup = CustomGroup::create(FALSE)
       ->addValue('title', 'MyFieldsToAlter')
index 8f006dfe66bb2fb9e94e1b7e55b167b301a91ff4..358d8192b3b0baa9476a7ff26f4e6e7bb4a18b17 100644 (file)
@@ -276,13 +276,13 @@ class PseudoconstantTest extends CustomTestBase {
   }
 
   public function testParticipantRole() {
-    $event = $this->createEntity(['type' => 'Event']);
-    $contact = $this->createEntity(['type' => 'Individual']);
-    $participant = Participant::create()
-      ->addValue('contact_id', $contact['id'])
-      ->addValue('event_id', $event['id'])
-      ->addValue('role_id:label', ['Attendee', 'Volunteer'])
-      ->execute()->first();
+    $event = $this->createTestRecord('Event');
+    $contact = $this->createTestRecord('Contact');
+    $participant = $this->createTestRecord('Participant', [
+      'contact_id' => $contact['id'],
+      'event_id' => $event['id'],
+      'role_id:label' => ['Attendee', 'Volunteer'],
+    ]);
 
     $search1 = Participant::get()
       ->addSelect('role_id', 'role_id:label')
@@ -304,7 +304,7 @@ class PseudoconstantTest extends CustomTestBase {
     \CRM_Core_BAO_ConfigSetting::enableComponent('CiviContribute');
     \CRM_Core_BAO_ConfigSetting::enableComponent('CiviCampaign');
 
-    $contact = $this->createEntity(['type' => 'Individual']);
+    $contact = $this->createTestRecord('Contact');
 
     $campaignTitle = uniqid('Test ');
 
diff --git a/tests/phpunit/api/v4/DataSets/CaseType.json b/tests/phpunit/api/v4/DataSets/CaseType.json
deleted file mode 100644 (file)
index dd1c084..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-{
-  "CaseType": [
-    {
-      "name": "test_case_type",
-      "title": "Test Case Type",
-      "definition": {
-        "activityTypes": [
-          {
-            "name": "Open Case",
-            "max_instances": "1"
-          },
-          {
-            "name": "Follow up"
-          }
-        ],
-        "activitySets": [
-          {
-            "name": "standard_timeline",
-            "label": "Standard Timeline",
-            "timeline": 1,
-            "activityTypes": [
-              {
-                "name": "Open Case",
-                "status": "Completed"
-              },
-              {
-                "name": "Follow up",
-                "reference_activity": "Open Case",
-                "reference_offset": "3",
-                "reference_select": "newest"
-              }
-            ]
-          }
-        ],
-        "timelineActivityTypes": [
-          {
-            "name": "Open Case",
-            "status": "Completed"
-          },
-          {
-            "name": "Follow up",
-            "reference_activity": "Open Case",
-            "reference_offset": "3",
-            "reference_select": "newest"
-          }
-        ],
-        "caseRoles": [
-          {
-            "name": "Parent of",
-            "creator": "1",
-            "manager": "1"
-          }
-        ]
-      },
-      "@ref": "test_case_type_1"
-    }
-  ]
-}
diff --git a/tests/phpunit/api/v4/DataSets/ConformanceTest.json b/tests/phpunit/api/v4/DataSets/ConformanceTest.json
deleted file mode 100644 (file)
index 0b5bf55..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-{
-  "Contact": [
-    {
-      "first_name": "Janice",
-      "last_name": "Voss",
-      "contact_type": "Individual",
-      "@ref": "test_contact_1"
-    },
-    {
-      "first_name": "Jim",
-      "last_name": "Henson",
-      "contact_type": "Individual",
-      "@ref": "test_contact_2"
-    }
-  ],
-  "Case": [
-    {
-      "case_type_id": "@ref test_case_type_1.id",
-      "status_id": 1,
-      "contact_id": "@ref test_contact_1.id",
-      "creator_id": "@ref test_contact_1.id"
-    }
-  ],
-  "CustomGroup": [
-    {
-      "name": "MyFavoriteThings",
-      "title": "MyFavoriteThings",
-      "extends": "Contact"
-    }
-  ],
-  "Event": [
-    {
-      "start_date": "20401010000000",
-      "title": "The Singularity",
-      "event_type_id": "major_historical_event"
-    }
-  ],
-  "Group": [
-    {
-      "name": "the_group",
-      "title": "The Group"
-    }
-  ],
-  "Mapping": [
-    {
-      "name": "the_mapping",
-      "mapping_type_id": "1"
-    }
-  ],
-  "Activity": [
-    {
-      "subject": "Test A Phone Activity",
-      "activity_type_id:name": "Phone Call",
-      "source_contact_id": "@ref test_contact_1.id"
-    }
-  ],
-  "Contribution": [
-    {
-      "total_amount": 999.89,
-      "financial_type_id:name": "Donation",
-      "contact_id": "@ref test_contact_1.id"
-    }
-  ],
-  "Pledge" : [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "original_installment_amount" : 10,
-      "amount" : 10,
-      "start_date" :  "now",
-      "create_date" :  "now",
-      "status_id:name" : "Pending"
-    }
-  ],
-  "PaymentProcessor" : [
-    {
-      "payment_processor_type_id:name": "Dummy"
-    }
-  ],
-  "Batch": [
-    {
-      "title": "Batch 433397",
-      "name": "Batch_433397",
-      "status_id": "1"
-    }
-  ],
-  "Product": [
-    {
-      "name": "Test Product",
-      "price": "10.00",
-      "sku": "Test SKU",
-      "financial_type_id:name": "Donation",
-      "min_contribution": "10.00"
-    }
-  ],
-  "MembershipType": [
-    {
-      "name": "General",
-      "period_type" : "fixed",
-      "financial_type_id:name": "Donation",
-      "duration_unit" : "month",
-      "member_of_contact_id" : "@ref test_contact_1.id"
-    }
-  ],
-  "ContributionPage": [
-    {
-      "name": "General"
-    }
-  ],
-  "MembershipType": [
-    {
-      "domain_id": "1",
-      "name": "General",
-      "description": "Regular annual membership.",
-      "member_of_contact_id": "1",
-      "financial_type_id": "2",
-      "minimum_fee": "100.000000000",
-      "duration_unit": "year",
-      "duration_interval": "2",
-      "period_type": "rolling",
-      "relationship_type_id": [
-        "7"
-      ],
-      "relationship_direction": [
-        "b_a"
-      ],
-      "visibility": "Public",
-      "weight": "1",
-      "auto_renew": "0",
-      "is_active": "1"
-    }
-  ],
-  "Membership": [
-    {
-      "membership_type_id:name": "General",
-      "contact_id" : "@ref test_contact_1.id",
-      "status_id:name" : "Pending"
-    }
-  ]
-}
diff --git a/tests/phpunit/api/v4/DataSets/DefaultDataSet.json b/tests/phpunit/api/v4/DataSets/DefaultDataSet.json
deleted file mode 100644 (file)
index 17a0a29..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-{
-  "Contact": [
-    {
-      "first_name": "Phoney",
-      "last_name": "Contact",
-      "contact_type": "Individual",
-      "@ref": "test_contact_1"
-    },
-    {
-      "first_name": "Second",
-      "last_name": "Test",
-      "contact_type": "Individual",
-      "@ref": "test_contact_2"
-    }
-  ],
-  "Activity": [
-    {
-      "subject": "Test Phone Activity",
-      "activity_type_id:name": "Phone Call",
-      "source_contact_id": "@ref test_contact_1.id"
-    },
-    {
-      "subject": "Another Activity",
-      "activity_type_id:name": "Meeting",
-      "source_contact_id": "@ref test_contact_1.id",
-      "assignee_contact_id": [
-        "@ref test_contact_1.id",
-        "@ref test_contact_2.id"
-      ]
-    }
-  ],
-  "Phone": [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "phone": "+35355439483",
-      "location_type_id": "1",
-      "@ref": "test_phone_1"
-    },
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "phone": "+3538733439483",
-      "location_type_id": "2"
-    }
-  ],
-  "Address": [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "street_address": "123 Sesame St.",
-      "country_id": "1228",
-      "location_type_id": "1",
-      "@ref": "test_address_1"
-    }
-  ]
-}
diff --git a/tests/phpunit/api/v4/DataSets/MultiContactMultiEmail.json b/tests/phpunit/api/v4/DataSets/MultiContactMultiEmail.json
deleted file mode 100644 (file)
index ce3fbca..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-  "Contact": [
-    {
-      "first_name": "First",
-      "last_name": "Contact",
-      "contact_type": "Individual",
-      "@ref": "test_contact_1"
-    },
-    {
-      "first_name": "Second",
-      "last_name": "Contact",
-      "contact_type": "Individual",
-      "@ref": "test_contact_2"
-    }
-  ],
-  "Email": [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "email": "test_contact_one_home@fakedomain.com",
-      "location_type_id": 1,
-      "@ref": "test_email_1"
-    },
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "email": "test_contact_one_work@fakedomain.com",
-      "location_type_id": 2,
-      "@ref": "test_email_2"
-    },
-    {
-      "contact_id": "@ref test_contact_2.id",
-      "email": "test_contact_two_home@fakedomain.com",
-      "location_type_id": 1,
-      "@ref": "test_email_3"
-    },
-    {
-      "contact_id": "@ref test_contact_2.id",
-      "email": "test_contact_two_work@fakedomain.com",
-      "location_type_id": 2,
-      "@ref": "test_email_4"
-    }
-  ]
-}
diff --git a/tests/phpunit/api/v4/DataSets/SingleContact.json b/tests/phpunit/api/v4/DataSets/SingleContact.json
deleted file mode 100644 (file)
index 4155336..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-{
-  "Contact": [
-    {
-      "first_name": "Single",
-      "last_name": "Contact",
-      "contact_type": "Individual",
-      "preferred_communication_method": "1",
-      "@ref": "test_contact_1"
-    }
-  ],
-  "Activity": [
-    {
-      "subject": "Won A Nobel Prize",
-      "activity_type_id:name": "Meeting",
-      "source_contact_id": "@ref test_contact_1.id",
-      "@ref": "test_activity_1"
-    },
-    {
-      "subject": "Cleaned The House",
-      "activity_type_id:name": "Meeting",
-      "source_contact_id": "@ref test_contact_1.id",
-      "assignee_contact_id": [
-        "@ref test_contact_1.id"
-      ],
-      "@ref": "test_activity_2"
-    }
-  ],
-  "Phone": [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "phone": "+1111111111111",
-      "location_type_id": 1
-    },
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "phone": "+2222222222222",
-      "location_type_id": 2
-    }
-  ],
-  "Email": [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "email": "test_contact_home@fakedomain.com",
-      "location_type_id": 1
-    },
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "email": "test_contact_work@fakedomain.com",
-      "location_type_id": 2
-    }
-  ],
-  "Address": [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "street_address": "123 Sesame St.",
-      "location_type_id": 1
-    }
-  ],
-  "Website": [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "url": "http://test.com",
-      "website_id": 1
-    }
-  ],
-  "OpenID": [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "openid": "123",
-      "allowed_to_login": 1,
-      "location_type_id": 1
-    }
-  ],
-  "IM": [
-    {
-      "contact_id": "@ref test_contact_1.id",
-      "name": "123",
-      "location_type_id": 1
-    }
-  ]
-}
index ac92b4c3d022c9c1e83a0ffb2bc99475fb68cc4d..6bf8c07b3be1914a936f45132ebdb21e0f89cad6 100644 (file)
 
 namespace api\v4\Entity;
 
-use Civi\Api4\CiviCase;
 use api\v4\Api4TestBase;
 use Civi\Api4\Relationship;
-use Civi\Test\TransactionalInterface;
 
 /**
  * @group headless
  */
-class CaseTest extends Api4TestBase implements TransactionalInterface {
+class CaseTest extends Api4TestBase {
 
   public function setUp(): void {
     parent::setUp();
     \CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase');
-    $this->loadDataSet('CaseType');
-  }
-
-  public function tearDown(): void {
-    $relatedTables = [
-      'civicrm_activity',
-      'civicrm_activity_contact',
-      'civicrm_relationship',
-      'civicrm_case_contact',
-      'civicrm_case_type',
-      'civicrm_case',
-    ];
-    $this->cleanup(['tablesToTruncate' => $relatedTables]);
-    parent::tearDown();
   }
 
   public function testCreateUsingLoggedInUser() {
     $uid = $this->createLoggedInUser();
 
-    $contactID = $this->createEntity(['type' => 'Individual'])['id'];
+    $contactID = $this->createTestRecord('Contact')['id'];
 
-    $case = CiviCase::create(FALSE)
-      ->addValue('case_type_id', $this->getReference('test_case_type_1')['id'])
-      ->addValue('creator_id', 'user_contact_id')
-      ->addValue('status_id', 1)
-      ->addValue('contact_id', $contactID)
-      ->execute()
-      ->first();
+    $case = $this->createTestRecord('Case', [
+      'creator_id' => 'user_contact_id',
+      'contact_id' => $contactID,
+    ]);
 
     $relationships = Relationship::get(FALSE)
       ->addWhere('case_id', '=', $case['id'])
@@ -71,6 +52,11 @@ class CaseTest extends Api4TestBase implements TransactionalInterface {
   }
 
   public function testCgExtendsObjects() {
+    $this->createTestRecord('CaseType', [
+      'title' => 'Test Case Type',
+      'name' => 'test_case_type1',
+    ]);
+
     $field = \Civi\Api4\CustomGroup::getFields(FALSE)
       ->setLoadOptions(TRUE)
       ->addValue('extends', 'Case')
index c85ace355e27d3873f064900bfaacb4c04d92c75..f7b43a04cdf158efdf4b6407d95a9f7661e633f6 100644 (file)
@@ -18,7 +18,6 @@
 
 namespace api\v4\Entity;
 
-use api\v4\Service\TestCreationParameterProvider;
 use api\v4\Traits\CheckAccessTrait;
 use api\v4\Traits\TableDropperTrait;
 use Civi\API\Exception\UnauthorizedException;
@@ -29,7 +28,6 @@ use api\v4\Api4TestBase;
 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;
@@ -43,11 +41,6 @@ class ConformanceTest extends Api4TestBase implements HookInterface {
   use CheckAccessTrait;
   use TableDropperTrait;
 
-  /**
-   * @var \api\v4\Service\TestCreationParameterProvider
-   */
-  protected $creationParamProvider;
-
   /**
    * Set up baseline for testing
    *
@@ -56,10 +49,6 @@ class ConformanceTest extends Api4TestBase implements HookInterface {
   public function setUp(): void {
     // Enable all components
     \CRM_Core_BAO_ConfigSetting::enableAllComponents();
-    $this->loadDataSet('CaseType');
-    $this->loadDataSet('ConformanceTest');
-    $gatherer = new SpecGatherer();
-    $this->creationParamProvider = new TestCreationParameterProvider($gatherer);
     parent::setUp();
     $this->resetCheckAccess();
   }
@@ -261,7 +250,7 @@ class ConformanceTest extends Api4TestBase implements HookInterface {
     $this->setCheckAccessGrants(["{$entity}::create" => TRUE]);
     $this->assertEquals(0, $this->checkAccessCounts["{$entity}::create"]);
 
-    $requiredParams = $this->creationParamProvider->getRequired($entity);
+    $requiredParams = $this->getRequiredValuesToCreate($entity);
     $createResult = $entityClass::create()
       ->setValues($requiredParams)
       ->setCheckPermissions(!$isReadOnly)
@@ -293,7 +282,7 @@ class ConformanceTest extends Api4TestBase implements HookInterface {
     $this->setCheckAccessGrants(["{$entity}::create" => FALSE]);
     $this->assertEquals(0, $this->checkAccessCounts["{$entity}::create"]);
 
-    $requiredParams = $this->creationParamProvider->getRequired($entity);
+    $requiredParams = $this->getRequiredValuesToCreate($entity);
 
     try {
       $entityClass::create()
index a2adafbb0d5141553bef19758fb8a2e684dbaee1..40fadf38e0af0f2a6452e1538fa20e1da98a1dba 100644 (file)
@@ -22,36 +22,23 @@ namespace api\v4\Entity;
 use Civi\Api4\Contact;
 use Civi\Api4\OptionValue;
 use api\v4\Api4TestBase;
-use Civi\Test\TransactionalInterface;
 
 /**
  * @group headless
  */
-class ContactJoinTest extends Api4TestBase implements TransactionalInterface {
-
-  public function setUpHeadless() {
-    $relatedTables = [
-      'civicrm_address',
-      'civicrm_email',
-      'civicrm_phone',
-      'civicrm_openid',
-      'civicrm_im',
-      'civicrm_website',
-      'civicrm_activity',
-      'civicrm_activity_contact',
-    ];
-
-    $this->cleanup(['tablesToTruncate' => $relatedTables]);
-    $this->loadDataSet('SingleContact');
-
-    return parent::setUpHeadless();
-  }
+class ContactJoinTest extends Api4TestBase {
 
   public function testContactJoin() {
-    $contact = $this->getReference('test_contact_1');
+    $contact = $this->createTestRecord('Contact', [
+      'first_name' => uniqid(),
+      'last_name' => uniqid(),
+    ]);
     $entitiesToTest = ['Address', 'OpenID', 'IM', 'Website', 'Email', 'Phone'];
 
     foreach ($entitiesToTest as $entity) {
+      $this->createTestRecord($entity, [
+        'contact_id' => $contact['id'],
+      ]);
       $results = civicrm_api4($entity, 'get', [
         'where' => [['contact_id', '=', $contact['id']]],
         'select' => ['contact_id.*_name', 'contact_id.id'],
@@ -64,12 +51,12 @@ class ContactJoinTest extends Api4TestBase implements TransactionalInterface {
   }
 
   public function testJoinToPCMWillReturnArray() {
-    $contact = Contact::create()->setValues([
+    $contact = $this->createTestRecord('Contact', [
       'preferred_communication_method' => [1, 2, 3],
       'contact_type' => 'Individual',
       'first_name' => 'Test',
       'last_name' => 'PCM',
-    ])->execute()->first();
+    ]);
 
     $fetchedContact = Contact::get()
       ->addWhere('id', '=', $contact['id'])
@@ -89,19 +76,19 @@ class ContactJoinTest extends Api4TestBase implements TransactionalInterface {
     $optionValues = array_column($options, 'value');
     $labels = array_column($options, 'label');
 
-    $contact = Contact::create()->setValues([
+    $contact = $this->createTestRecord('Contact', [
       'preferred_communication_method' => $optionValues,
       'contact_type' => 'Individual',
       'first_name' => 'Test',
       'last_name' => 'PCM',
-    ])->execute()->first();
+    ]);
 
-    $contact2 = Contact::create()->setValues([
+    $contact2 = $this->createTestRecord('Contact', [
       'preferred_communication_method' => $optionValues,
       'contact_type' => 'Individual',
       'first_name' => 'Test',
       'last_name' => 'PCM2',
-    ])->execute()->first();
+    ]);
 
     $contactIds = array_column([$contact, $contact2], 'id');
 
index 1b97a61ce0c3fe03856f646a71ed3e702ea0b8ea..79215069760c43d8b1b8762120ad4674659e58f2 100644 (file)
 namespace api\v4\Entity;
 
 use api\v4\Api4TestBase;
-use Civi\Api4\GroupContact;
-use Civi\Test\TransactionalInterface;
 
 /**
  * @group headless
  */
-class GroupContactTest extends Api4TestBase implements TransactionalInterface {
+class GroupContactTest extends Api4TestBase {
 
   public function testCreate() {
-    $contact = $this->createEntity(['type' => 'Individual']);
-    $group = $this->createEntity(['type' => 'Group']);
-    $result = GroupContact::create(FALSE)
-      ->addValue('group_id', $group['id'])
-      ->addValue('contact_id', $contact['id'])
-      ->execute()
-      ->first();
+    $contact = $this->createTestRecord('Contact');
+    $group = $this->createTestRecord('Group');
+    $result = $this->createTestRecord('GroupContact', [
+      'group_id' => $group['id'],
+      'contact_id' => $contact['id'],
+    ]);
     $this->assertEquals('Added', $result['status']);
   }
 
index 212a481f50fba1ad14100f49938889f59a2c6f64..31bdacfb3389f1fe97f58a834cd65cf3f8a1e7ef 100644 (file)
@@ -28,7 +28,7 @@ use Civi\Test\TransactionalInterface;
 class NoteTest extends Api4TestBase implements TransactionalInterface {
 
   public function testDeleteWithChildren() {
-    $c1 = $this->createEntity(['type' => 'Individual']);
+    $c1 = $this->createTestRecord('Contact');
 
     $text = uniqid(__FUNCTION__, TRUE);
 
index 7ff67408429ec7239f9b2efcb88210c4c101baaf..f7e91c841bd91ae84ddf4c8cf748b58eb8e2a98a 100644 (file)
@@ -54,7 +54,7 @@ class ParticipantTest extends Api4TestBase implements TransactionalInterface {
   public function testGet() {
     $rows = $this->getRowCount('civicrm_participant');
     if ($rows > 0) {
-      $this->markTestSkipped('Participant table must be empty');
+      $this->fail('Participant table must be empty');
     }
 
     // With no records:
@@ -76,36 +76,34 @@ class ParticipantTest extends Api4TestBase implements TransactionalInterface {
     $expectedFirstEventCount = ceil($participantCount / $eventCount);
 
     $dummy = [
-      'contacts' => $this->createEntity([
-        'type' => 'Individual',
-        'count' => $contactCount,
-        'seq' => 1,
+      'contacts' => $this->saveTestRecords('Contact', [
+        'records' => array_fill(0, $contactCount, []),
       ]),
-      'events' => $this->createEntity([
-        'type' => 'Event',
-        'count' => $eventCount,
-        'seq' => 1,
+      'events' => $this->saveTestRecords('Event', [
+        'records' => array_fill(0, $eventCount, []),
       ]),
       'sources' => ['Paddington', 'Springfield', 'Central'],
     ];
 
     // - create dummy participants record
+    $records = [];
     for ($i = 0; $i < $participantCount; $i++) {
-      $dummy['participants'][$i] = $this->sample([
-        'type' => 'Participant',
-        'overrides' => [
-          'event_id' => $dummy['events'][$i % $eventCount]['id'],
-          'contact_id' => $dummy['contacts'][$i % $contactCount]['id'],
-          // 3 = number of sources
-          'source' => $dummy['sources'][$i % 3],
-        ],
-      ])['sample_params'];
-
-      Participant::create()
-        ->setValues($dummy['participants'][$i])
-        ->setCheckPermissions(FALSE)
-        ->execute();
+      $records[] = [
+        'event_id' => $dummy['events'][$i % $eventCount]['id'],
+        'contact_id' => $dummy['contacts'][$i % $contactCount]['id'],
+        // 3 = number of sources
+        'source' => $dummy['sources'][$i % 3],
+      ];
     }
+    $this->saveTestRecords('Participant', [
+      'records' => $records,
+      'defaults' => [
+        'status_id' => 2,
+        'role_id' => 1,
+        'register_date' => 20070219,
+        'event_level' => 'Payment',
+      ],
+    ]);
     $sqlCount = $this->getRowCount('civicrm_participant');
     $this->assertEquals($participantCount, $sqlCount, "Unexpected count");
 
@@ -253,4 +251,15 @@ class ParticipantTest extends Api4TestBase implements TransactionalInterface {
     $this->assertCount(1, Participant::get()->selectRowCount()->addWhere('id', '=', $testParticipants->first()['id'])->execute());
   }
 
+  /**
+   * Quick record counter
+   *
+   * @param string $table_name
+   * @returns int record count
+   */
+  private function getRowCount($table_name) {
+    $sql = "SELECT count(id) FROM $table_name";
+    return (int) \CRM_Core_DAO::singleValueQuery($sql);
+  }
+
 }
index ab1aab3db2df31b971c7d38adddb8deab25f57e7..79255599e9f7afcd22bd66b4af329d63512bfa4d 100644 (file)
@@ -32,12 +32,12 @@ class ValidateValuesTest extends Api4TestBase implements TransactionalInterface
 
   private $lastValidator;
 
-  protected function setUp(): void {
+  public function setUp(): void {
     $this->lastValidator = NULL;
     parent::setUp();
   }
 
-  protected function tearDown(): void {
+  public function tearDown(): void {
     $this->setValidator(NULL);
     parent::tearDown();
   }
index a47b022ff50eb736b53a115852b90db423fc7dc4..03f147b62d0d56f63349dfcb2c0d4924aef42cfb 100644 (file)
@@ -22,35 +22,23 @@ namespace api\v4\Query;
 use Civi\API\Request;
 use Civi\Api4\Query\Api4SelectQuery;
 use api\v4\Api4TestBase;
-use Civi\Test\TransactionalInterface;
 
 /**
  * @group headless
  */
-class Api4SelectQueryTest extends Api4TestBase implements TransactionalInterface {
-
-  public function setUpHeadless() {
-    $relatedTables = [
-      'civicrm_address',
-      'civicrm_email',
-      'civicrm_phone',
-      'civicrm_openid',
-      'civicrm_im',
-      'civicrm_website',
-      'civicrm_activity',
-      'civicrm_activity_contact',
-    ];
-    $this->cleanup(['tablesToTruncate' => $relatedTables]);
-    $this->loadDataSet('DefaultDataSet');
-    $displayNameFormat = '{contact.first_name}{ }{contact.last_name}';
-    \Civi::settings()->set('display_name_format', $displayNameFormat);
-
-    return parent::setUpHeadless();
-  }
+class Api4SelectQueryTest extends Api4TestBase {
 
   public function testManyToOneJoin() {
-    $phoneNum = $this->getReference('test_phone_1')['phone'];
-    $contact = $this->getReference('test_contact_1');
+    $contact = $this->createTestRecord('Contact', [
+      'first_name' => uniqid(),
+      'last_name' => uniqid(),
+    ]);
+    $phone = $this->createTestRecord('Phone', [
+      'contact_id' => $contact['id'],
+      'phone' => uniqid(),
+    ]);
+
+    $phoneNum = $phone['phone'];
 
     $api = Request::create('Phone', 'get', [
       'version' => 4,
index 0c8161617da73a32f684e1935f5528869621aa81..3b3342ce129cf368cf3946709e602c267b72375c 100644 (file)
@@ -21,32 +21,17 @@ namespace api\v4\Query;
 
 use Civi\Api4\Query\Api4SelectQuery;
 use api\v4\Api4TestBase;
-use Civi\Test\TransactionalInterface;
 
 /**
  * @group headless
  */
-class OptionValueJoinTest extends Api4TestBase implements TransactionalInterface {
-
-  public function setUpHeadless() {
-    $relatedTables = [
-      'civicrm_address',
-      'civicrm_email',
-      'civicrm_phone',
-      'civicrm_openid',
-      'civicrm_im',
-      'civicrm_website',
-      'civicrm_activity',
-      'civicrm_activity_contact',
-    ];
-
-    $this->cleanup(['tablesToTruncate' => $relatedTables]);
-    $this->loadDataSet('SingleContact');
-
-    return parent::setUpHeadless();
-  }
+class OptionValueJoinTest extends Api4TestBase {
 
   public function testCommunicationMethodJoin() {
+    $this->createTestRecord('Contact', [
+      'preferred_communication_method' => 1,
+    ]);
+
     $api = \Civi\API\Request::create('Contact', 'get', [
       'version' => 4,
       'checkPermissions' => FALSE,
index 73fdb03ccfb73d99df02d4a1f26daf412cc73941..f3b2ce370c5c8f71c6dad62100bd1cde6be08c9f 100644 (file)
@@ -21,31 +21,46 @@ namespace api\v4\Query;
 
 use Civi\Api4\Email;
 use api\v4\Api4TestBase;
-use Civi\Test\TransactionalInterface;
 
 /**
  * Class SelectQueryMultiJoinTest
  * @package api\v4\Query
  * @group headless
  */
-class SelectQueryMultiJoinTest extends Api4TestBase implements TransactionalInterface {
-
-  public function setUpHeadless() {
-    $this->cleanup(['tablesToTruncate' => ['civicrm_contact', 'civicrm_email']]);
-    $this->loadDataSet('MultiContactMultiEmail');
-    return parent::setUpHeadless();
-  }
+class SelectQueryMultiJoinTest extends Api4TestBase {
 
   public function testManyToOneSelect() {
+
+    $contact1 = $this->createTestRecord('Contact', [
+      'first_name' => 'First',
+      'last_name' => 'Contact',
+    ]);
+    $firstEmail = $this->createTestRecord('Email', [
+      'contact_id' => $contact1['id'],
+      'location_type_id:name' => 'Home',
+    ]);
+    $secondEmail = $this->createTestRecord('Email', [
+      'contact_id' => $contact1['id'],
+      'location_type_id:name' => 'Work',
+    ]);
+    $contact2 = $this->createTestRecord('Contact', [
+      'first_name' => 'Second',
+      'last_name' => 'Contact',
+    ]);
+    $thirdEmail = $this->createTestRecord('Email', [
+      'contact_id' => $contact2['id'],
+      'location_type_id:name' => 'Home',
+    ]);
+    $fourthEmail = $this->createTestRecord('Email', [
+      'contact_id' => $contact2['id'],
+      'location_type_id:name' => 'Work',
+    ]);
+
     $results = Email::get()
       ->addSelect('contact_id.display_name')
       ->execute()
       ->indexBy('id');
 
-    $firstEmail = $this->getReference('test_email_1');
-    $secondEmail = $this->getReference('test_email_2');
-    $thirdEmail = $this->getReference('test_email_3');
-    $fourthEmail = $this->getReference('test_email_4');
     $firstContactEmailIds = [$firstEmail['id'], $secondEmail['id']];
     $secondContactEmailIds = [$thirdEmail['id'], $fourthEmail['id']];
 
diff --git a/tests/phpunit/api/v4/Service/TestCreationParameterProvider.php b/tests/phpunit/api/v4/Service/TestCreationParameterProvider.php
deleted file mode 100644 (file)
index 7d016aa..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-<?php
-
-/*
- +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC. All rights reserved.                        |
- |                                                                    |
- | This work is published under the GNU AGPLv3 license with some      |
- | permitted exceptions and without any warranty. For full license    |
- | and copyright information, see https://civicrm.org/licensing       |
- +--------------------------------------------------------------------+
- */
-
-/**
- *
- * @package CRM
- * @copyright CiviCRM LLC https://civicrm.org/licensing
- */
-
-
-namespace api\v4\Service;
-
-use Civi\Api4\Service\Spec\FieldSpec;
-use Civi\Api4\Service\Spec\Provider\FinancialItemCreationSpecProvider;
-use Civi\Api4\Service\Spec\SpecGatherer;
-
-class TestCreationParameterProvider {
-
-  /**
-   * @var \Civi\Api4\Service\Spec\SpecGatherer
-   */
-  protected $gatherer;
-
-  /**
-   * @param \Civi\Api4\Service\Spec\SpecGatherer $gatherer
-   */
-  public function __construct(SpecGatherer $gatherer) {
-    $this->gatherer = $gatherer;
-  }
-
-  /**
-   * Get the required fields for the api entity + action.
-   *
-   * @param string $entity
-   *
-   * @return array
-   * @throws \API_Exception
-   */
-  public function getRequired(string $entity) {
-    $requiredFields = civicrm_api4($entity, 'getfields', [
-      'action' => 'create',
-      'loadOptions' => TRUE,
-      'where' => [
-        ['OR', [['required', '=', TRUE], ['required_if', 'IS NOT EMPTY']]],
-        ['readonly', 'IS EMPTY'],
-      ],
-    ], 'name');
-
-    $requiredParams = [];
-    foreach ($requiredFields as $fieldName => $requiredField) {
-      $requiredParams[$fieldName] = $this->getRequiredValue($requiredField);
-    }
-
-    // This is a ruthless hack to avoid peculiar constraints - but
-    // it's also a test class & hard to care enough to do something
-    // better
-    $overrides = [];
-    $overrides['UFField'] = [
-      'field_name' => 'activity_campaign_id',
-    ];
-    $overrides['Translation'] = [
-      'entity_table' => 'civicrm_event',
-      'entity_field' => 'description',
-      'entity_id' => \CRM_Core_DAO::singleValueQuery('SELECT min(id) FROM civicrm_event'),
-    ];
-
-    if (isset($overrides[$entity])) {
-      $requiredParams = array_merge($requiredParams, $overrides[$entity]);
-    }
-
-    return $requiredParams;
-  }
-
-  /**
-   * Attempt to get a value using field option, defaults, FKEntity, or a random
-   * value based on the data type.
-   *
-   * @param array $field
-   *
-   * @return mixed
-   * @throws \Exception
-   */
-  private function getRequiredValue(array $field) {
-
-    if (!empty($field['options'])) {
-      return key($field['options']);
-    }
-    if (!empty($field['fk_entity'])) {
-      return $this->getFkID($field['fk_entity']);
-    }
-    if (isset($field['default_value'])) {
-      return $field['default_value'];
-    }
-    if ($field['name'] === 'contact_id') {
-      return $this->getFkID('Contact');
-    }
-    if ($field['name'] === 'entity_id') {
-      // What could possibly go wrong with this?
-      switch ($field['table_name'] ?? NULL) {
-        case 'civicrm_financial_item':
-          return $this->getFkID(FinancialItemCreationSpecProvider::DEFAULT_ENTITY);
-
-        default:
-          return $this->getFkID('Contact');
-      }
-    }
-
-    $randomValue = $this->getRandomValue($field['data_type']);
-
-    if ($randomValue) {
-      return $randomValue;
-    }
-
-    throw new \API_Exception('Could not provide default value');
-  }
-
-  /**
-   * @param \Civi\Api4\Service\Spec\FieldSpec $field
-   *
-   * @return mixed
-   */
-  private function getOption(FieldSpec $field) {
-    $options = array_column($field->getOptions(), 'label', 'id');
-    return key($options);
-  }
-
-  /**
-   * Get an ID for the appropriate entity.
-   *
-   * @param string $fkEntity
-   *
-   * @return mixed
-   *
-   * @throws \API_Exception
-   */
-  private function getFkID(string $fkEntity) {
-    $params = ['checkPermissions' => FALSE];
-    // Be predictable about what type of contact we select
-    if ($fkEntity === 'Contact') {
-      $params['where'] = [['contact_type', '=', 'Individual']];
-    }
-    $entityList = civicrm_api4($fkEntity, 'get', $params);
-    // If no existing entities, create one
-    if ($entityList->count() < 1) {
-      $entityList = civicrm_api4($fkEntity, 'create', [
-        'checkPermissions' => FALSE,
-        'values' => $this->getRequired($fkEntity),
-      ]);
-    }
-
-    return $entityList->last()['id'];
-  }
-
-  /**
-   * @param $dataType
-   *
-   * @return int|null|string
-   */
-  private function getRandomValue($dataType) {
-    switch ($dataType) {
-      case 'Boolean':
-        return TRUE;
-
-      case 'Integer':
-        return random_int(1, 2000);
-
-      case 'String':
-        return \CRM_Utils_String::createRandom(10, implode('', range('a', 'z')));
-
-      case 'Text':
-        return \CRM_Utils_String::createRandom(100, implode('', range('a', 'z')));
-
-      case 'Money':
-        return sprintf('%d.%2d', rand(0, 2000), rand(10, 99));
-
-      case 'Date':
-        return '20100102';
-
-      case 'Timestamp':
-        return 'now';
-    }
-
-    return NULL;
-  }
-
-}
diff --git a/tests/phpunit/api/v4/Traits/TestDataLoaderTrait.php b/tests/phpunit/api/v4/Traits/TestDataLoaderTrait.php
deleted file mode 100644 (file)
index ce8d632..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-/*
- +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC. All rights reserved.                        |
- |                                                                    |
- | This work is published under the GNU AGPLv3 license with some      |
- | permitted exceptions and without any warranty. For full license    |
- | and copyright information, see https://civicrm.org/licensing       |
- +--------------------------------------------------------------------+
- */
-
-/**
- *
- * @package CRM
- * @copyright CiviCRM LLC https://civicrm.org/licensing
- */
-
-
-namespace api\v4\Traits;
-
-/**
- * This probably should be a separate class
- */
-trait TestDataLoaderTrait {
-
-  /**
-   * @var array
-   *   References to entities used for loading test data
-   */
-  protected $references;
-
-  /**
-   * Creates entities from a JSON data set
-   *
-   * @param $path
-   */
-  protected function loadDataSet($path) {
-    if (!file_exists($path)) {
-      $path = __DIR__ . '/../DataSets/' . $path . '.json';
-    }
-
-    $dataSet = json_decode(file_get_contents($path), TRUE);
-    foreach ($dataSet as $entityName => $entities) {
-      foreach ($entities as $entityValues) {
-
-        $entityValues = $this->replaceReferences($entityValues);
-
-        $params = ['values' => $entityValues, 'checkPermissions' => FALSE];
-        $result = civicrm_api4($entityName, 'create', $params);
-        if (isset($entityValues['@ref'])) {
-          $this->references[$entityValues['@ref']] = $result->first();
-        }
-      }
-    }
-  }
-
-  /**
-   * @param $name
-   *
-   * @return null|mixed
-   */
-  protected function getReference($name) {
-    return $this->references[$name] ?? NULL;
-  }
-
-  /**
-   * @param array $entityValues
-   *
-   * @return array
-   */
-  private function replaceReferences($entityValues) {
-    foreach ($entityValues as $name => $value) {
-      if (is_array($value)) {
-        $entityValues[$name] = $this->replaceReferences($value);
-      }
-      elseif (substr($value, 0, 4) === '@ref') {
-        $referenceName = substr($value, 5);
-        list ($reference, $property) = explode('.', $referenceName);
-        $entityValues[$name] = $this->references[$reference][$property];
-      }
-    }
-    return $entityValues;
-  }
-
-}