3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License along with this program; if not, contact CiviCRM LLC |
21 | at info[AT]civicrm[DOT]org. If you have questions about the |
22 | GNU Affero General Public License or the licensing of CiviCRM, |
23 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
24 +--------------------------------------------------------------------+
28 * Verify that the REST API bindings correctly parse and authenticate requests.
32 class E2E_Extern_RestTest
extends CiviEndToEndTestCase
{
34 protected static $api_key;
35 protected $session_id;
36 protected $nocms_contact_id;
37 protected $old_api_keys;
38 protected $adminContactId;
43 * @param string $prefix
45 protected function assertAPIErrorCode($apiResult, $cmpvar, $prefix = '') {
46 if (!empty($prefix)) {
49 $this->assertEquals($cmpvar, $apiResult['is_error'],
50 $prefix . (empty($apiResult['error_message']) ?
'' : $apiResult['error_message']));
51 //$this->assertEquals($cmpvar, $apiResult['is_error'], $prefix . print_r($apiResult, TRUE));
54 protected function setUp() {
57 if (empty($GLOBALS['_CV']['CIVI_SITE_KEY'])) {
58 $this->markTestSkipped('Missing siteKey');
61 $this->old_api_keys
= array();
64 protected function getRestUrl() {
65 return CRM_Core_Resources
::singleton()
66 ->getUrl('civicrm', 'extern/rest.php');
69 protected function tearDown() {
70 if (!empty($this->old_api_keys
)) {
71 foreach ($this->old_api_keys
as $cid => $apiKey) {
72 civicrm_api3('Contact', 'create', array(
79 if (isset($this->nocms_contact_id
)) {
80 $deleteParams = array(
81 "id" => $this->nocms_contact_id
,
84 $res = civicrm_api3("Contact", "delete", $deleteParams);
85 unset($this->nocms_contact_id
);
90 * Build a list of test cases. Each test case defines a set of REST query
91 * parameters and an expected outcome for the REST request (eg is_error=>1 or is_error=>0).
93 * @return array; each item is a list of parameters for testAPICalls
95 public function apiTestCases() {
98 // entity,action: omit apiKey, valid entity+action
102 "entity" => "Contact",
104 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
111 // entity,action: valid apiKey, valid entity+action
115 "entity" => "Contact",
117 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
119 "api_key" => self
::getApiKey(),
125 // entity,action: bad apiKey, valid entity+action
129 "entity" => "Contact",
131 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
133 "api_key" => 'garbage_' . self
::getApiKey(),
139 // entity,action: valid apiKey, invalid entity+action
143 "entity" => "Contactses",
145 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
147 "api_key" => self
::getApiKey(),
153 // q=civicrm/entity/action: omit apiKey, valid entity+action
157 "q" => "civicrm/contact/get",
158 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
165 // q=civicrm/entity/action: valid apiKey, valid entity+action
169 "q" => "civicrm/contact/get",
170 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
172 "api_key" => self
::getApiKey(),
178 // q=civicrm/entity/action: invalid apiKey, valid entity+action
182 "q" => "civicrm/contact/get",
183 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
185 "api_key" => 'garbage_' . self
::getApiKey(),
191 // q=civicrm/entity/action: valid apiKey, invalid entity+action
195 "q" => "civicrm/contactses/get",
196 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
198 "api_key" => self
::getApiKey(),
204 // q=civicrm/entity/action: valid apiKey, invalid entity+action
205 // XXX Actually Ping is valid, no?
209 "q" => "civicrm/ping",
210 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
212 "api_key" => self
::getApiKey(),
222 * @dataProvider apiTestCases
226 public function testAPICalls($query, $is_error) {
227 $this->updateAdminApiKey();
229 $client = CRM_Utils_HttpClient
::singleton();
230 list($status, $data) = $client->post($this->getRestUrl(), $query);
231 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
232 $result = json_decode($data, TRUE);
233 if ($result === NULL) {
234 $msg = print_r(array(
235 'restUrl' => $this->getRestUrl(),
237 'response data' => $data,
239 $this->assertNotNull($result, $msg);
241 $this->assertAPIErrorCode($result, $is_error);
245 * Submit a request with an API key that exists but does not correspond to.
246 * a real user. Submit in "?entity=X&action=X" notation
248 public function testNotCMSUser_entityAction() {
249 $client = CRM_Utils_HttpClient
::singleton();
251 //Create contact with api_key
252 $test_key = "testing1234";
253 $contactParams = array(
254 "api_key" => $test_key,
255 "contact_type" => "Individual",
256 "first_name" => "RestTester1",
258 $contact = civicrm_api3("Contact", "create", $contactParams);
259 $this->nocms_contact_id
= $contact["id"];
261 // The key associates with a real contact but not a real user
263 "entity" => "Contact",
265 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
267 "api_key" => $test_key,
269 list($status, $data) = $client->post($this->getRestUrl(), $params);
270 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
271 $result = json_decode($data, TRUE);
272 $this->assertNotNull($result);
273 $this->assertAPIErrorCode($result, 1);
277 * Submit a request with an API key that exists but does not correspond to.
278 * a real user. Submit in "?entity=X&action=X" notation
280 public function testGetCorrectUserBack() {
281 $this->updateAdminApiKey();
282 $client = CRM_Utils_HttpClient
::singleton();
284 //Create contact with api_key
285 // The key associates with a real contact but not a real user
287 "entity" => "Contact",
289 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
291 "api_key" => self
::getApiKey(),
292 "id" => "user_contact_id",
294 list($status, $data) = $client->post($this->getRestUrl(), $params);
295 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
296 $result = json_decode($data, TRUE);
297 $this->assertNotNull($result);
298 $this->assertEquals($result['id'], $this->adminContactId
);
302 * Submit a request with an API key that exists but does not correspond to
303 * a real user. Submit in "?q=civicrm/$entity/$action" notation
305 public function testNotCMSUser_q() {
306 $client = CRM_Utils_HttpClient
::singleton();
308 //Create contact with api_key
309 $test_key = "testing1234";
310 $contactParams = array(
311 "api_key" => $test_key,
312 "contact_type" => "Individual",
313 "first_name" => "RestTester1",
315 $contact = civicrm_api3("Contact", "create", $contactParams);
316 $this->nocms_contact_id
= $contact["id"];
318 // The key associates with a real contact but not a real user
320 "q" => "civicrm/contact/get",
321 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
323 "api_key" => $test_key,
325 list($status, $data) = $client->post($this->getRestUrl(), $params);
326 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
327 $result = json_decode($data, TRUE);
328 $this->assertNotNull($result);
329 $this->assertAPIErrorCode($result, 1);
332 protected function updateAdminApiKey() {
333 /** @var int $adminContactId */
334 $this->adminContactId
= civicrm_api3('contact', 'getvalue', array(
335 'id' => '@user:' . $GLOBALS['_CV']['ADMIN_USER'],
339 $this->old_api_keys
[$this->adminContactId
] = CRM_Core_DAO
::singleValueQuery('SELECT api_key FROM civicrm_contact WHERE id = %1', [
340 1 => [$this->adminContactId
, 'Positive'],
343 //$this->old_admin_api_key = civicrm_api3('Contact', 'get', array(
344 // 'id' => $adminContactId,
345 // 'return' => 'api_key',
348 civicrm_api3('Contact', 'create', array(
349 'id' => $this->adminContactId
,
350 'api_key' => self
::getApiKey(),
354 protected static function getApiKey() {
355 if (empty(self
::$api_key)) {
356 self
::$api_key = mt_rand() . mt_rand();
358 return self
::$api_key;