diff --git a/ext/legacycustomsearches/CRM/Contact/Form/Search/Custom/Base.php b/ext/legacycustomsearches/CRM/Contact/Form/Search/Custom/Base.php
index 43e59d3ff15a..6550170deb77 100644
--- a/ext/legacycustomsearches/CRM/Contact/Form/Search/Custom/Base.php
+++ b/ext/legacycustomsearches/CRM/Contact/Form/Search/Custom/Base.php
@@ -104,7 +104,7 @@ public function sql(
$sql = "SELECT $selectClause " . $this->from();
$where = $this->where();
if (!empty($where)) {
- $sql .= " WHERE " . $where;
+ $sql .= ' WHERE ' . $where;
}
if ($includeContactIDs) {
diff --git a/ext/legacycustomsearches/phpunit.xml.dist b/ext/legacycustomsearches/phpunit.xml.dist
new file mode 100644
index 000000000000..14dee7b067b2
--- /dev/null
+++ b/ext/legacycustomsearches/phpunit.xml.dist
@@ -0,0 +1,18 @@
+
+
+
+
+ ./tests/phpunit
+
+
+
+
+ ./
+
+
+
+
+
+
+
+
diff --git a/ext/legacycustomsearches/tests/phpunit/Civi/Searches/SampleTest.php b/ext/legacycustomsearches/tests/phpunit/Civi/Searches/SampleTest.php
new file mode 100644
index 000000000000..8ab593b024a0
--- /dev/null
+++ b/ext/legacycustomsearches/tests/phpunit/Civi/Searches/SampleTest.php
@@ -0,0 +1,357 @@
+install(['legacycustomsearches'])
+ ->apply();
+ }
+
+ /**
+ * Set up for test.
+ *
+ * @throws \API_Exception
+ * @throws \Civi\API\Exception\UnauthorizedException
+ */
+ public function setUp(): void {
+ OptionValue::create()->setValues([
+ 'option_group_id:name' => 'custom_search',
+ 'label' => 'CRM_Contact_Form_Search_Custom_Sample',
+ 'value' => 100,
+ 'name' => 'CRM_Contact_Form_Search_Custom_Sample',
+ 'description' => 'Household Name and State',
+ ])->execute();
+ }
+
+ /**
+ * Get data for tests.
+ *
+ * @return array
+ */
+ public function dataProvider(): array {
+ return [
+ // Search by Household name: 'Household 9'
+ [
+ 'form_values' => ['household_name' => 'Household - No state'],
+ 'names' => [
+ 'Household - No state',
+ ],
+ ],
+ // Search by Household name: 'Household'
+ [
+ 'form_values' => ['household_name' => 'Household'],
+ 'id' => [
+ 'Household - No state',
+ 'Household - CA',
+ 'Household - CA - 2',
+ 'Household - NY',
+ ],
+ ],
+ // Search by State: California
+ [
+ 'form_values' => ['state_province_id' => '1004'],
+ 'id' => [
+ 'Household - CA',
+ 'Household - CA - 2',
+ ],
+ ],
+ // Search by State: New York
+ [
+ 'form_values' => ['state_province_id' => '1031'],
+ 'id' => [
+ 'Household - NY',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Test CRM_Contact_Form_Search_Custom_Sample::count()
+ *
+ * @dataProvider dataProvider
+ *
+ * @param array $formValues
+ * @param array $names
+ *
+ * @throws \API_Exception
+ */
+ public function testCount(array $formValues, array $names): void {
+ $this->setupSampleData();
+ $obj = new CRM_Contact_Form_Search_Custom_Sample($formValues);
+ $this->assertEquals(count($names), $obj->count());
+ }
+
+ /**
+ * Test CRM_Contact_Form_Search_Custom_Sample::all()
+ *
+ * @dataProvider dataProvider
+ *
+ * @param array $formValues
+ * @param array $names
+ *
+ * @throws \API_Exception
+ */
+ public function testAll(array $formValues, array $names): void {
+ $this->setupSampleData();
+ $obj = new CRM_Contact_Form_Search_Custom_Sample($formValues);
+ $sql = $obj->all(0, 0, 'contact_id');
+ $this->assertIsString($sql);
+ $dao = CRM_Core_DAO::executeQuery($sql);
+ $all = [];
+ while ($dao->fetch()) {
+ $all[] = [
+ 'contact_id' => $dao->contact_id,
+ 'contact_type' => $dao->contact_type,
+ 'household_name' => $dao->sort_name,
+ ];
+ }
+ $full = [];
+ foreach ($names as $name) {
+ $full[] = [
+ 'contact_type' => 'Household',
+ 'household_name' => $name,
+ 'contact_id' => Contact::get()
+ ->addWhere('household_name', '=', $name)
+ ->execute()
+ ->first()['id'],
+ ];
+ }
+ asort($all);
+ $this->assertEquals($full, $all);
+ }
+
+ /**
+ * Test CRM_Contact_Form_Search_Custom_Sample::contactIDs().
+ *
+ * @dataProvider dataProvider
+ *
+ * @param array $formValues
+ * @param array $names
+ *
+ * @throws \API_Exception
+ */
+ public function testContactIDs(array $formValues, array $names): void {
+ $this->setupSampleData();
+ $obj = new CRM_Contact_Form_Search_Custom_Sample($formValues);
+ $sql = $obj->contactIDs();
+ $this->assertIsString($sql);
+ $dao = CRM_Core_DAO::executeQuery($sql);
+ $contacts = [];
+ while ($dao->fetch()) {
+ $contacts[$dao->contact_id] = 1;
+ }
+ $contacts = array_keys($contacts);
+ sort($contacts, SORT_NUMERIC);
+ $this->assertEquals($this->getContactIDs($names), $contacts);
+ }
+
+ /**
+ * Test CRM_Contact_Form_Search_Custom_Group::columns().
+ *
+ * It returns an array of translated name => keys
+ */
+ public function testColumns(): void {
+ $formValues = [];
+ $obj = new CRM_Contact_Form_Search_Custom_Sample($formValues);
+ $columns = $obj->columns();
+ $this->assertIsArray($columns);
+ foreach ($columns as $key => $value) {
+ $this->assertIsString($key);
+ $this->assertIsString($value);
+ }
+ }
+
+ /**
+ * Test CRM_Contact_Form_Search_Custom_Group::summary()
+ * It returns NULL
+ */
+ public function testSummary(): void {
+ $formValues = [];
+ $obj = new CRM_Contact_Form_Search_Custom_Group($formValues);
+ $this->assertNull($obj->summary());
+ }
+
+ /**
+ * Test CRM_Contact_Form_Search_Custom_Sample::templateFile()
+ * Returns the path to the file as a string
+ */
+ public function testTemplateFile(): void {
+ $formValues = [];
+ $obj = new CRM_Contact_Form_Search_Custom_Group($formValues);
+ $fileName = $obj->templateFile();
+ $this->assertIsString($fileName);
+ }
+
+ /**
+ * Test CRM_Contact_Form_Search_Custom_Sample with saved_search_id
+ * With true argument it returns list of contact IDs
+ *
+ * @throws \API_Exception
+ * @throws \CRM_Core_Exception
+ * @throws \CiviCRM_API3_Exception
+ * @throws \Civi\API\Exception\UnauthorizedException
+ */
+ public function testSavedSearch(): void {
+ $this->setupSampleData();
+ $this->setupSavedSearches();
+ $dataset[1] = ['id' => $this->getContactIDs(['Household - NY'])];
+ $dataset[2] = [
+ 'id' => $this->getContactIDs([
+ 'Household - CA',
+ 'Household - CA - 2',
+ ]),
+ ];
+ $searches = SavedSearch::get()->addSelect('*')->execute();
+ foreach ($searches as $search) {
+ $formValues = CRM_Contact_BAO_SavedSearch::getFormValues($search['id']);
+ $obj = new CRM_Contact_Form_Search_Custom_Sample($formValues);
+ $sql = $obj->contactIDs();
+ $this->assertIsString($sql);
+ $dao = CRM_Core_DAO::executeQuery($sql);
+ $contacts = [];
+ while ($dao->fetch()) {
+ $contacts[] = $dao->contact_id;
+ }
+ sort($contacts, SORT_NUMERIC);
+ $this->assertEquals($dataset[$search['id']]['id'], $contacts);
+ }
+ }
+
+ /**
+ * Set up our sample data.
+ *
+ * @throws \API_Exception
+ */
+ public function setupSampleData(): void {
+ $households = [
+ 'Household - No state' => '',
+ 'Household - CA' => 1004,
+ 'Household - CA - 2' => 1004,
+ 'Household - NY' => 1031,
+ ];
+ foreach ($households as $household => $state) {
+ $create = Contact::create(FALSE)->setValues([
+ 'contact_type' => 'Household',
+ 'household_name' => $household,
+ ]);
+ if ($state) {
+ $create->addChain(
+ 'address',
+ Address::create()->setValues([
+ 'contact_id' => '$id',
+ 'location_type_id' => 1,
+ 'state_province_id' => $state,
+ ]));
+ }
+ $create->execute();
+ }
+ }
+
+ /**
+ * Get the ids for the relevant contacts.@
+ *
+ * @return array
+ * IDs of the contacts.
+ *
+ * @throws \API_Exception
+ */
+ protected function getContactIDs($names): array {
+ return array_keys((array) Contact::get()->addWhere(
+ 'display_name', 'IN', $names
+ )->addOrderBy('id')->execute()->indexBy('id'));
+ }
+
+ /**
+ * Set up saved searches.
+ */
+ protected function setupSavedSearches(): void {
+ SavedSearch::create()->setValues([
+ 'form_values' => [
+ [
+ 0 => 'csid',
+ 1 => '=',
+ 2 => '1',
+ 3 => 0,
+ 4 => 0,
+ ],
+ [
+ 0 => 'household_name',
+ 1 => '=',
+ 2 => 'Household - NY',
+ 3 => 0,
+ 4 => 0,
+ ],
+ [
+ 0 => 'state_province_id',
+ 1 => '=',
+ 2 => '1031',
+ 3 => 0,
+ 4 => 0,
+ ],
+ 6 =>
+ [
+ 0 => 'customSearchID',
+ 1 => '=',
+ 2 => '1',
+ 3 => 0,
+ 4 => 0,
+ ],
+ 7 =>
+ [
+ 0 => 'customSearchClass',
+ 1 => '=',
+ 2 => 'CRM_Contact_Form_Search_Custom_Sample',
+ 3 => 0,
+ 4 => 0,
+ ],
+ ],
+ ])->execute();
+
+ SavedSearch::create()->setValues([
+ 'form_values' => [
+ 'csid' => '1',
+ 'household_name' => '',
+ 'state_province_id' => '1004',
+ ],
+ ])->execute();
+ }
+
+}
diff --git a/ext/legacycustomsearches/tests/phpunit/bootstrap.php b/ext/legacycustomsearches/tests/phpunit/bootstrap.php
new file mode 100644
index 000000000000..4da10a185a93
--- /dev/null
+++ b/ext/legacycustomsearches/tests/phpunit/bootstrap.php
@@ -0,0 +1,64 @@
+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 mixed
+ * Response output (if the command executed normally).
+ * For 'raw' or 'phpcode', this will be a string. For 'json', it could be any JSON value.
+ * @throws \RuntimeException
+ * If the command terminates abnormally.
+ */
+function cv(string $cmd, string $decode = 'json') {
+ $cmd = 'cv ' . $cmd;
+ $descriptorSpec = [0 => ['pipe', 'r'], 1 => ['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)");
+ }
+}
diff --git a/tests/phpunit/CRM/Contact/Form/Search/Custom/SampleTest.php b/tests/phpunit/CRM/Contact/Form/Search/Custom/SampleTest.php
deleted file mode 100644
index 297cbd30d18c..000000000000
--- a/tests/phpunit/CRM/Contact/Form/Search/Custom/SampleTest.php
+++ /dev/null
@@ -1,226 +0,0 @@
-setValues([
- 'option_group_id:name' => 'custom_search',
- 'label' => 'CRM_Contact_Form_Search_Custom_Sample',
- 'value' => 100,
- 'name' => 'CRM_Contact_Form_Search_Custom_Sample',
- 'description' => 'Household Name and State',
- ])->execute();
- }
-
- /**
- * Post test cleanup.
- *
- * @throws \API_Exception
- * @throws \CRM_Core_Exception
- * @throws \CiviCRM_API3_Exception
- * @throws \Civi\API\Exception\UnauthorizedException
- */
- public function tearDown(): void {
- $this->quickCleanup([
- 'civicrm_address',
- 'civicrm_saved_search',
- 'civicrm_contact',
- ]);
- OptionValue::delete()->addWhere('name', '=', 'CRM_Contact_Form_Search_Custom_Sample')->execute();
- parent::tearDown();
- }
-
- /**
- * @return \CRM_Contact_Form_Search_Custom_SampleTestDataProvider
- */
- public function dataProvider(): CRM_Contact_Form_Search_Custom_SampleTestDataProvider {
- return new CRM_Contact_Form_Search_Custom_SampleTestDataProvider();
- }
-
- /**
- * Test CRM_Contact_Form_Search_Custom_Sample::count()
- *
- * @dataProvider dataProvider
- *
- * @param array $fv
- * @param int $count
- */
- public function testCount(array $fv, int $count): void {
- $this->loadXMLDataSet(__DIR__ . '/datasets/sample-dataset.xml');
- $obj = new CRM_Contact_Form_Search_Custom_Sample($fv);
- $this->assertEquals($count, $obj->count());
- }
-
- /**
- * Test CRM_Contact_Form_Search_Custom_Sample::all()
- *
- * @dataProvider dataProvider
- *
- * @param array $fv
- * @param int $count
- * @param array $ids
- * @param array $full
- *
- * @noinspection PhpUnusedParameterInspection
- */
- public function testAll(array $fv, int $count, array $ids, array $full): void {
- $this->loadXMLDataSet(__DIR__ . '/datasets/sample-dataset.xml');
-
- $obj = new CRM_Contact_Form_Search_Custom_Sample($fv);
- $sql = $obj->all(0, 0, 'contact_id');
- $this->assertIsString($sql);
- $dao = CRM_Core_DAO::executeQuery($sql);
- $all = [];
- while ($dao->fetch()) {
- $all[] = [
- 'contact_id' => $dao->contact_id,
- 'contact_type' => $dao->contact_type,
- 'household_name' => $dao->sort_name,
- ];
- }
- asort($all);
- $this->assertEquals($full, $all);
- }
-
- /**
- * Test CRM_Contact_Form_Search_Custom_Sample::contactIDs()
- *
- * @dataProvider dataProvider
- *
- * @param array $fv
- * @param int $count
- * @param array $ids
- * @param array $full
- *
- * @noinspection PhpUnusedParameterInspection
- */
- public function testContactIDs(array $fv, int $count, array $ids, array $full): void {
- $this->loadXMLDataSet(__DIR__ . '/datasets/sample-dataset.xml');
- $obj = new CRM_Contact_Form_Search_Custom_Sample($fv);
- $sql = $obj->contactIDs();
- $this->assertIsString($sql);
- $dao = CRM_Core_DAO::executeQuery($sql);
- $contacts = [];
- while ($dao->fetch()) {
- $contacts[$dao->contact_id] = 1;
- }
- $contacts = array_keys($contacts);
- sort($contacts, SORT_NUMERIC);
- $this->assertEquals($ids, $contacts);
- }
-
- /**
- * Test CRM_Contact_Form_Search_Custom_Group::columns()
- * It returns an array of translated name => keys
- */
- public function testColumns(): void {
- $formValues = [];
- $obj = new CRM_Contact_Form_Search_Custom_Sample($formValues);
- $columns = $obj->columns();
- $this->assertIsArray($columns);
- foreach ($columns as $key => $value) {
- $this->assertIsString($key);
- $this->assertIsString($value);
- }
- }
-
- /**
- * Test CRM_Contact_Form_Search_Custom_Group::summary()
- * It returns NULL
- */
- public function testSummary(): void {
- $formValues = [];
- $obj = new CRM_Contact_Form_Search_Custom_Group($formValues);
- $this->assertNull($obj->summary());
- }
-
- /**
- * Test CRM_Contact_Form_Search_Custom_Sample::templateFile()
- * Returns the path to the file as a string
- */
- public function testTemplateFile(): void {
- $formValues = [];
- $obj = new CRM_Contact_Form_Search_Custom_Group($formValues);
- $fileName = $obj->templateFile();
- $this->assertIsString($fileName);
- //FIXME: we would need to search the include path to do the following
- //$this->assertTrue( file_exists( $fileName ) );
- }
-
- /**
- * Test CRM_Contact_Form_Search_Custom_Sample with saved_search_id
- * With true argument it returns list of contact IDs
- *
- * @throws \API_Exception
- * @throws \CRM_Core_Exception
- * @throws \CiviCRM_API3_Exception
- * @throws \Civi\API\Exception\UnauthorizedException
- */
- public function testSavedSearch(): void {
- $this->loadXMLDataSet(__DIR__ . '/datasets/sample-dataset.xml');
-
- $dataset[1] = ['id' => [12]];
- $dataset[2] = ['id' => [10, 11]];
-
- $searches = SavedSearch::get()->addSelect('*')->execute();
- foreach ($searches as $search) {
- $fv = CRM_Contact_BAO_SavedSearch::getFormValues($search['id']);
- $obj = new CRM_Contact_Form_Search_Custom_Sample($fv);
- $sql = $obj->contactIDs();
- $this->assertIsString($sql);
- $dao = CRM_Core_DAO::executeQuery($sql);
- $contacts = [];
- while ($dao->fetch()) {
- $contacts[] = $dao->contact_id;
- }
- sort($contacts, SORT_NUMERIC);
- $this->assertEquals($dataset[$search['id']]['id'], $contacts);
- }
- }
-
-}
diff --git a/tests/phpunit/CRM/Contact/Form/Search/Custom/SampleTestDataProvider.php b/tests/phpunit/CRM/Contact/Form/Search/Custom/SampleTestDataProvider.php
deleted file mode 100644
index fedc6f557398..000000000000
--- a/tests/phpunit/CRM/Contact/Form/Search/Custom/SampleTestDataProvider.php
+++ /dev/null
@@ -1,110 +0,0 @@
- ['household_name' => 'Household 9'],
- 'id' => [
- '9',
- ],
- ],
- // Search by Household name: 'Household'
- [
- 'fv' => ['household_name' => 'Household'],
- 'id' => [
- '9',
- '10',
- '11',
- '12',
- ],
- ],
- // Search by State: California
- [
- 'fv' => ['state_province_id' => '1004'],
- 'id' => [
- '10',
- '11',
- ],
- ],
- // Search by State: New York
- [
- 'fv' => ['state_province_id' => '1031'],
- 'id' => [
- '12',
- ],
- ],
- ];
-
- public function _construct() {
- $this->i = 0;
- }
-
- public function rewind() {
- $this->i = 0;
- }
-
- /**
- * @return array
- */
- public function current() {
- $count = count($this->dataset[$this->i]['id']);
- $ids = $this->dataset[$this->i]['id'];
- $full = [];
- foreach ($this->dataset[$this->i]['id'] as $key => $value) {
- $full[] = [
- 'contact_id' => $value,
- 'contact_type' => 'Household',
- 'household_name' => "Household $value",
- ];
- }
- return [$this->dataset[$this->i]['fv'], $count, $ids, $full];
- }
-
- /**
- * @return int
- */
- public function key() {
- return $this->i;
- }
-
- public function next() {
- $this->i++;
- }
-
- /**
- * @return bool
- */
- public function valid() {
- return isset($this->dataset[$this->i]);
- }
-
-}
diff --git a/tests/phpunit/CRM/Contact/Form/Search/Custom/datasets/sample-dataset.xml b/tests/phpunit/CRM/Contact/Form/Search/Custom/datasets/sample-dataset.xml
deleted file mode 100644
index 7f323889ac94..000000000000
--- a/tests/phpunit/CRM/Contact/Form/Search/Custom/datasets/sample-dataset.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-