836eb043 |
1 | <?php |
2 | /* |
3 | +--------------------------------------------------------------------+ |
4 | | CiviCRM version 4.7 | |
5 | +--------------------------------------------------------------------+ |
6 | | Copyright CiviCRM LLC (c) 2004-2015 | |
7 | +--------------------------------------------------------------------+ |
8 | | This file is a part of CiviCRM. | |
9 | | | |
10 | | CiviCRM is free software; you can copy, modify, and distribute it | |
11 | | under the terms of the GNU Affero General Public License | |
12 | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | |
13 | | | |
14 | | CiviCRM is distributed in the hope that it will be useful, but | |
15 | | WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
17 | | See the GNU Affero General Public License for more details. | |
18 | | | |
19 | | You should have received a copy of the GNU Affero General Public | |
20 | | License and the CiviCRM Licensing Exception along | |
21 | | with this program; if not, contact CiviCRM LLC | |
22 | | at info[AT]civicrm[DOT]org. If you have questions about the | |
23 | | GNU Affero General Public License or the licensing of CiviCRM, | |
24 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | |
25 | +--------------------------------------------------------------------+ |
26 | */ |
27 | |
28 | /** |
29 | * Include parent class definition |
30 | */ |
836eb043 |
31 | |
32 | /** |
33 | * Test contact custom search functions |
34 | * |
35 | * @package CiviCRM |
36 | */ |
37 | class CRM_Contact_Form_SelectorTest extends CiviUnitTestCase { |
38 | |
39 | public function tearDown() { |
40 | |
41 | } |
42 | /** |
43 | * Test the query from the selector class is consistent with the dataset expectation. |
44 | * |
45 | * @param array $dataSet |
46 | * The data set to be tested. Note that when adding new datasets often only form_values and expected where |
47 | * clause will need changing. |
48 | * |
49 | * @dataProvider querySets |
50 | */ |
51 | public function testSelectorQuery($dataSet) { |
52 | $params = CRM_Contact_BAO_Query::convertFormValues($dataSet['form_values'], 0, FALSE, NULL, array()); |
53 | foreach ($dataSet['settings'] as $setting) { |
54 | $this->callAPISuccess('Setting', 'create', array($setting['name'] => $setting['value'])); |
55 | } |
56 | $selector = new CRM_Contact_Selector( |
57 | $dataSet['class'], |
58 | $dataSet['form_values'], |
59 | $params, |
60 | $dataSet['return_properties'], |
61 | $dataSet['action'], |
62 | $dataSet['includeContactIds'], |
63 | $dataSet['searchDescendentGroups'], |
64 | $dataSet['context'] |
65 | ); |
66 | $queryObject = $selector->getQueryObject(); |
67 | $sql = $queryObject->query(); |
68 | $this->wrangleDefaultClauses($dataSet['expected_query']); |
69 | foreach ($dataSet['expected_query'] as $index => $queryString) { |
70 | $this->assertEquals($this->strWrangle($queryString), $this->strWrangle($sql[$index])); |
71 | } |
72 | } |
73 | |
74 | /** |
75 | * Data sets for testing. |
76 | */ |
77 | public function querySets() { |
78 | return array( |
79 | array( |
80 | array( |
81 | 'description' => 'Normal default behaviour', |
82 | 'class' => 'CRM_Contact_Selector', |
83 | 'settings' => array(), |
84 | 'form_values' => array('email' => 'mickey@mouseville.com'), |
85 | 'params' => array(), |
86 | 'return_properties' => NULL, |
87 | 'context' => 'advanced', |
88 | 'action' => CRM_Core_Action::ADVANCED, |
89 | 'includeContactIds' => NULL, |
90 | 'searchDescendentGroups' => FALSE, |
91 | 'expected_query' => array( |
92 | 0 => 'default', |
93 | 1 => 'default', |
94 | 2 => "WHERE ( civicrm_email.email LIKE '%mickey@mouseville.com%' ) AND (contact_a.is_deleted = 0)", |
95 | ), |
96 | ), |
97 | ), |
98 | array( |
99 | array( |
100 | 'description' => 'Normal default + user added wildcard', |
101 | 'class' => 'CRM_Contact_Selector', |
102 | 'settings' => array(), |
103 | 'form_values' => array('email' => '%mickey@mouseville.com', 'sort_name' => 'Mouse'), |
104 | 'params' => array(), |
105 | 'return_properties' => NULL, |
106 | 'context' => 'advanced', |
107 | 'action' => CRM_Core_Action::ADVANCED, |
108 | 'includeContactIds' => NULL, |
109 | 'searchDescendentGroups' => FALSE, |
110 | 'expected_query' => array( |
111 | 0 => 'default', |
112 | 1 => 'default', |
113 | 2 => "WHERE ( civicrm_email.email LIKE '%mickey@mouseville.com%' AND ( ( ( contact_a.sort_name LIKE '%mouse%' ) OR ( civicrm_email.email LIKE '%mouse%' ) ) ) ) AND (contact_a.is_deleted = 0)", |
114 | ), |
115 | ), |
116 | ), |
117 | array( |
118 | array( |
119 | 'description' => 'Site set to not pre-pend wildcard', |
120 | 'class' => 'CRM_Contact_Selector', |
121 | 'settings' => array(array('name' => 'includeWildCardInName', 'value' => FALSE)), |
122 | 'form_values' => array('email' => 'mickey@mouseville.com', 'sort_name' => 'Mouse'), |
123 | 'params' => array(), |
124 | 'return_properties' => NULL, |
125 | 'context' => 'advanced', |
126 | 'action' => CRM_Core_Action::ADVANCED, |
127 | 'includeContactIds' => NULL, |
128 | 'searchDescendentGroups' => FALSE, |
129 | 'expected_query' => array( |
130 | 0 => 'default', |
131 | 1 => 'default', |
132 | 2 => "WHERE ( civicrm_email.email LIKE 'mickey@mouseville.com%' AND ( ( ( contact_a.sort_name LIKE 'mouse%' ) OR ( civicrm_email.email LIKE 'mouse%' ) ) ) ) AND (contact_a.is_deleted = 0)", |
133 | ), |
134 | ), |
135 | ), |
136 | array( |
137 | array( |
138 | 'description' => 'Use of quotes for exact string', |
139 | 'use_case_comments' => 'This is something that was in the code but seemingly not working. No UI info on it though!', |
140 | 'class' => 'CRM_Contact_Selector', |
141 | 'settings' => array(array('name' => 'includeWildCardInName', 'value' => FALSE)), |
142 | 'form_values' => array('email' => '"mickey@mouseville.com"', 'sort_name' => 'Mouse'), |
143 | 'params' => array(), |
144 | 'return_properties' => NULL, |
145 | 'context' => 'advanced', |
146 | 'action' => CRM_Core_Action::ADVANCED, |
147 | 'includeContactIds' => NULL, |
148 | 'searchDescendentGroups' => FALSE, |
149 | 'expected_query' => array( |
150 | 0 => 'default', |
151 | 1 => 'default', |
152 | 2 => "WHERE ( civicrm_email.email = 'mickey@mouseville.com' AND ( ( ( contact_a.sort_name LIKE 'mouse%' ) OR ( civicrm_email.email LIKE 'mouse%' ) ) ) ) AND (contact_a.is_deleted = 0)", |
153 | ), |
154 | ), |
155 | ), |
156 | ); |
157 | } |
158 | |
159 | /** |
160 | * Get the default select string since this is generally consistent. |
161 | */ |
162 | public function getDefaultSelectString() { |
163 | return 'SELECT contact_a.id as contact_id, contact_a.contact_type as `contact_type`, contact_a.contact_sub_type as `contact_sub_type`, contact_a.sort_name as `sort_name`,' |
164 | . ' contact_a.display_name as `display_name`, contact_a.do_not_email as `do_not_email`, contact_a.do_not_phone as `do_not_phone`, contact_a.do_not_mail as `do_not_mail`,' |
165 | . ' contact_a.do_not_sms as `do_not_sms`, contact_a.do_not_trade as `do_not_trade`, contact_a.is_opt_out as `is_opt_out`, contact_a.legal_identifier as `legal_identifier`,' |
166 | . ' contact_a.external_identifier as `external_identifier`, contact_a.nick_name as `nick_name`, contact_a.legal_name as `legal_name`, contact_a.image_URL as `image_URL`,' |
167 | . ' contact_a.preferred_communication_method as `preferred_communication_method`, contact_a.preferred_language as `preferred_language`,' |
168 | . ' contact_a.preferred_mail_format as `preferred_mail_format`, contact_a.first_name as `first_name`, contact_a.middle_name as `middle_name`, contact_a.last_name as `last_name`,' |
169 | . ' contact_a.prefix_id as `prefix_id`, contact_a.suffix_id as `suffix_id`, contact_a.formal_title as `formal_title`, contact_a.communication_style_id as `communication_style_id`,' |
170 | . ' contact_a.job_title as `job_title`, contact_a.gender_id as `gender_id`, contact_a.birth_date as `birth_date`, contact_a.is_deceased as `is_deceased`,' |
171 | . ' contact_a.deceased_date as `deceased_date`, contact_a.household_name as `household_name`,' |
172 | . ' IF ( contact_a.contact_type = \'Individual\', NULL, contact_a.organization_name ) as organization_name, contact_a.sic_code as `sic_code`, contact_a.is_deleted as `contact_is_deleted`,' |
173 | . ' IF ( contact_a.contact_type = \'Individual\', contact_a.organization_name, NULL ) as current_employer, civicrm_address.id as address_id,' |
174 | . ' civicrm_address.street_address as `street_address`, civicrm_address.supplemental_address_1 as `supplemental_address_1`, ' |
175 | . 'civicrm_address.supplemental_address_2 as `supplemental_address_2`, civicrm_address.city as `city`, civicrm_address.postal_code_suffix as `postal_code_suffix`, ' |
176 | . 'civicrm_address.postal_code as `postal_code`, civicrm_address.geo_code_1 as `geo_code_1`, civicrm_address.geo_code_2 as `geo_code_2`, ' |
177 | . 'civicrm_address.state_province_id as state_province_id, civicrm_address.country_id as country_id, civicrm_phone.id as phone_id, civicrm_phone.phone_type_id as phone_type_id, ' |
178 | . 'civicrm_phone.phone as `phone`, civicrm_email.id as email_id, civicrm_email.email as `email`, civicrm_email.on_hold as `on_hold`, civicrm_im.id as im_id, ' |
179 | . 'civicrm_im.provider_id as provider_id, civicrm_im.name as `im`, civicrm_worldregion.id as worldregion_id, civicrm_worldregion.name as `world_region`'; |
180 | } |
181 | |
182 | /** |
183 | * Get the default from string since this is generally consistent. |
184 | */ |
185 | public function getDefaultFromString() { |
186 | return ' FROM civicrm_contact contact_a LEFT JOIN civicrm_address ON ( contact_a.id = civicrm_address.contact_id AND civicrm_address.is_primary = 1 )' |
187 | . ' LEFT JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id AND civicrm_email.is_primary = 1)' |
188 | . ' LEFT JOIN civicrm_phone ON (contact_a.id = civicrm_phone.contact_id AND civicrm_phone.is_primary = 1)' |
189 | . ' LEFT JOIN civicrm_im ON (contact_a.id = civicrm_im.contact_id AND civicrm_im.is_primary = 1) ' |
190 | . 'LEFT JOIN civicrm_country ON civicrm_address.country_id = civicrm_country.id LEFT JOIN civicrm_worldregion ON civicrm_country.region_id = civicrm_worldregion.id '; |
191 | } |
192 | |
193 | /** |
194 | * Strangle strings into a more matchable format. |
195 | * |
196 | * @param string $string |
197 | * @return string |
198 | */ |
199 | public function strWrangle($string) { |
200 | return str_replace(' ', ' ', $string); |
201 | } |
202 | |
203 | /** |
204 | * Swap out default parts of the query for the actual string. |
205 | * |
206 | * Note that it seems to make more sense to resolve this earlier & pass it in from a clean code point of |
207 | * view, but the output on fail includes long sql statements that are of low relevance then. |
208 | * |
209 | * @param array $expectedQuery |
210 | */ |
211 | public function wrangleDefaultClauses(&$expectedQuery) { |
212 | if ($expectedQuery[0] == 'default') { |
213 | $expectedQuery[0] = $this->getDefaultSelectString(); |
214 | } |
215 | if ($expectedQuery[1] == 'default') { |
216 | $expectedQuery[1] = $this->getDefaultFromString(); |
217 | } |
218 | } |
219 | |
220 | } |