3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
13 * Verify that the REST API bindings correctly parse and authenticate requests.
17 class E2E_Extern_RestTest
extends CiviEndToEndTestCase
{
19 protected static $api_key;
20 protected $session_id;
21 protected $nocms_contact_id;
22 protected $old_api_keys;
23 protected $adminContactId;
28 * @param string $prefix
30 protected function assertAPIErrorCode($apiResult, $cmpvar, $prefix = '') {
31 if (!empty($prefix)) {
34 $this->assertEquals($cmpvar, $apiResult['is_error'],
35 $prefix . (empty($apiResult['error_message']) ?
'' : $apiResult['error_message']));
36 //$this->assertEquals($cmpvar, $apiResult['is_error'], $prefix . print_r($apiResult, TRUE));
39 protected function setUp() {
42 if (empty($GLOBALS['_CV']['CIVI_SITE_KEY'])) {
43 $this->markTestSkipped('Missing siteKey');
46 $this->old_api_keys
= array();
49 protected function getRestUrl() {
50 return CRM_Core_Resources
::singleton()
51 ->getUrl('civicrm', 'extern/rest.php');
54 protected function tearDown() {
55 if (!empty($this->old_api_keys
)) {
56 foreach ($this->old_api_keys
as $cid => $apiKey) {
57 civicrm_api3('Contact', 'create', array(
64 if (isset($this->nocms_contact_id
)) {
65 $deleteParams = array(
66 "id" => $this->nocms_contact_id
,
69 $res = civicrm_api3("Contact", "delete", $deleteParams);
70 unset($this->nocms_contact_id
);
75 * Build a list of test cases. Each test case defines a set of REST query
76 * parameters and an expected outcome for the REST request (eg is_error=>1 or is_error=>0).
78 * @return array; each item is a list of parameters for testAPICalls
80 public function apiTestCases() {
83 // entity,action: omit apiKey, valid entity+action
87 "entity" => "Contact",
89 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
96 // entity,action: valid apiKey, valid entity+action
100 "entity" => "Contact",
102 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
104 "api_key" => self
::getApiKey(),
110 // entity,action: bad apiKey, valid entity+action
114 "entity" => "Contact",
116 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
118 "api_key" => 'garbage_' . self
::getApiKey(),
124 // entity,action: valid apiKey, invalid entity+action
128 "entity" => "Contactses",
130 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
132 "api_key" => self
::getApiKey(),
138 // q=civicrm/entity/action: omit apiKey, valid entity+action
142 "q" => "civicrm/contact/get",
143 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
150 // q=civicrm/entity/action: valid apiKey, valid entity+action
154 "q" => "civicrm/contact/get",
155 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
157 "api_key" => self
::getApiKey(),
163 // q=civicrm/entity/action: invalid apiKey, valid entity+action
167 "q" => "civicrm/contact/get",
168 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
170 "api_key" => 'garbage_' . self
::getApiKey(),
176 // q=civicrm/entity/action: valid apiKey, invalid entity+action
180 "q" => "civicrm/contactses/get",
181 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
183 "api_key" => self
::getApiKey(),
189 // q=civicrm/entity/action: valid apiKey, invalid entity+action
190 // XXX Actually Ping is valid, no?
194 "q" => "civicrm/ping",
195 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
197 "api_key" => self
::getApiKey(),
207 * @dataProvider apiTestCases
211 public function testAPICalls($query, $is_error) {
212 $this->updateAdminApiKey();
214 $client = CRM_Utils_HttpClient
::singleton();
215 list($status, $data) = $client->post($this->getRestUrl(), $query);
216 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
217 $result = json_decode($data, TRUE);
218 if ($result === NULL) {
219 $msg = print_r(array(
220 'restUrl' => $this->getRestUrl(),
222 'response data' => $data,
224 $this->assertNotNull($result, $msg);
226 $this->assertAPIErrorCode($result, $is_error);
230 * Submit a request with an API key that exists but does not correspond to.
231 * a real user. Submit in "?entity=X&action=X" notation
233 public function testNotCMSUser_entityAction() {
234 $client = CRM_Utils_HttpClient
::singleton();
236 //Create contact with api_key
237 $test_key = "testing1234";
238 $contactParams = array(
239 "api_key" => $test_key,
240 "contact_type" => "Individual",
241 "first_name" => "RestTester1",
243 $contact = civicrm_api3("Contact", "create", $contactParams);
244 $this->nocms_contact_id
= $contact["id"];
246 // The key associates with a real contact but not a real user
248 "entity" => "Contact",
250 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
252 "api_key" => $test_key,
254 list($status, $data) = $client->post($this->getRestUrl(), $params);
255 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
256 $result = json_decode($data, TRUE);
257 $this->assertNotNull($result);
258 $this->assertAPIErrorCode($result, 1);
262 * Submit a request with an API key that exists but does not correspond to.
263 * a real user. Submit in "?entity=X&action=X" notation
265 public function testGetCorrectUserBack() {
266 $this->updateAdminApiKey();
267 $client = CRM_Utils_HttpClient
::singleton();
269 //Create contact with api_key
270 // The key associates with a real contact but not a real user
272 "entity" => "Contact",
274 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
276 "api_key" => self
::getApiKey(),
277 "id" => "user_contact_id",
279 list($status, $data) = $client->post($this->getRestUrl(), $params);
280 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
281 $result = json_decode($data, TRUE);
282 $this->assertNotNull($result);
283 $this->assertEquals($result['id'], $this->adminContactId
);
287 * Submit a request with an API key that exists but does not correspond to
288 * a real user. Submit in "?q=civicrm/$entity/$action" notation
290 public function testNotCMSUser_q() {
291 $client = CRM_Utils_HttpClient
::singleton();
293 //Create contact with api_key
294 $test_key = "testing1234";
295 $contactParams = array(
296 "api_key" => $test_key,
297 "contact_type" => "Individual",
298 "first_name" => "RestTester1",
300 $contact = civicrm_api3("Contact", "create", $contactParams);
301 $this->nocms_contact_id
= $contact["id"];
303 // The key associates with a real contact but not a real user
305 "q" => "civicrm/contact/get",
306 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
308 "api_key" => $test_key,
310 list($status, $data) = $client->post($this->getRestUrl(), $params);
311 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
312 $result = json_decode($data, TRUE);
313 $this->assertNotNull($result);
314 $this->assertAPIErrorCode($result, 1);
317 protected function updateAdminApiKey() {
318 /** @var int $adminContactId */
319 $this->adminContactId
= civicrm_api3('contact', 'getvalue', array(
320 'id' => '@user:' . $GLOBALS['_CV']['ADMIN_USER'],
324 $this->old_api_keys
[$this->adminContactId
] = CRM_Core_DAO
::singleValueQuery('SELECT api_key FROM civicrm_contact WHERE id = %1', [
325 1 => [$this->adminContactId
, 'Positive'],
328 //$this->old_admin_api_key = civicrm_api3('Contact', 'get', array(
329 // 'id' => $adminContactId,
330 // 'return' => 'api_key',
333 civicrm_api3('Contact', 'create', array(
334 'id' => $this->adminContactId
,
335 'api_key' => self
::getApiKey(),
339 protected static function getApiKey() {
340 if (empty(self
::$api_key)) {
341 self
::$api_key = mt_rand() . mt_rand();
343 return self
::$api_key;