PageRenderTime 93ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/service/RESTAPI3Test.php

https://bitbucket.org/cviolette/sugarcrm
PHP | 823 lines | 625 code | 130 blank | 68 comment | 47 complexity | 50e57cf74ba6f7cd6789eebebc2ecc40 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. <?php
  2. /*********************************************************************************
  3. * SugarCRM Community Edition is a customer relationship management program developed by
  4. * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU Affero General Public License version 3 as published by the
  8. * Free Software Foundation with the addition of the following permission added
  9. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  10. * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
  11. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  12. *
  13. * This program is distributed in the hope that it will be useful, but WITHOUT
  14. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  15. * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License along with
  19. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  20. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  21. * 02110-1301 USA.
  22. *
  23. * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
  24. * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
  25. *
  26. * The interactive user interfaces in modified source and object code versions
  27. * of this program must display Appropriate Legal Notices, as required under
  28. * Section 5 of the GNU Affero General Public License version 3.
  29. *
  30. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  31. * these Appropriate Legal Notices must retain the display of the "Powered by
  32. * SugarCRM" logo. If the display of the logo is not reasonably feasible for
  33. * technical reasons, the Appropriate Legal Notices must display the words
  34. * "Powered by SugarCRM".
  35. ********************************************************************************/
  36. require_once('service/v3/SugarWebServiceUtilv3.php');
  37. require_once('tests/service/APIv3Helper.php');
  38. class RESTAPI3Test extends Sugar_PHPUnit_Framework_TestCase
  39. {
  40. protected $_user;
  41. protected $_lastRawResponse;
  42. private static $helperObject;
  43. private $_unified_search_modules_content;
  44. public function setUp()
  45. {
  46. global $beanList, $beanFiles;
  47. include('include/modules.php');
  48. //Reload langauge strings
  49. $GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
  50. $GLOBALS['app_list_strings'] = return_app_list_strings_language($GLOBALS['current_language']);
  51. $GLOBALS['mod_strings'] = return_module_language($GLOBALS['current_language'], 'Accounts');
  52. //Create an anonymous user for login purposes/
  53. $this->_user = SugarTestUserUtilities::createAnonymousUser();
  54. $GLOBALS['current_user'] = $this->_user;
  55. self::$helperObject = new APIv3Helper();
  56. if(file_exists(sugar_cached('modules/unified_search_modules.php')))
  57. {
  58. $this->unified_search_modules_content = file_get_contents(sugar_cached('modules/unified_search_modules.php'));
  59. unlink(sugar_cached('modules/unified_search_modules.php'));
  60. }
  61. require_once('modules/Home/UnifiedSearchAdvanced.php');
  62. $unifiedSearchAdvanced = new UnifiedSearchAdvanced();
  63. $_REQUEST['enabled_modules'] = 'Accounts,Contacts,Opportunities';
  64. $unifiedSearchAdvanced->saveGlobalSearchSettings();
  65. $GLOBALS['db']->query("DELETE FROM accounts WHERE name like 'UNIT TEST%' ");
  66. $GLOBALS['db']->query("DELETE FROM opportunities WHERE name like 'UNIT TEST%' ");
  67. $GLOBALS['db']->query("DELETE FROM contacts WHERE first_name like 'UNIT TEST%' ");
  68. $GLOBALS['db']->query("DELETE FROM calls WHERE name like 'UNIT TEST%' ");
  69. $GLOBALS['db']->query("DELETE FROM tasks WHERE name like 'UNIT TEST%' ");
  70. $GLOBALS['db']->query("DELETE FROM meetings WHERE name like 'UNIT TEST%' ");
  71. $GLOBALS['db']->commit();
  72. //$this->useOutputBuffering = false;
  73. }
  74. public function tearDown()
  75. {
  76. if(isset($GLOBALS['listViewDefs'])) unset($GLOBALS['listViewDefs']);
  77. if(isset($GLOBALS['viewdefs'])) unset($GLOBALS['viewdefs']);
  78. unset($GLOBALS['app_list_strings']);
  79. unset($GLOBALS['app_strings']);
  80. unset($GLOBALS['mod_strings']);
  81. if(!empty($this->unified_search_modules_content))
  82. {
  83. file_put_contents(sugar_cached('modules/unified_search_modules.php'), $this->unified_search_modules_content);
  84. }
  85. $GLOBALS['db']->query("DELETE FROM accounts WHERE name like 'UNIT TEST%' ");
  86. $GLOBALS['db']->query("DELETE FROM opportunities WHERE name like 'UNIT TEST%' ");
  87. $GLOBALS['db']->query("DELETE FROM contacts WHERE first_name like 'UNIT TEST%' ");
  88. $GLOBALS['db']->query("DELETE FROM calls WHERE name like 'UNIT TEST%' ");
  89. $GLOBALS['db']->query("DELETE FROM tasks WHERE name like 'UNIT TEST%' ");
  90. $GLOBALS['db']->query("DELETE FROM meetings WHERE name like 'UNIT TEST%' ");
  91. SugarTestUserUtilities::removeAllCreatedAnonymousUsers();
  92. }
  93. protected function _makeRESTCall($method,$parameters)
  94. {
  95. // specify the REST web service to interact with
  96. $url = $GLOBALS['sugar_config']['site_url'].'/service/v3/rest.php';
  97. // Open a curl session for making the call
  98. $curl = curl_init($url);
  99. // set URL and other appropriate options
  100. curl_setopt($curl, CURLOPT_URL, $url);
  101. curl_setopt($curl, CURLOPT_POST, 1);
  102. curl_setopt($curl, CURLOPT_HEADER, 0);
  103. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
  104. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  105. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 0);
  106. curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 );
  107. // build the request URL
  108. $json = json_encode($parameters);
  109. $postArgs = "method=$method&input_type=JSON&response_type=JSON&rest_data=$json";
  110. curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);
  111. // Make the REST call, returning the result
  112. $response = curl_exec($curl);
  113. // Close the connection
  114. curl_close($curl);
  115. $this->_lastRawResponse = $response;
  116. // Convert the result from JSON format to a PHP array
  117. return json_decode($response,true);
  118. }
  119. protected function _returnLastRawResponse()
  120. {
  121. return "Error in web services call. Response was: {$this->_lastRawResponse}";
  122. }
  123. protected function _login()
  124. {
  125. $GLOBALS['db']->commit(); // Making sure we commit any changes before logging in
  126. return $this->_makeRESTCall('login',
  127. array(
  128. 'user_auth' =>
  129. array(
  130. 'user_name' => $this->_user->user_name,
  131. 'password' => $this->_user->user_hash,
  132. 'version' => '.01',
  133. ),
  134. 'application_name' => 'SugarTestRunner',
  135. 'name_value_list' => array(),
  136. )
  137. );
  138. }
  139. public function testSearchByModule()
  140. {
  141. $seedData = self::$helperObject->populateSeedDataForSearchTest($this->_user->id);
  142. $searchModules = array('Accounts','Contacts','Opportunities');
  143. $searchString = "UNIT TEST";
  144. $offSet = 0;
  145. $maxResults = 10;
  146. $result = $this->_login(); // Logging in just before the REST call as this will also commit any pending DB changes
  147. $session = $result['id'];
  148. $results = $this->_makeRESTCall('search_by_module',
  149. array(
  150. 'session' => $session,
  151. 'search' => $searchString,
  152. 'modules' => $searchModules,
  153. 'offset' => $offSet,
  154. 'max' => $maxResults,
  155. 'user' => $this->_user->id)
  156. );
  157. $this->assertTrue( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[0]['id'],'Accounts') );
  158. $this->assertFalse( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[1]['id'],'Accounts') );
  159. $this->assertTrue( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[2]['id'],'Contacts') );
  160. $this->assertTrue( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[3]['id'],'Opportunities') );
  161. $this->assertFalse( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[4]['id'],'Opportunities') );
  162. }
  163. public function testSearchByModuleWithReturnFields()
  164. {
  165. $seedData = self::$helperObject->populateSeedDataForSearchTest($this->_user->id);
  166. $returnFields = array('name','id','deleted');
  167. $searchModules = array('Accounts','Contacts','Opportunities');
  168. $searchString = "UNIT TEST";
  169. $offSet = 0;
  170. $maxResults = 10;
  171. $result = $this->_login(); // Logging in just before the REST call as this will also commit any pending DB changes
  172. $session = $result['id'];
  173. $results = $this->_makeRESTCall('search_by_module',
  174. array(
  175. 'session' => $session,
  176. 'search' => $searchString,
  177. 'modules' => $searchModules,
  178. 'offset' => $offSet,
  179. 'max' => $maxResults,
  180. 'user' => $this->_user->id,
  181. 'selectFields' => $returnFields)
  182. );
  183. $this->assertEquals($seedData[0]['fieldValue'], self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[0]['id'],'Accounts', $seedData[0]['fieldName']));
  184. $this->assertFalse(self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[1]['id'],'Accounts', $seedData[1]['fieldName']));
  185. $this->assertEquals($seedData[2]['fieldValue'], self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[2]['id'],'Contacts', $seedData[2]['fieldName']));
  186. $this->assertEquals($seedData[3]['fieldValue'], self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[3]['id'],'Opportunities', $seedData[3]['fieldName']));
  187. $this->assertFalse(self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[4]['id'],'Opportunities', $seedData[4]['fieldName']));
  188. }
  189. public function testGetServerInformation()
  190. {
  191. require('sugar_version.php');
  192. $result = $this->_login();
  193. $session = $result['id'];
  194. $result = $this->_makeRESTCall('get_server_info',array());
  195. $this->assertEquals($sugar_version, $result['version'],'Unable to get server information');
  196. $this->assertEquals($sugar_flavor, $result['flavor'],'Unable to get server information');
  197. }
  198. public function testGetModuleList()
  199. {
  200. $account = new Account();
  201. $account->id = uniqid();
  202. $account->new_with_id = TRUE;
  203. $account->name = "Test " . $account->id;
  204. $account->save();
  205. $whereClause = "accounts.name='{$account->name}'";
  206. $module = 'Accounts';
  207. $orderBy = 'name';
  208. $offset = 0;
  209. $returnFields = array('name');
  210. $result = $this->_login(); // Logging in just before the REST call as this will also commit any pending DB changes
  211. $session = $result['id'];
  212. $result = $this->_makeRESTCall('get_entry_list', array($session, $module, $whereClause, $orderBy,$offset, $returnFields));
  213. $this->assertEquals($account->id, $result['entry_list'][0]['id'],'Unable to retrieve account list during search.');
  214. $GLOBALS['db']->query("DELETE FROM accounts WHERE id = '{$account->id}'");
  215. }
  216. public function testLogin()
  217. {
  218. $result = $this->_login();
  219. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  220. }
  221. public static function _multipleModuleLayoutProvider()
  222. {
  223. return array(
  224. array(
  225. 'module' => array('Accounts','Contacts'),
  226. 'type' => array('default'),
  227. 'view' => array('list'),
  228. 'expected_file' => array(
  229. 'Accounts' => array( 'default' => array('list' => 'modules/Accounts/metadata/listviewdefs.php')),
  230. 'Contacts' => array( 'default' => array('list' => 'modules/Contacts/metadata/listviewdefs.php')))
  231. ),
  232. array(
  233. 'module' => array('Accounts','Contacts'),
  234. 'type' => array('default'),
  235. 'view' => array('list','detail'),
  236. 'expected_file' => array(
  237. 'Accounts' => array(
  238. 'default' => array(
  239. 'list' => 'modules/Accounts/metadata/listviewdefs.php',
  240. 'detail' => 'modules/Accounts/metadata/detailviewdefs.php')),
  241. 'Contacts' => array(
  242. 'default' => array(
  243. 'list' => 'modules/Contacts/metadata/listviewdefs.php',
  244. 'detail' => 'modules/Contacts/metadata/detailviewdefs.php'))
  245. ))
  246. );
  247. }
  248. /**
  249. * @dataProvider _multipleModuleLayoutProvider
  250. */
  251. public function testGetMultipleModuleLayout($a_module, $a_type, $a_view, $a_expected_file)
  252. {
  253. $result = $this->_login();
  254. $session = $result['id'];
  255. $results = $this->_makeRESTCall('get_module_layout',
  256. array(
  257. 'session' => $session,
  258. 'module' => $a_module,
  259. 'type' => $a_type,
  260. 'view' => $a_view)
  261. );
  262. foreach ($results as $module => $moduleResults )
  263. {
  264. foreach ($moduleResults as $type => $viewResults)
  265. {
  266. foreach ($viewResults as $view => $result)
  267. {
  268. $expected_file = $a_expected_file[$module][$type][$view];
  269. if ( is_file('custom' . DIRECTORY_SEPARATOR . $expected_file) )
  270. require('custom' . DIRECTORY_SEPARATOR . $expected_file);
  271. else
  272. require($expected_file);
  273. if($view == 'list')
  274. $expectedResults = $listViewDefs[$module];
  275. else
  276. $expectedResults = $viewdefs[$module][ucfirst($view) .'View' ];
  277. $this->assertEquals(md5(serialize($expectedResults)), md5(serialize($result)), "Unable to retrieve module layout: module {$module}, type $type, view $view");
  278. }
  279. }
  280. }
  281. }
  282. public static function _moduleLayoutProvider()
  283. {
  284. return array(
  285. array('module' => 'Accounts','type' => 'default', 'view' => 'list','expected_file' => 'modules/Accounts/metadata/listviewdefs.php' ),
  286. array('module' => 'Accounts','type' => 'default', 'view' => 'edit','expected_file' => 'modules/Accounts/metadata/editviewdefs.php' ),
  287. array('module' => 'Accounts','type' => 'default', 'view' => 'detail','expected_file' => 'modules/Accounts/metadata/detailviewdefs.php' ),
  288. );
  289. }
  290. /**
  291. * @dataProvider _moduleLayoutProvider
  292. */
  293. public function testGetModuleLayout($module, $type, $view, $expected_file)
  294. {
  295. $result = $this->_login();
  296. $session = $result['id'];
  297. $result = $this->_makeRESTCall('get_module_layout',
  298. array(
  299. 'session' => $session,
  300. 'module' => array($module),
  301. 'type' => array($type),
  302. 'view' => array($view))
  303. );
  304. if ( is_file('custom' . DIRECTORY_SEPARATOR . $expected_file) )
  305. require('custom' . DIRECTORY_SEPARATOR . $expected_file);
  306. else
  307. require($expected_file);
  308. if($view == 'list')
  309. $expectedResults = $listViewDefs[$module];
  310. else
  311. $expectedResults = $viewdefs[$module][ucfirst($view) .'View' ];
  312. $a_expectedResults = array();
  313. $a_expectedResults[$module][$type][$view] = $expectedResults;
  314. $this->assertEquals(md5(serialize($a_expectedResults)), md5(serialize($result)), "Unable to retrieve module layout: module {$module}, type $type, view $view");
  315. }
  316. /**
  317. * @dataProvider _moduleLayoutProvider
  318. */
  319. public function testGetModuleLayoutMD5($module, $type, $view, $expected_file)
  320. {
  321. $result = $this->_login();
  322. $session = $result['id'];
  323. $fullResult = $this->_makeRESTCall('get_module_layout_md5',
  324. array(
  325. 'session' => $session,
  326. 'module' => array($module),
  327. 'type' => array($type),
  328. 'view' => array($view) )
  329. );
  330. $result = $fullResult['md5'];
  331. if ( is_file('custom' . DIRECTORY_SEPARATOR . $expected_file) )
  332. require('custom' . DIRECTORY_SEPARATOR . $expected_file);
  333. else
  334. require($expected_file);
  335. if($view == 'list')
  336. $expectedResults = $listViewDefs[$module];
  337. else
  338. $expectedResults = $viewdefs[$module][ucfirst($view) .'View' ];
  339. $a_expectedResults = array();
  340. $a_expectedResults[$module][$type][$view] = $expectedResults;
  341. $this->assertEquals(md5(serialize($expectedResults)), $result[$module][$type][$view], "Unable to retrieve module layout md5: module {$module}, type $type, view $view");
  342. }
  343. public function testGetAvailableModules()
  344. {
  345. $this->markTestIncomplete('Will be updated week of June 21, 2010');
  346. $result = $this->_login();
  347. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  348. $session = $result['id'];
  349. $fullResult = $this->_makeRESTCall('get_available_modules', array('session' => $session, 'filter' => 'all' ));
  350. $this->assertTrue(in_array('ACLFields', $fullResult['modules']), "Unable to get all available modules");
  351. $this->assertTrue(in_array('Schedulers', $fullResult['modules']), "Unable to get all available modules");
  352. $this->assertTrue(in_array('Roles', $fullResult['modules']), "Unable to get all available modules");
  353. $sh = new SugarWebServiceUtilv3();
  354. $mobileResult = $this->_makeRESTCall('get_available_modules', array('session' => $session, 'filter' => 'mobile' ));
  355. $mobileResultExpected = $sh->get_visible_mobile_modules($fullResult['modules']);
  356. $mobileResultExpected = md5(serialize(array('modules' => $mobileResultExpected)));
  357. $mobileResult = md5(serialize($mobileResult));
  358. $this->assertEquals($mobileResultExpected, $mobileResult, "Unable to get all visible mobile modules");
  359. $defaultResult = $this->_makeRESTCall('get_available_modules', array('session' => $session, 'filter' => 'default' ));
  360. $defaultResult = md5(serialize($defaultResult['modules']));
  361. $defaultResultExpected = $sh->get_visible_modules($fullResult['modules']);
  362. $defaultResultExpected = md5(serialize($defaultResultExpected));
  363. $this->assertEquals($defaultResultExpected, $defaultResult, "Unable to get all visible default modules");
  364. }
  365. public function testGetVardefsMD5()
  366. {
  367. $GLOBALS['reload_vardefs'] = TRUE;
  368. $result = $this->_login();
  369. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  370. $session = $result['id'];
  371. //Test a regular module
  372. $fullResult = $this->_makeRESTCall('get_module_fields_md5', array('session' => $session, 'module' => 'Currencies' ));
  373. $result = $fullResult['Currencies'];
  374. $a = new Currency();
  375. $soapHelper = new SugarWebServiceUtilv3();
  376. $actualVardef = $soapHelper->get_return_module_fields($a,'Currencies','');
  377. $actualMD5 = md5(serialize($actualVardef));
  378. $this->assertEquals($actualMD5, $result, "Unable to retrieve vardef md5.");
  379. //Test a fake module
  380. $result = $this->_makeRESTCall('get_module_fields_md5', array('session' => $session, 'module' => 'BadModule' ));
  381. $this->assertEquals('Module Does Not Exist', $result['name']);
  382. unset($GLOBALS['reload_vardefs']);
  383. }
  384. public function testAddNewAccountAndThenDeleteIt()
  385. {
  386. $result = $this->_login();
  387. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  388. $session = $result['id'];
  389. $result = $this->_makeRESTCall('set_entry',
  390. array(
  391. 'session' => $session,
  392. 'module' => 'Accounts',
  393. 'name_value_list' => array(
  394. array('name' => 'name', 'value' => 'New Account'),
  395. array('name' => 'description', 'value' => 'This is an account created from a REST web services call'),
  396. ),
  397. )
  398. );
  399. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  400. $accountId = $result['id'];
  401. // verify record was created
  402. $result = $this->_makeRESTCall('get_entry',
  403. array(
  404. 'session' => $session,
  405. 'module' => 'Accounts',
  406. 'id' => $accountId,
  407. )
  408. );
  409. $this->assertEquals($result['entry_list'][0]['id'],$accountId,$this->_returnLastRawResponse());
  410. // delete the record
  411. $result = $this->_makeRESTCall('set_entry',
  412. array(
  413. 'session' => $session,
  414. 'module' => 'Accounts',
  415. 'name_value_list' => array(
  416. array('name' => 'id', 'value' => $accountId),
  417. array('name' => 'deleted', 'value' => '1'),
  418. ),
  419. )
  420. );
  421. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  422. // try to retrieve again to validate it is deleted
  423. $result = $this->_makeRESTCall('get_entry',
  424. array(
  425. 'session' => $session,
  426. 'module' => 'Accounts',
  427. 'id' => $accountId,
  428. )
  429. );
  430. $GLOBALS['db']->query("DELETE FROM accounts WHERE id= '{$accountId}'");
  431. $this->assertTrue(!empty($result['entry_list'][0]['id']) && $result['entry_list'][0]['id'] != -1,$this->_returnLastRawResponse());
  432. $this->assertEquals($result['entry_list'][0]['name_value_list'][0]['name'],'warning',$this->_returnLastRawResponse());
  433. $this->assertEquals($result['entry_list'][0]['name_value_list'][0]['value'],"Access to this object is denied since it has been deleted or does not exist",$this->_returnLastRawResponse());
  434. $this->assertEquals($result['entry_list'][0]['name_value_list'][1]['name'],'deleted',$this->_returnLastRawResponse());
  435. $this->assertEquals($result['entry_list'][0]['name_value_list'][1]['value'],1,$this->_returnLastRawResponse());
  436. }
  437. public function testRelateAccountToTwoContacts()
  438. {
  439. $result = $this->_login();
  440. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  441. $session = $result['id'];
  442. $result = $this->_makeRESTCall('set_entry',
  443. array(
  444. 'session' => $session,
  445. 'module' => 'Accounts',
  446. 'name_value_list' => array(
  447. array('name' => 'name', 'value' => 'New Account'),
  448. array('name' => 'description', 'value' => 'This is an account created from a REST web services call'),
  449. ),
  450. )
  451. );
  452. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  453. $accountId = $result['id'];
  454. $result = $this->_makeRESTCall('set_entry',
  455. array(
  456. 'session' => $session,
  457. 'module' => 'Contacts',
  458. 'name_value_list' => array(
  459. array('name' => 'last_name', 'value' => 'New Contact 1'),
  460. array('name' => 'description', 'value' => 'This is a contact created from a REST web services call'),
  461. ),
  462. )
  463. );
  464. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  465. $contactId1 = $result['id'];
  466. $result = $this->_makeRESTCall('set_entry',
  467. array(
  468. 'session' => $session,
  469. 'module' => 'Contacts',
  470. 'name_value_list' => array(
  471. array('name' => 'last_name', 'value' => 'New Contact 2'),
  472. array('name' => 'description', 'value' => 'This is a contact created from a REST web services call'),
  473. ),
  474. )
  475. );
  476. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  477. $contactId2 = $result['id'];
  478. // now relate them together
  479. $result = $this->_makeRESTCall('set_relationship',
  480. array(
  481. 'session' => $session,
  482. 'module' => 'Accounts',
  483. 'module_id' => $accountId,
  484. 'link_field_name' => 'contacts',
  485. 'related_ids' => array($contactId1,$contactId2),
  486. )
  487. );
  488. $this->assertEquals($result['created'],1,$this->_returnLastRawResponse());
  489. // check the relationship
  490. $result = $this->_makeRESTCall('get_relationships',
  491. array(
  492. 'session' => $session,
  493. 'module' => 'Accounts',
  494. 'module_id' => $accountId,
  495. 'link_field_name' => 'contacts',
  496. 'related_module_query' => '',
  497. 'related_fields' => array('last_name','description'),
  498. 'related_module_link_name_to_fields_array' => array(),
  499. 'deleted' => false,
  500. )
  501. );
  502. $returnedValues = array();
  503. $returnedValues[] = $result['entry_list'][0]['name_value_list']['last_name']['value'];
  504. $returnedValues[] = $result['entry_list'][1]['name_value_list']['last_name']['value'];
  505. $GLOBALS['db']->query("DELETE FROM accounts WHERE id= '{$accountId}'");
  506. $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId1}'");
  507. $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId2}'");
  508. $GLOBALS['db']->query("DELETE FROM accounts_contacts WHERE account_id= '{$accountId}'");
  509. $this->assertContains('New Contact 1',$returnedValues,$this->_returnLastRawResponse());
  510. $this->assertContains('New Contact 2',$returnedValues,$this->_returnLastRawResponse());
  511. }
  512. /**
  513. * @ticket 36658
  514. */
  515. public function testOrderByClauseOfGetRelationship()
  516. {
  517. $result = $this->_login();
  518. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  519. $session = $result['id'];
  520. $result = $this->_makeRESTCall('set_entry',
  521. array(
  522. 'session' => $session,
  523. 'module' => 'Accounts',
  524. 'name_value_list' => array(
  525. array('name' => 'name', 'value' => 'New Account'),
  526. array('name' => 'description', 'value' => 'This is an account created from a REST web services call'),
  527. ),
  528. )
  529. );
  530. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  531. $accountId = $result['id'];
  532. $result = $this->_makeRESTCall('set_entry',
  533. array(
  534. 'session' => $session,
  535. 'module' => 'Contacts',
  536. 'name_value_list' => array(
  537. array('name' => 'last_name', 'value' => 'New Contact 1'),
  538. array('name' => 'description', 'value' => 'This is a contact created from a REST web services call'),
  539. ),
  540. )
  541. );
  542. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  543. $contactId1 = $result['id'];
  544. $result = $this->_makeRESTCall('set_entry',
  545. array(
  546. 'session' => $session,
  547. 'module' => 'Contacts',
  548. 'name_value_list' => array(
  549. array('name' => 'last_name', 'value' => 'New Contact 3'),
  550. array('name' => 'description', 'value' => 'This is a contact created from a REST web services call'),
  551. ),
  552. )
  553. );
  554. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  555. $contactId3 = $result['id'];
  556. $result = $this->_makeRESTCall('set_entry',
  557. array(
  558. 'session' => $session,
  559. 'module' => 'Contacts',
  560. 'name_value_list' => array(
  561. array('name' => 'last_name', 'value' => 'New Contact 2'),
  562. array('name' => 'description', 'value' => 'This is a contact created from a REST web services call'),
  563. ),
  564. )
  565. );
  566. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  567. $contactId2 = $result['id'];
  568. // now relate them together
  569. $result = $this->_makeRESTCall('set_relationship',
  570. array(
  571. 'session' => $session,
  572. 'module' => 'Accounts',
  573. 'module_id' => $accountId,
  574. 'link_field_name' => 'contacts',
  575. 'related_ids' => array($contactId1,$contactId3,$contactId2),
  576. )
  577. );
  578. $this->assertEquals($result['created'],1,$this->_returnLastRawResponse());
  579. // check the relationship
  580. $result = $this->_makeRESTCall('get_relationships',
  581. array(
  582. 'session' => $session,
  583. 'module' => 'Accounts',
  584. 'module_id' => $accountId,
  585. 'link_field_name' => 'contacts',
  586. 'related_module_query' => '',
  587. 'related_fields' => array('last_name','description'),
  588. 'related_module_link_name_to_fields_array' => array(),
  589. 'deleted' => false,
  590. 'order_by' => 'last_name',
  591. )
  592. );
  593. $GLOBALS['db']->query("DELETE FROM accounts WHERE id= '{$accountId}'");
  594. $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId1}'");
  595. $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId2}'");
  596. $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId3}'");
  597. $GLOBALS['db']->query("DELETE FROM accounts_contacts WHERE account_id= '{$accountId}'");
  598. $this->assertEquals($result['entry_list'][0]['name_value_list']['last_name']['value'],'New Contact 1',$this->_returnLastRawResponse());
  599. $this->assertEquals($result['entry_list'][1]['name_value_list']['last_name']['value'],'New Contact 2',$this->_returnLastRawResponse());
  600. $this->assertEquals($result['entry_list'][2]['name_value_list']['last_name']['value'],'New Contact 3',$this->_returnLastRawResponse());
  601. }
  602. public static function _subpanelLayoutProvider()
  603. {
  604. return array(
  605. array(
  606. 'module' => 'Contacts',
  607. 'type' => 'default',
  608. 'view' => 'subpanel',
  609. ),
  610. array(
  611. 'module' => 'Leads',
  612. 'type' => 'wireless',
  613. 'view' => 'subpanel',
  614. ),
  615. );
  616. }
  617. /**
  618. * @dataProvider _subpanelLayoutProvider
  619. */
  620. public function testGetSubpanelLayout($module, $type, $view)
  621. {
  622. $result = $this->_login();
  623. $session = $result['id'];
  624. $results = $this->_makeRESTCall('get_module_layout',
  625. array(
  626. 'session' => $session,
  627. 'module' => array($module),
  628. 'type' => array($type),
  629. 'view' => array($view))
  630. );
  631. $this->assertTrue(isset($results[$module][$type][$view]), "Unable to get subpanel defs");
  632. }
  633. public function testGetUpcomingActivities()
  634. {
  635. $expected = $this->_createUpcomingActivities(); //Seed the data.
  636. $result = $this->_login(); // Logging in just before the REST call as this will also commit any pending DB changes
  637. $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
  638. $session = $result['id'];
  639. $results = $this->_makeRESTCall('get_upcoming_activities',
  640. array(
  641. 'session' => $session,
  642. )
  643. );
  644. $ids = array();
  645. foreach($results as $activity)
  646. {
  647. $ids[$activity['id']] = $activity['id'];
  648. }
  649. $this->assertArrayHasKey($expected[0] , $ids , "Unable to get upcoming activities");
  650. $this->assertArrayHasKey($expected[1] ,$ids , "Unable to get upcoming activities");
  651. $this->_removeUpcomingActivities();
  652. }
  653. private function _removeUpcomingActivities()
  654. {
  655. $GLOBALS['db']->query("DELETE FROM calls where name = 'UNIT TEST'");
  656. $GLOBALS['db']->query("DELETE FROM tasks where name = 'UNIT TEST'");
  657. }
  658. private function _createUpcomingActivities()
  659. {
  660. $GLOBALS['current_user']->setPreference('datef','Y-m-d') ;
  661. $GLOBALS['current_user']->setPreference('timef','H:i') ;
  662. $date1 = $GLOBALS['timedate']->to_display_date_time(gmdate("Y-m-d H:i:s", (gmmktime() + (3600 * 24 * 2) ) ),true,true, $GLOBALS['current_user']) ; //Two days from today
  663. $date2 = $GLOBALS['timedate']->to_display_date_time(gmdate("Y-m-d H:i:s", (gmmktime() + (3600 * 24 * 4) ) ),true,true, $GLOBALS['current_user']) ; //Two days from today
  664. $callID = uniqid();
  665. $c = new Call();
  666. $c->id = $callID;
  667. $c->new_with_id = TRUE;
  668. $c->status = 'Not Planned';
  669. $c->date_start = $date1;
  670. $c->name = "UNIT TEST";
  671. $c->assigned_user_id = $this->_user->id;
  672. $c->save(FALSE);
  673. $callID = uniqid();
  674. $c = new Call();
  675. $c->id = $callID;
  676. $c->new_with_id = TRUE;
  677. $c->status = 'Planned';
  678. $c->date_start = $date1;
  679. $c->name = "UNIT TEST";
  680. $c->assigned_user_id = $this->_user->id;
  681. $c->save(FALSE);
  682. $taskID = uniqid();
  683. $t = new Task();
  684. $t->id = $taskID;
  685. $t->new_with_id = TRUE;
  686. $t->status = 'Not Started';
  687. $t->date_due = $date2;
  688. $t->name = "UNIT TEST";
  689. $t->assigned_user_id = $this->_user->id;
  690. $t->save(FALSE);
  691. return array($callID, $taskID);
  692. }
  693. }