3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2018 |
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;
42 * @param string $prefix
44 protected function assertAPIErrorCode($apiResult, $cmpvar, $prefix = '') {
45 if (!empty($prefix)) {
48 $this->assertEquals($cmpvar, $apiResult['is_error'],
49 $prefix . (empty($apiResult['error_message']) ?
'' : $apiResult['error_message']));
50 //$this->assertEquals($cmpvar, $apiResult['is_error'], $prefix . print_r($apiResult, TRUE));
53 protected function setUp() {
56 if (empty($GLOBALS['_CV']['CIVI_SITE_KEY'])) {
57 $this->markTestSkipped('Missing siteKey');
60 $this->old_api_keys
= array();
63 protected function getRestUrl() {
64 return CRM_Core_Resources
::singleton()
65 ->getUrl('civicrm', 'extern/rest.php');
68 protected function tearDown() {
69 if (!empty($this->old_api_keys
)) {
70 foreach ($this->old_api_keys
as $cid => $apiKey) {
71 civicrm_api3('Contact', 'create', array(
78 if (isset($this->nocms_contact_id
)) {
79 $deleteParams = array(
80 "id" => $this->nocms_contact_id
,
83 $res = civicrm_api3("Contact", "delete", $deleteParams);
84 unset($this->nocms_contact_id
);
89 * Build a list of test cases. Each test case defines a set of REST query
90 * parameters and an expected outcome for the REST request (eg is_error=>1 or is_error=>0).
92 * @return array; each item is a list of parameters for testAPICalls
94 public function apiTestCases() {
97 // entity,action: omit apiKey, valid entity+action
100 "entity" => "Contact",
102 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
108 // entity,action: valid apiKey, valid entity+action
111 "entity" => "Contact",
113 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
115 "api_key" => self
::getApiKey(),
120 // entity,action: bad apiKey, valid entity+action
123 "entity" => "Contact",
125 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
127 "api_key" => 'garbage_' . self
::getApiKey(),
132 // entity,action: valid apiKey, invalid entity+action
135 "entity" => "Contactses",
137 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
139 "api_key" => self
::getApiKey(),
144 // q=civicrm/entity/action: omit apiKey, valid entity+action
147 "q" => "civicrm/contact/get",
148 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
154 // q=civicrm/entity/action: valid apiKey, valid entity+action
157 "q" => "civicrm/contact/get",
158 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
160 "api_key" => self
::getApiKey(),
165 // q=civicrm/entity/action: invalid apiKey, valid entity+action
168 "q" => "civicrm/contact/get",
169 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
171 "api_key" => 'garbage_' . self
::getApiKey(),
176 // q=civicrm/entity/action: valid apiKey, invalid entity+action
179 "q" => "civicrm/contactses/get",
180 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
182 "api_key" => self
::getApiKey(),
187 // q=civicrm/entity/action: valid apiKey, invalid entity+action
188 // XXX Actually Ping is valid, no?
191 "q" => "civicrm/ping",
192 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
194 "api_key" => self
::getApiKey(),
203 * @dataProvider apiTestCases
207 public function testAPICalls($query, $is_error) {
208 $this->updateAdminApiKey();
210 $client = CRM_Utils_HttpClient
::singleton();
211 list($status, $data) = $client->post($this->getRestUrl(), $query);
212 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
213 $result = json_decode($data, TRUE);
214 if ($result === NULL) {
215 $msg = print_r(array(
216 'restUrl' => $this->getRestUrl(),
218 'response data' => $data,
220 $this->assertNotNull($result, $msg);
222 $this->assertAPIErrorCode($result, $is_error);
226 * Submit a request with an API key that exists but does not correspond to.
227 * a real user. Submit in "?entity=X&action=X" notation
229 public function testNotCMSUser_entityAction() {
230 $client = CRM_Utils_HttpClient
::singleton();
232 //Create contact with api_key
233 $test_key = "testing1234";
234 $contactParams = array(
235 "api_key" => $test_key,
236 "contact_type" => "Individual",
237 "first_name" => "RestTester1",
239 $contact = civicrm_api3("Contact", "create", $contactParams);
240 $this->nocms_contact_id
= $contact["id"];
242 // The key associates with a real contact but not a real user
244 "entity" => "Contact",
246 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
248 "api_key" => $test_key,
250 list($status, $data) = $client->post($this->getRestUrl(), $params);
251 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
252 $result = json_decode($data, TRUE);
253 $this->assertNotNull($result);
254 $this->assertAPIErrorCode($result, 1);
258 * Submit a request with an API key that exists but does not correspond to
259 * a real user. Submit in "?q=civicrm/$entity/$action" notation
261 public function testNotCMSUser_q() {
262 $client = CRM_Utils_HttpClient
::singleton();
264 //Create contact with api_key
265 $test_key = "testing1234";
266 $contactParams = array(
267 "api_key" => $test_key,
268 "contact_type" => "Individual",
269 "first_name" => "RestTester1",
271 $contact = civicrm_api3("Contact", "create", $contactParams);
272 $this->nocms_contact_id
= $contact["id"];
274 // The key associates with a real contact but not a real user
276 "q" => "civicrm/contact/get",
277 "key" => $GLOBALS['_CV']['CIVI_SITE_KEY'],
279 "api_key" => $test_key,
281 list($status, $data) = $client->post($this->getRestUrl(), $params);
282 $this->assertEquals(CRM_Utils_HttpClient
::STATUS_OK
, $status);
283 $result = json_decode($data, TRUE);
284 $this->assertNotNull($result);
285 $this->assertAPIErrorCode($result, 1);
288 protected function updateAdminApiKey() {
289 /** @var int $adminContactId */
290 $adminContactId = civicrm_api3('contact', 'getvalue', array(
291 'id' => '@user:' . $GLOBALS['_CV']['ADMIN_USER'],
295 $this->old_api_keys
[$adminContactId] = CRM_Core_DAO
::singleValueQuery('SELECT api_key FROM civicrm_contact WHERE id = %1',
297 1 => array($adminContactId, 'Positive'),
300 //$this->old_admin_api_key = civicrm_api3('Contact', 'get', array(
301 // 'id' => $adminContactId,
302 // 'return' => 'api_key',
305 civicrm_api3('Contact', 'create', array(
306 'id' => $adminContactId,
307 'api_key' => self
::getApiKey(),
311 protected static function getApiKey() {
312 if (empty(self
::$api_key)) {
313 self
::$api_key = mt_rand() . mt_rand();
315 return self
::$api_key;