PageRenderTime 244ms CodeModel.GetById 83ms app.highlight 110ms RepoModel.GetById 41ms 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
  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
 37
 38require_once('service/v3/SugarWebServiceUtilv3.php');
 39require_once('tests/service/APIv3Helper.php');
 40
 41
 42class RESTAPI3Test extends Sugar_PHPUnit_Framework_TestCase
 43{
 44    protected $_user;
 45
 46    protected $_lastRawResponse;
 47
 48    private static $helperObject;
 49
 50    private $_unified_search_modules_content;
 51
 52    public function setUp()
 53    {
 54        global $beanList, $beanFiles;
 55        include('include/modules.php');
 56
 57        //Reload langauge strings
 58        $GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
 59        $GLOBALS['app_list_strings'] = return_app_list_strings_language($GLOBALS['current_language']);
 60        $GLOBALS['mod_strings'] = return_module_language($GLOBALS['current_language'], 'Accounts');
 61        //Create an anonymous user for login purposes/
 62        $this->_user = SugarTestUserUtilities::createAnonymousUser();
 63        $GLOBALS['current_user'] = $this->_user;
 64
 65        self::$helperObject = new APIv3Helper();
 66
 67        if(file_exists(sugar_cached('modules/unified_search_modules.php')))
 68        {
 69            $this->unified_search_modules_content = file_get_contents(sugar_cached('modules/unified_search_modules.php'));
 70            unlink(sugar_cached('modules/unified_search_modules.php'));
 71        }
 72
 73        require_once('modules/Home/UnifiedSearchAdvanced.php');
 74        $unifiedSearchAdvanced = new UnifiedSearchAdvanced();
 75        $_REQUEST['enabled_modules'] = 'Accounts,Contacts,Opportunities';
 76        $unifiedSearchAdvanced->saveGlobalSearchSettings();
 77
 78        $GLOBALS['db']->query("DELETE FROM accounts WHERE name like 'UNIT TEST%' ");
 79        $GLOBALS['db']->query("DELETE FROM opportunities WHERE name like 'UNIT TEST%' ");
 80        $GLOBALS['db']->query("DELETE FROM contacts WHERE first_name like 'UNIT TEST%' ");
 81        $GLOBALS['db']->query("DELETE FROM calls WHERE name like 'UNIT TEST%' ");
 82        $GLOBALS['db']->query("DELETE FROM tasks WHERE name like 'UNIT TEST%' ");
 83        $GLOBALS['db']->query("DELETE FROM meetings WHERE name like 'UNIT TEST%' ");
 84        $GLOBALS['db']->commit();
 85        //$this->useOutputBuffering = false;
 86    }
 87
 88    public function tearDown()
 89	{
 90	    if(isset($GLOBALS['listViewDefs'])) unset($GLOBALS['listViewDefs']);
 91	    if(isset($GLOBALS['viewdefs'])) unset($GLOBALS['viewdefs']);
 92	    unset($GLOBALS['app_list_strings']);
 93	    unset($GLOBALS['app_strings']);
 94	    unset($GLOBALS['mod_strings']);
 95
 96        if(!empty($this->unified_search_modules_content))
 97        {
 98            file_put_contents(sugar_cached('modules/unified_search_modules.php'), $this->unified_search_modules_content);
 99        }
100
101        $GLOBALS['db']->query("DELETE FROM accounts WHERE name like 'UNIT TEST%' ");
102        $GLOBALS['db']->query("DELETE FROM opportunities WHERE name like 'UNIT TEST%' ");
103        $GLOBALS['db']->query("DELETE FROM contacts WHERE first_name like 'UNIT TEST%' ");
104        $GLOBALS['db']->query("DELETE FROM calls WHERE name like 'UNIT TEST%' ");
105        $GLOBALS['db']->query("DELETE FROM tasks WHERE name like 'UNIT TEST%' ");
106        $GLOBALS['db']->query("DELETE FROM meetings WHERE name like 'UNIT TEST%' ");
107        SugarTestUserUtilities::removeAllCreatedAnonymousUsers();
108	}
109
110    protected function _makeRESTCall($method,$parameters)
111    {
112        // specify the REST web service to interact with
113        $url = $GLOBALS['sugar_config']['site_url'].'/service/v3/rest.php';
114        // Open a curl session for making the call
115        $curl = curl_init($url);
116        // set URL and other appropriate options
117        curl_setopt($curl, CURLOPT_URL, $url);
118        curl_setopt($curl, CURLOPT_POST, 1);
119        curl_setopt($curl, CURLOPT_HEADER, 0);
120        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
121        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
122        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 0);
123        curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 );
124        // build the request URL
125        $json = json_encode($parameters);
126        $postArgs = "method=$method&input_type=JSON&response_type=JSON&rest_data=$json";
127        curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);
128        // Make the REST call, returning the result
129        $response = curl_exec($curl);
130        // Close the connection
131        curl_close($curl);
132
133        $this->_lastRawResponse = $response;
134
135        // Convert the result from JSON format to a PHP array
136        return json_decode($response,true);
137    }
138
139    protected function _returnLastRawResponse()
140    {
141        return "Error in web services call. Response was: {$this->_lastRawResponse}";
142    }
143
144    protected function _login()
145    {
146        $GLOBALS['db']->commit(); // Making sure we commit any changes before logging in
147
148        return $this->_makeRESTCall('login',
149            array(
150                'user_auth' =>
151                    array(
152                        'user_name' => $this->_user->user_name,
153                        'password' => $this->_user->user_hash,
154                        'version' => '.01',
155                        ),
156                'application_name' => 'SugarTestRunner',
157                'name_value_list' => array(),
158                )
159            );
160    }
161
162    public function testSearchByModule()
163    {
164        $seedData = self::$helperObject->populateSeedDataForSearchTest($this->_user->id);
165
166        $searchModules = array('Accounts','Contacts','Opportunities');
167        $searchString = "UNIT TEST";
168        $offSet = 0;
169        $maxResults = 10;
170
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                        );
182
183        $this->assertTrue( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[0]['id'],'Accounts') );
184        $this->assertFalse( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[1]['id'],'Accounts') );
185        $this->assertTrue( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[2]['id'],'Contacts') );
186        $this->assertTrue( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[3]['id'],'Opportunities') );
187        $this->assertFalse( self::$helperObject->findBeanIdFromEntryList($results['entry_list'],$seedData[4]['id'],'Opportunities') );
188    }
189
190    public function testSearchByModuleWithReturnFields()
191    {
192        $seedData = self::$helperObject->populateSeedDataForSearchTest($this->_user->id);
193
194        $returnFields = array('name','id','deleted');
195        $searchModules = array('Accounts','Contacts','Opportunities');
196        $searchString = "UNIT TEST";
197        $offSet = 0;
198        $maxResults = 10;
199
200        $result = $this->_login(); // Logging in just before the REST call as this will also commit any pending DB changes
201        $session = $result['id'];
202        $results = $this->_makeRESTCall('search_by_module',
203                        array(
204                            'session' => $session,
205                            'search'  => $searchString,
206                            'modules' => $searchModules,
207                            'offset'  => $offSet,
208                            'max'     => $maxResults,
209                            'user'    => $this->_user->id,
210                            'selectFields' => $returnFields)
211                        );
212
213
214        $this->assertEquals($seedData[0]['fieldValue'], self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[0]['id'],'Accounts', $seedData[0]['fieldName']));
215        $this->assertFalse(self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[1]['id'],'Accounts', $seedData[1]['fieldName']));
216        $this->assertEquals($seedData[2]['fieldValue'], self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[2]['id'],'Contacts', $seedData[2]['fieldName']));
217        $this->assertEquals($seedData[3]['fieldValue'], self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[3]['id'],'Opportunities', $seedData[3]['fieldName']));
218        $this->assertFalse(self::$helperObject->findFieldByNameFromEntryList($results['entry_list'],$seedData[4]['id'],'Opportunities', $seedData[4]['fieldName']));
219    }
220
221    public function testGetServerInformation()
222    {
223        require('sugar_version.php');
224
225        $result = $this->_login();
226        $session = $result['id'];
227
228        $result = $this->_makeRESTCall('get_server_info',array());
229
230        $this->assertEquals($sugar_version, $result['version'],'Unable to get server information');
231        $this->assertEquals($sugar_flavor, $result['flavor'],'Unable to get server information');
232    }
233
234    public function testGetModuleList()
235    {
236        $account = new Account();
237        $account->id = uniqid();
238        $account->new_with_id = TRUE;
239        $account->name = "Test " . $account->id;
240        $account->save();
241
242        $whereClause = "accounts.name='{$account->name}'";
243        $module = 'Accounts';
244        $orderBy = 'name';
245        $offset = 0;
246        $returnFields = array('name');
247
248        $result = $this->_login(); // Logging in just before the REST call as this will also commit any pending DB changes
249        $session = $result['id'];
250        $result = $this->_makeRESTCall('get_entry_list', array($session, $module, $whereClause, $orderBy,$offset, $returnFields));
251
252        $this->assertEquals($account->id, $result['entry_list'][0]['id'],'Unable to retrieve account list during search.');
253
254        $GLOBALS['db']->query("DELETE FROM accounts WHERE id = '{$account->id}'");
255
256    }
257
258    public function testLogin()
259    {
260        $result = $this->_login();
261        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
262    }
263
264    public static function _multipleModuleLayoutProvider()
265    {
266        return array(
267                        array(
268                            'module' => array('Accounts','Contacts'),
269                            'type' => array('default'),
270                            'view' => array('list'),
271                            'expected_file' => array(
272                                'Accounts' => array( 'default' => array('list' => 'modules/Accounts/metadata/listviewdefs.php')),
273                                'Contacts' => array( 'default' => array('list' => 'modules/Contacts/metadata/listviewdefs.php')))
274                        ),
275                        array(
276                            'module' => array('Accounts','Contacts'),
277                            'type' => array('default'),
278                            'view' => array('list','detail'),
279                            'expected_file' => array(
280                                'Accounts' => array(
281                                    'default' => array(
282                                                'list' => 'modules/Accounts/metadata/listviewdefs.php',
283                                                'detail' => 'modules/Accounts/metadata/detailviewdefs.php')),
284                                'Contacts' => array(
285                                    'default' => array(
286                                                'list' => 'modules/Contacts/metadata/listviewdefs.php',
287                                                'detail' => 'modules/Contacts/metadata/detailviewdefs.php'))
288                        ))
289        );
290    }
291
292    /**
293     * @dataProvider _multipleModuleLayoutProvider
294     */
295    public function testGetMultipleModuleLayout($a_module, $a_type, $a_view, $a_expected_file)
296    {
297        $result = $this->_login();
298        $session = $result['id'];
299
300        $results = $this->_makeRESTCall('get_module_layout',
301                        array(
302                            'session' => $session,
303                            'module' => $a_module,
304                            'type' => $a_type,
305                            'view' => $a_view)
306                        );
307
308        foreach ($results as $module => $moduleResults )
309        {
310            foreach ($moduleResults as $type => $viewResults)
311            {
312                foreach ($viewResults as $view => $result)
313                {
314                    $expected_file = $a_expected_file[$module][$type][$view];
315                    if ( is_file('custom'  . DIRECTORY_SEPARATOR . $expected_file) )
316                    	require('custom'  . DIRECTORY_SEPARATOR . $expected_file);
317                    else
318                        require($expected_file);
319
320                    if($view == 'list')
321                        $expectedResults = $listViewDefs[$module];
322                    else
323                        $expectedResults = $viewdefs[$module][ucfirst($view) .'View' ];
324
325                    $this->assertEquals(md5(serialize($expectedResults)), md5(serialize($result)), "Unable to retrieve module layout: module {$module}, type $type, view $view");
326                }
327                }
328        }
329   }
330
331    public static function _moduleLayoutProvider()
332    {
333        return array(
334                    array('module' => 'Accounts','type' => 'default', 'view' => 'list','expected_file' => 'modules/Accounts/metadata/listviewdefs.php' ),
335                    array('module' => 'Accounts','type' => 'default', 'view' => 'edit','expected_file' => 'modules/Accounts/metadata/editviewdefs.php' ),
336                    array('module' => 'Accounts','type' => 'default', 'view' => 'detail','expected_file' => 'modules/Accounts/metadata/detailviewdefs.php' ),
337        );
338    }
339
340    /**
341     * @dataProvider _moduleLayoutProvider
342     */
343    public function testGetModuleLayout($module, $type, $view, $expected_file)
344    {
345        $result = $this->_login();
346        $session = $result['id'];
347
348        $result = $this->_makeRESTCall('get_module_layout',
349                        array(
350                            'session' => $session,
351                            'module' => array($module),
352                            'type' => array($type),
353                            'view' => array($view))
354                        );
355
356        if ( is_file('custom'  . DIRECTORY_SEPARATOR . $expected_file) )
357        	require('custom'  . DIRECTORY_SEPARATOR . $expected_file);
358        else
359            require($expected_file);
360
361        if($view == 'list')
362            $expectedResults = $listViewDefs[$module];
363        else
364            $expectedResults = $viewdefs[$module][ucfirst($view) .'View' ];
365
366        $a_expectedResults = array();
367        $a_expectedResults[$module][$type][$view] = $expectedResults;
368
369        $this->assertEquals(md5(serialize($a_expectedResults)), md5(serialize($result)), "Unable to retrieve module layout: module {$module}, type $type, view $view");
370    }
371
372     /**
373     * @dataProvider _moduleLayoutProvider
374     */
375    public function testGetModuleLayoutMD5($module, $type, $view, $expected_file)
376    {
377        $result = $this->_login();
378        $session = $result['id'];
379
380        $fullResult = $this->_makeRESTCall('get_module_layout_md5',
381                        array(
382                            'session' => $session,
383                            'module' => array($module),
384                            'type' => array($type),
385                            'view' => array($view) )
386                        );
387        $result = $fullResult['md5'];
388        if ( is_file('custom'  . DIRECTORY_SEPARATOR . $expected_file) )
389        	require('custom'  . DIRECTORY_SEPARATOR . $expected_file);
390        else
391            require($expected_file);
392
393        if($view == 'list')
394            $expectedResults = $listViewDefs[$module];
395        else
396            $expectedResults = $viewdefs[$module][ucfirst($view) .'View' ];
397
398        $a_expectedResults = array();
399        $a_expectedResults[$module][$type][$view] = $expectedResults;
400
401        $this->assertEquals(md5(serialize($expectedResults)), $result[$module][$type][$view], "Unable to retrieve module layout md5: module {$module}, type $type, view $view");
402
403    }
404
405    public function testGetAvailableModules()
406    {
407        $this->markTestIncomplete('Will be updated week of June 21, 2010');
408
409        $result = $this->_login();
410        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
411        $session = $result['id'];
412
413        $fullResult = $this->_makeRESTCall('get_available_modules', array('session' => $session, 'filter' => 'all' ));
414        $this->assertTrue(in_array('ACLFields', $fullResult['modules']), "Unable to get all available modules");
415        $this->assertTrue(in_array('Schedulers', $fullResult['modules']), "Unable to get all available modules");
416        $this->assertTrue(in_array('Roles', $fullResult['modules']), "Unable to get all available modules");
417
418        $sh = new SugarWebServiceUtilv3();
419
420        $mobileResult = $this->_makeRESTCall('get_available_modules', array('session' => $session, 'filter' => 'mobile' ));
421        $mobileResultExpected = $sh->get_visible_mobile_modules($fullResult['modules']);
422        $mobileResultExpected = md5(serialize(array('modules' => $mobileResultExpected)));
423        $mobileResult = md5(serialize($mobileResult));
424        $this->assertEquals($mobileResultExpected, $mobileResult, "Unable to get all visible mobile modules");
425
426        $defaultResult = $this->_makeRESTCall('get_available_modules', array('session' => $session, 'filter' => 'default' ));
427        $defaultResult = md5(serialize($defaultResult['modules']));
428        $defaultResultExpected = $sh->get_visible_modules($fullResult['modules']);
429        $defaultResultExpected = md5(serialize($defaultResultExpected));
430        $this->assertEquals($defaultResultExpected, $defaultResult, "Unable to get all visible default modules");
431
432    }
433
434    public function testGetVardefsMD5()
435    {
436        $GLOBALS['reload_vardefs'] = TRUE;
437        $result = $this->_login();
438        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
439        $session = $result['id'];
440
441        //Test a regular module
442        $fullResult = $this->_makeRESTCall('get_module_fields_md5', array('session' => $session, 'module' => 'Currencies' ));
443        $result = $fullResult['Currencies'];
444        $a = new Currency();
445        $soapHelper = new SugarWebServiceUtilv3();
446        $actualVardef = $soapHelper->get_return_module_fields($a,'Currencies','');
447        $actualMD5 = md5(serialize($actualVardef));
448        $this->assertEquals($actualMD5, $result, "Unable to retrieve vardef md5.");
449
450        //Test a fake module
451        $result = $this->_makeRESTCall('get_module_fields_md5', array('session' => $session, 'module' => 'BadModule' ));
452        $this->assertEquals('Module Does Not Exist', $result['name']);
453        unset($GLOBALS['reload_vardefs']);
454    }
455
456    public function testAddNewAccountAndThenDeleteIt()
457    {
458        $result = $this->_login();
459        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
460        $session = $result['id'];
461
462        $result = $this->_makeRESTCall('set_entry',
463            array(
464                'session' => $session,
465                'module' => 'Accounts',
466                'name_value_list' => array(
467                    array('name' => 'name', 'value' => 'New Account'),
468                    array('name' => 'description', 'value' => 'This is an account created from a REST web services call'),
469                    ),
470                )
471            );
472
473        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
474
475        $accountId = $result['id'];
476
477        // verify record was created
478        $result = $this->_makeRESTCall('get_entry',
479            array(
480                'session' => $session,
481                'module' => 'Accounts',
482                'id' => $accountId,
483                )
484            );
485
486        $this->assertEquals($result['entry_list'][0]['id'],$accountId,$this->_returnLastRawResponse());
487
488        // delete the record
489        $result = $this->_makeRESTCall('set_entry',
490            array(
491                'session' => $session,
492                'module' => 'Accounts',
493                'name_value_list' => array(
494                    array('name' => 'id', 'value' => $accountId),
495                    array('name' => 'deleted', 'value' => '1'),
496                    ),
497                )
498            );
499
500        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
501
502        // try to retrieve again to validate it is deleted
503        $result = $this->_makeRESTCall('get_entry',
504            array(
505                'session' => $session,
506                'module' => 'Accounts',
507                'id' => $accountId,
508                )
509            );
510
511        $GLOBALS['db']->query("DELETE FROM accounts WHERE id= '{$accountId}'");
512
513        $this->assertTrue(!empty($result['entry_list'][0]['id']) && $result['entry_list'][0]['id'] != -1,$this->_returnLastRawResponse());
514        $this->assertEquals($result['entry_list'][0]['name_value_list'][0]['name'],'warning',$this->_returnLastRawResponse());
515        $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());
516        $this->assertEquals($result['entry_list'][0]['name_value_list'][1]['name'],'deleted',$this->_returnLastRawResponse());
517        $this->assertEquals($result['entry_list'][0]['name_value_list'][1]['value'],1,$this->_returnLastRawResponse());
518    }
519
520    public function testRelateAccountToTwoContacts()
521    {
522        $result = $this->_login();
523        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
524        $session = $result['id'];
525
526        $result = $this->_makeRESTCall('set_entry',
527            array(
528                'session' => $session,
529                'module' => 'Accounts',
530                'name_value_list' => array(
531                    array('name' => 'name', 'value' => 'New Account'),
532                    array('name' => 'description', 'value' => 'This is an account created from a REST web services call'),
533                    ),
534                )
535            );
536
537        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
538
539        $accountId = $result['id'];
540
541        $result = $this->_makeRESTCall('set_entry',
542            array(
543                'session' => $session,
544                'module' => 'Contacts',
545                'name_value_list' => array(
546                    array('name' => 'last_name', 'value' => 'New Contact 1'),
547                    array('name' => 'description', 'value' => 'This is a contact created from a REST web services call'),
548                    ),
549                )
550            );
551
552        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
553
554        $contactId1 = $result['id'];
555
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
567        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
568
569        $contactId2 = $result['id'];
570
571        // now relate them together
572        $result = $this->_makeRESTCall('set_relationship',
573            array(
574                'session' => $session,
575                'module' => 'Accounts',
576                'module_id' => $accountId,
577                'link_field_name' => 'contacts',
578                'related_ids' => array($contactId1,$contactId2),
579                )
580            );
581
582        $this->assertEquals($result['created'],1,$this->_returnLastRawResponse());
583
584        // check the relationship
585        $result = $this->_makeRESTCall('get_relationships',
586            array(
587                'session' => $session,
588                'module' => 'Accounts',
589                'module_id' => $accountId,
590                'link_field_name' => 'contacts',
591                'related_module_query' => '',
592                'related_fields' => array('last_name','description'),
593                'related_module_link_name_to_fields_array' => array(),
594                'deleted' => false,
595                )
596            );
597
598        $returnedValues = array();
599        $returnedValues[] = $result['entry_list'][0]['name_value_list']['last_name']['value'];
600        $returnedValues[] = $result['entry_list'][1]['name_value_list']['last_name']['value'];
601
602        $GLOBALS['db']->query("DELETE FROM accounts WHERE id= '{$accountId}'");
603        $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId1}'");
604        $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId2}'");
605        $GLOBALS['db']->query("DELETE FROM accounts_contacts WHERE account_id= '{$accountId}'");
606
607        $this->assertContains('New Contact 1',$returnedValues,$this->_returnLastRawResponse());
608        $this->assertContains('New Contact 2',$returnedValues,$this->_returnLastRawResponse());
609    }
610
611    /**
612     * @ticket 36658
613     */
614    public function testOrderByClauseOfGetRelationship()
615    {
616        $result = $this->_login();
617        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
618        $session = $result['id'];
619
620        $result = $this->_makeRESTCall('set_entry',
621            array(
622                'session' => $session,
623                'module' => 'Accounts',
624                'name_value_list' => array(
625                    array('name' => 'name', 'value' => 'New Account'),
626                    array('name' => 'description', 'value' => 'This is an account created from a REST web services call'),
627                    ),
628                )
629            );
630
631        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
632
633        $accountId = $result['id'];
634
635        $result = $this->_makeRESTCall('set_entry',
636            array(
637                'session' => $session,
638                'module' => 'Contacts',
639                'name_value_list' => array(
640                    array('name' => 'last_name', 'value' => 'New Contact 1'),
641                    array('name' => 'description', 'value' => 'This is a contact created from a REST web services call'),
642                    ),
643                )
644            );
645
646        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
647
648        $contactId1 = $result['id'];
649
650        $result = $this->_makeRESTCall('set_entry',
651            array(
652                'session' => $session,
653                'module' => 'Contacts',
654                'name_value_list' => array(
655                    array('name' => 'last_name', 'value' => 'New Contact 3'),
656                    array('name' => 'description', 'value' => 'This is a contact created from a REST web services call'),
657                    ),
658                )
659            );
660
661        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
662        $contactId3 = $result['id'];
663
664        $result = $this->_makeRESTCall('set_entry',
665            array(
666                'session' => $session,
667                'module' => 'Contacts',
668                'name_value_list' => array(
669                    array('name' => 'last_name', 'value' => 'New Contact 2'),
670                    array('name' => 'description', 'value' => 'This is a contact created from a REST web services call'),
671                    ),
672                )
673            );
674
675        $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
676
677        $contactId2 = $result['id'];
678
679        // now relate them together
680        $result = $this->_makeRESTCall('set_relationship',
681            array(
682                'session' => $session,
683                'module' => 'Accounts',
684                'module_id' => $accountId,
685                'link_field_name' => 'contacts',
686                'related_ids' => array($contactId1,$contactId3,$contactId2),
687                )
688            );
689
690        $this->assertEquals($result['created'],1,$this->_returnLastRawResponse());
691
692        // check the relationship
693        $result = $this->_makeRESTCall('get_relationships',
694            array(
695                'session' => $session,
696                'module' => 'Accounts',
697                'module_id' => $accountId,
698                'link_field_name' => 'contacts',
699                'related_module_query' => '',
700                'related_fields' => array('last_name','description'),
701                'related_module_link_name_to_fields_array' => array(),
702                'deleted' => false,
703                'order_by' => 'last_name',
704                )
705            );
706
707        $GLOBALS['db']->query("DELETE FROM accounts WHERE id= '{$accountId}'");
708        $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId1}'");
709        $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId2}'");
710        $GLOBALS['db']->query("DELETE FROM contacts WHERE id= '{$contactId3}'");
711        $GLOBALS['db']->query("DELETE FROM accounts_contacts WHERE account_id= '{$accountId}'");
712
713        $this->assertEquals($result['entry_list'][0]['name_value_list']['last_name']['value'],'New Contact 1',$this->_returnLastRawResponse());
714        $this->assertEquals($result['entry_list'][1]['name_value_list']['last_name']['value'],'New Contact 2',$this->_returnLastRawResponse());
715        $this->assertEquals($result['entry_list'][2]['name_value_list']['last_name']['value'],'New Contact 3',$this->_returnLastRawResponse());
716    }
717
718    public static function _subpanelLayoutProvider()
719    {
720        return array(
721            array(
722                'module' => 'Contacts',
723                'type' => 'default',
724                'view' => 'subpanel',
725            ),
726            array(
727                'module' => 'Leads',
728                'type' => 'wireless',
729                'view' => 'subpanel',
730            ),
731        );
732    }
733
734    /**
735     * @dataProvider _subpanelLayoutProvider
736     */
737    public function testGetSubpanelLayout($module, $type, $view)
738    {
739        $result = $this->_login();
740        $session = $result['id'];
741
742        $results = $this->_makeRESTCall('get_module_layout',
743            array(
744                'session' => $session,
745                'module' => array($module),
746                'type' => array($type),
747                'view' => array($view))
748        );
749
750        $this->assertTrue(isset($results[$module][$type][$view]), "Unable to get subpanel defs");
751    }
752     public function testGetUpcomingActivities()
753     {
754         $expected = $this->_createUpcomingActivities(); //Seed the data.
755
756         $result = $this->_login(); // Logging in just before the REST call as this will also commit any pending DB changes
757         $this->assertTrue(!empty($result['id']) && $result['id'] != -1,$this->_returnLastRawResponse());
758         $session = $result['id'];
759         $results = $this->_makeRESTCall('get_upcoming_activities',
760                             array(
761                             'session' => $session,
762                             )
763         );
764
765         $ids = array();
766         foreach($results as $activity)
767         {
768             $ids[$activity['id']] = $activity['id'];
769         }
770
771         $this->assertArrayHasKey($expected[0] , $ids , "Unable to get upcoming activities");
772         $this->assertArrayHasKey($expected[1] ,$ids , "Unable to get upcoming activities");
773
774         $this->_removeUpcomingActivities();
775     }
776
777     private function _removeUpcomingActivities()
778     {
779         $GLOBALS['db']->query("DELETE FROM calls where name = 'UNIT TEST'");
780         $GLOBALS['db']->query("DELETE FROM tasks where name = 'UNIT TEST'");
781     }
782
783     private function _createUpcomingActivities()
784     {
785         $GLOBALS['current_user']->setPreference('datef','Y-m-d') ;
786         $GLOBALS['current_user']->setPreference('timef','H:i') ;
787
788         $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
789         $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
790
791         $callID = uniqid();
792         $c = new Call();
793         $c->id = $callID;
794         $c->new_with_id = TRUE;
795         $c->status = 'Not Planned';
796         $c->date_start = $date1;
797         $c->name = "UNIT TEST";
798         $c->assigned_user_id = $this->_user->id;
799         $c->save(FALSE);
800
801         $callID = uniqid();
802         $c = new Call();
803         $c->id = $callID;
804         $c->new_with_id = TRUE;
805         $c->status = 'Planned';
806         $c->date_start = $date1;
807         $c->name = "UNIT TEST";
808         $c->assigned_user_id = $this->_user->id;
809         $c->save(FALSE);
810
811         $taskID = uniqid();
812         $t = new Task();
813         $t->id = $taskID;
814         $t->new_with_id = TRUE;
815         $t->status = 'Not Started';
816         $t->date_due = $date2;
817         $t->name = "UNIT TEST";
818         $t->assigned_user_id = $this->_user->id;
819         $t->save(FALSE);
820
821         return array($callID, $taskID);
822     }
823}