Пример #1
0
 public function testMassUpdateNameId()
 {
     $contact = $this->contact('testAnyone');
     // First, need to break all the nameIds...
     Contacts::model()->updateAll(array('nameId' => null));
     // Try with the mass update method, one ID:
     X2Model::massUpdateNameId('Contacts', array($contact->id));
     $contact->refresh();
     $this->assertEquals(Fields::nameId($contact->name, $contact->id), $contact->nameId);
     // Again, but with the "ids" parameter an int instead of an array
     X2Model::massUpdateNameId('Contacts', $contact->id);
     $contact->refresh();
     $this->assertEquals(Fields::nameId($contact->name, $contact->id), $contact->nameId);
     // Try again, multiple records:
     $contact2 = $this->contact('testUser');
     Contacts::model()->updateAll(array('nameId' => null));
     X2Model::massUpdateNameId('Contacts', array($contact->id, $contact2->id));
     $contact->refresh();
     $contact2->refresh();
     $this->assertEquals(Fields::nameId($contact->name, $contact->id), $contact->nameId);
     $this->assertEquals(Fields::nameId($contact2->name, $contact2->id), $contact2->nameId);
     // Try one last time, all records:
     Contacts::model()->updateAll(array('nameId' => null));
     X2Model::massUpdateNameId('Contacts');
     $contact->refresh();
     $contact2->refresh();
     $this->assertEquals(Fields::nameId($contact->name, $contact->id), $contact->nameId);
     $this->assertEquals(Fields::nameId($contact2->name, $contact2->id), $contact2->nameId);
 }
Пример #2
0
 /**
  * Sets the nameId field appropriately.
  *
  * The model must be inserted already, so that its primary key can
  * be used.
  * @param bool $save If true, update the model when done.
  */
 public function updateNameId($save = false)
 {
     if (!$this->hasAttribute('nameId')) {
         return;
     }
     $this->_oldAttributes['nameId'] = $this->nameId;
     $this->nameId = Fields::nameId($this->name, $this->id);
     if ($save) {
         $that = $this;
         $this->runWithoutBehavior('X2FlowTriggerBehavior', function () use($that) {
             $that->updateByPk($that->id, array('nameId' => $that->nameId));
         });
     }
 }
Пример #3
0
 public function testAfterSave()
 {
     $contact = $this->contact('testAnyone');
     $account = $this->account('account1');
     $account2 = $this->account('account2');
     $this->assertFalse($contact->relationships->hasRelationship($account));
     $contact->company = Fields::nameId($account->name, $account->id);
     $this->assertSaves($contact);
     $this->assertTrue($contact->relationships->hasRelationship($account));
     //Contact needs to be reloaded to refresh oldAttributes for afterSave
     $contact = Contacts::model()->findByPk($contact->id);
     $contact->company = Fields::nameId($account2->name, $account2->id);
     $this->assertSaves($contact);
     $this->assertFalse($contact->relationships->hasRelationship($account));
     $this->assertTrue($contact->relationships->hasRelationship($account2));
     $contact = Contacts::model()->findByPk($contact->id);
     $contact->company = NULL;
     $this->assertSaves($contact);
     $this->assertFalse($contact->relationships->hasRelationship($account));
     $this->assertFalse($contact->relationships->hasRelationship($account2));
 }
Пример #4
0
 /**
  * Assert that an Action's association* fields are properly set
  * @param Actions $action
  * @param X2Model $association
  */
 protected function assertActionAssociation(Actions $action, X2Model $association)
 {
     $associationNameId = Fields::nameId($association->name, $association->id);
     $this->assertEquals(lcfirst(get_class($association)), $action->associationType);
     $this->assertEquals($association->id, $action->associationId);
     $this->assertEquals($associationNameId, $action->associationName);
 }
Пример #5
0
 public function actionCreateRecords()
 {
     $contact = new Contacts();
     $account = new Accounts();
     $opportunity = new Opportunity();
     $users = User::getNames();
     if (isset($_POST['Contacts']) && isset($_POST['Accounts']) && isset($_POST['Opportunity'])) {
         $contact->setX2Fields($_POST['Contacts']);
         $account->setX2Fields($_POST['Accounts']);
         $opportunity->setX2Fields($_POST['Opportunity']);
         $validAccount = true;
         if ($account->validate() == false) {
             $validAccount = false;
             // validate other models so that the user gets feedback
             $contact->validate();
             $opportunity->validate();
         }
         if ($validAccount) {
             $allValid = true;
             $a = $this->createAccount($account, $account->attributes, '1');
             // Contact and Opportunity require Account id for lookup field
             $contact->company = Fields::nameId($account->name, $account->id);
             if ($contact->validate() == false) {
                 $allValid = false;
             }
             $c = $this->createContact($contact, $contact->attributes, '1');
             $opportunity->accountName = Fields::nameId($account->name, $account->id);
             $opportunity->contactName = Fields::nameId($contact->name, $contact->id);
             if ($opportunity->validate() == false) {
                 $allValid = false;
             }
             $o = $this->createOpportunity($opportunity, $opportunity->attributes, '1');
             if ($allValid && $c && $a && $o) {
                 // all records created?
                 Relationships::create('Contacts', $contact->id, 'Accounts', $account->id);
                 Relationships::create('Opportunity', $opportunity->id, 'Contacts', $contact->id);
                 Relationships::create('Opportunity', $opportunity->id, 'Accounts', $account->id);
                 if (isset($_GET['ret'])) {
                     if ($_GET['ret'] == 'contacts') {
                         $this->redirect(array("/contacts/contacts/view", 'id' => $contact->id));
                     } else {
                         if ($_GET['ret'] == 'accounts') {
                             $this->redirect(array("/accounts/accounts/view", 'id' => $account->id));
                         } else {
                             if ($_GET['ret'] == 'opportunities') {
                                 $this->redirect(array("/opportunities/opportunities/view", 'id' => $opportunity->id));
                             }
                         }
                     }
                 } else {
                     $this->redirect(array("/contacts/contacts/view", $contact->id));
                 }
             } else {
                 // otherwise clean up
                 $types = array('account' => 'Accounts', 'contact' => 'Contacts', 'opportunity' => 'Opportunity');
                 foreach ($types as $model => $type) {
                     if (${$model} && isset(${$model}->id)) {
                         $modelId = ${$model}->id;
                         ${$model}->delete();
                         // delete all new actions and events from creating/deleting records
                         foreach (array('Actions', 'Events') as $meta) {
                             X2Model::model($meta)->deleteAllByAttributes(array('associationId' => $modelId, 'associationType' => $type));
                         }
                     }
                 }
             }
         }
     }
     $this->render('createRecords', array('contact' => $contact, 'account' => $account, 'opportunity' => $opportunity, 'users' => $users));
 }
Пример #6
0
 public function testNameId()
 {
     $d = Fields::NAMEID_DELIM;
     $this->assertEquals('My Name' . $d . '12345', Fields::nameId('My Name', 12345));
 }
Пример #7
0
 /**
  * Test the creation, reading, updating and deletion of records through the 
  * API, and validation errors.
  */
 public function assertCRUD()
 {
     $urlParam = $this->urlParam;
     $urlParam['{action}'] = 'create';
     $param = $this->param;
     $modelAttrs = array('Accounts' => array('name' => 'ApiAccount', 'type' => 'business', 'assignedTo' => 'testuser'), 'Actions' => array('assignedTo' => 'testuser', 'dueDate' => time() + 86400), 'Contacts' => array('firstName' => 'ApiContactFirstName', 'lastName' => 'ApiContactLastName', 'email' => '*****@*****.**', 'visibility' => 1, 'assignedTo' => 'admin'), 'Docs' => array('name' => 'Excellent birds', 'subject' => 'Test subject', 'text' => 'Vel lorem risus, massa, sociis sagittis! Turpis magna sed, tristique? Pid massa integer facilisis...'), 'Opportunity' => array('name' => 'Falling snow', 'description' => 'Urna dolor? Sed tortor arcu mid porttitor egestas pulvinar etiam, diam? Aliquam, cras ultricies elementum?...', 'assignedTo' => 'testuser'), 'Product' => array('name' => 'Excellent snow', 'description' => "Enim amet! Porttitor, amet pulvinar augue sed auctor, phasellus pellentesque nunc nunc amet proin...", 'type' => 'watch it fall'), 'Services' => array('contactId' => $this->contacts('testUser')->id, 'description' => 'This is the picture! (of the error). Fix it.', 'impact' => '1 - Severe', 'status' => 'new'));
     $classModulesMap = array_combine(array_keys($modelAttrs), array_keys($modelAttrs));
     $classModulesMap['Product'] = 'Products';
     $classModulesMap['Opportunity'] = 'Opportunities';
     // Stash models in here:
     $models = array();
     // Users to try the actions for:
     $n_users = count($this->users);
     $i = 0;
     foreach ($this->users as $userParam) {
         $param = array('user' => $userParam['username'], 'userKey' => $userParam['userKey']);
         $apiModel = $this->newModel($userParam['username'], $userParam['userKey']);
         $i++;
         foreach ($modelAttrs as $class => $attrs) {
             //			echo "Testing creation of $class record through API\n";
             $urlParam['{model}'] = $class;
             $ch = $this->getCurlHandle($urlParam, array_merge($param, $attrs));
             $cr = curl_exec($ch);
             file_put_contents('api_response.html', $cr);
             $authAction = $classModulesMap[$class] . 'Create';
             $this->assertResponseCodeIs(200, $ch, 'Failed create operation. Response = ' . $cr);
             $access = $this->assertAuthControlCorrectness($authAction, $ch, $apiModel);
             if ($access) {
                 $userAttrs = array();
                 foreach (array('createdBy', 'updatedBy') as $name) {
                     if (X2Model::model($class)->hasAttribute($name)) {
                         $userAttrs[$name] = $param['user'];
                     }
                 }
                 if ($class == 'Services') {
                     // Test setting a linktype field and having it turn into a nameId reference:
                     $attrs['contactId'] = Fields::nameId($this->contacts('testUser')->name, $this->contacts('testUser')->id);
                 }
                 $models[$class] = X2Model::model($class)->findByAttributes(array_merge($attrs, $userAttrs));
                 $this->assertTrue((bool) $models[$class], "Model of class {$class} not created properly when user = {$param['user']}. The response was: {$cr}.");
                 foreach ($attrs as $attr => $value) {
                     $this->assertEquals($value, $models[$class]->{$attr});
                 }
                 // Test that createDate was set properly:
                 if ($models[$class]->hasAttribute('createDate')) {
                     $this->assertNotNull($models[$class]->createDate);
                 }
             }
         }
     }
     // We've got our models. Now let's test finding by attributes ("lookup"):
     $urlParam['{action}'] = 'view';
     // We're going to need primary keys for the direct "view" read action:
     $pkValues = array();
     foreach ($this->users as $userParam) {
         $param = array('user' => $userParam['username'], 'userKey' => $userParam['userKey']);
         $apiModel = $this->newModel($userParam['username'], $userParam['userKey']);
         foreach ($modelAttrs as $class => $attrs) {
             $urlParam['{model}'] = $class;
             $ch = $this->getCurlHandle($urlParam, array_merge($param, array('id' => $models[$class]->id)));
             $cr = curl_exec($ch);
             file_put_contents('api_response.html', $cr);
             $authAction = $classModulesMap[$class] . 'View';
             $access = $this->assertAuthControlCorrectness($authAction, $ch, $apiModel);
             if ($access) {
                 $this->assertResponseCodeIs(200, $ch);
                 $queriedModel = CJSON::decode($cr);
                 // Response must be valid JSON:
                 $this->assertEquals('array', gettype($queriedModel));
                 $models[$class]->refresh();
                 // Test that the attributes are all equal. This is pretty much overkill.
                 foreach ($queriedModel as $attr => $value) {
                     $this->assertEquals($models[$class]->{$attr}, $value, "Failed asserting attribute equality for {$class}.{$attr}");
                 }
                 // This will be useful for the next tests (lookup by pk, update & delete):
                 $pkValues[$class] = $models[$class]->primaryKey;
             }
         }
     }
     // Test "view": lookup by ID. We already know that access control for the
     // "view" action is already correct; it was tested just previously. So
     // this test shall use the admin user:
     $urlParam['{action}'] = 'view';
     $param = array('user' => $userParam['username'], 'userKey' => $userParam['userKey']);
     foreach ($pkValues as $class => $pk) {
         $urlParam['{model}'] = $class;
         $get = array();
         if (is_array($pk)) {
             // Composite primary key
             $get = array_merge($get, $pk);
         } else {
             // Single-column primary key
             $get[$models[$class]->tableSchema->primaryKey] = $pk;
         }
         $urlParam['{params}'] = '?' . http_build_query($get, '', '&');
         $ch = $this->getCurlHandle($urlParam, $param);
         $cr = curl_exec($ch);
         file_put_contents('api_response.html', $cr);
         $this->assertResponseCodeIs(200, $ch);
         $queriedModel = CJSON::decode($cr);
         $this->assertEquals('array', gettype($queriedModel), 'Failed asserting that the response from the server was valid JSON.');
     }
     // Test "update": modify record by ID:
     $urlParam['{action}'] = 'update';
     $urlParam['{params}'] = '';
     $modelAttrs = array('Accounts' => array('description' => 'I have now added a description to this account.'), 'Actions' => array('assignedTo' => 'testuser', 'dueDate' => time() + 86400), 'Contacts' => array('firstName' => 'ApiContactFirstNameEdited', 'lastName' => 'ApiContactLastNameEdited', 'email' => '*****@*****.**'), 'Docs' => array('name' => 'Excellent.', 'subject' => 'Test subject 2', 'text' => 'Edited...'), 'Opportunity' => array('name' => 'Falling snow', 'description' => 'Urna dolor? Aliquam, cras ultricies elementum?...Edited'), 'Product' => array('name' => 'Esnow', 'description' => "Enim amet! Edited", 'type' => 'watchfall'), 'Services' => array('description' => 'This is edited.'));
     foreach ($this->users as $userParam) {
         $param = array('user' => $userParam['username'], 'userKey' => $userParam['userKey']);
         $apiModel = $this->newModel($userParam['username'], $userParam['userKey']);
         foreach ($pkValues as $class => $pk) {
             $urlParam['{model}'] = $class;
             $post = array_merge($param, $modelAttrs[$class]);
             $get = array();
             if (is_array($pk)) {
                 // Composite primary key
                 $get = array_merge($get, $pk);
             } else {
                 // Single-column primary key
                 $get[$models[$class]->tableSchema->primaryKey] = $pk;
             }
             $urlParam['{params}'] = '?' . http_build_query($get, '', '&');
             $ch = $this->getCurlHandle($urlParam, $post);
             $cr = curl_exec($ch);
             file_put_contents('api_response.html', $cr);
             // Choose the expected response code based on the permissions:
             $authAction = $classModulesMap[$class] . 'Update';
             $access = $this->assertAuthControlCorrectness($authAction, $ch, $apiModel);
             // Refresh the stowed model and verify that it was updated properly:
             $models[$class]->refresh();
             if ($access) {
                 foreach ($modelAttrs[$class] as $attr => $value) {
                     $this->assertEquals($value, $models[$class]->{$attr}, "Failed asserting that attribute {$attr} was updated in model {$class}.");
                 }
             }
         }
     }
     // Test errors.
     // We'll need use the admin user to avoid unnecessary 403's.
     // Test validation errors.
     $class = 'Docs';
     $oldModelAttrs = $modelAttrs[$class]['subject'];
     $modelAttrs[$class]['subject'] = implode(',', range(1, 10000));
     $urlParam['{model}'] = $class;
     $param = array('user' => $this->users('admin')->username, 'userKey' => $this->users('admin')->userKey);
     $post = array_merge($param, $modelAttrs[$class]);
     $get = array();
     $pk = $pkValues[$class];
     if (is_array($pk)) {
         // Composite primary key
         $get = array_merge($get, $pk);
     } else {
         // Single-column primary key
         $get[$models[$class]->tableSchema->primaryKey] = $pk;
     }
     $urlParam['{params}'] = '?' . http_build_query($get, '', '&');
     $ch = $this->getCurlHandle($urlParam, $post);
     $cr = curl_exec($ch);
     file_put_contents('api_response.html', $cr);
     $this->assertResponseCodeIs(500, $ch, 'Failed asserting that a validation error could be triggered in the API');
     // Test incorrect primary key errors:
     $class = 'Docs';
     $modelAttrs[$class]['subject'] = $oldModelAttrs;
     $pk = 38923;
     $urlParam['{model}'] = $class;
     $get = array();
     $get['id'] = $pk;
     $urlParam['{params}'] = '?' . http_build_query($get, '', '&');
     $ch = $this->getCurlHandle($urlParam, $post);
     $cr = curl_exec($ch);
     file_put_contents('api_response.html', $cr);
     $this->assertResponseCodeIs(404, $ch, 'Failed asserting proper error code in an update operation with incorrect primary key.');
     $urlParam['{action}'] = 'delete';
     $ch = $this->getCurlHandle($urlParam, $post);
     $cr = curl_exec($ch);
     file_put_contents('api_response.html', $cr);
     $this->assertResponseCodeIs(404, $ch, 'Failed asserting proper error code in a delete operation with incorrect primary key.');
     $urlParam['{action}'] = 'view';
     $ch = $this->getCurlHandle($urlParam, $post);
     $cr = curl_exec($ch);
     file_put_contents('api_response.html', $cr);
     $this->assertResponseCodeIs(404, $ch, 'Failed asserting proper error code in a view operation with incorrect primary key.');
     // Test missing primary key errors:
     $get = array();
     $urlParam['{params}'] = '?' . http_build_query($get, '', '&');
     $ch = $this->getCurlHandle($urlParam, $post);
     $cr = curl_exec($ch);
     file_put_contents('api_response.html', $cr);
     $this->assertResponseCodeIs(400, $ch, 'Failed asserting proper error code in an update operation missing primary key.');
     $urlParam['{action}'] = 'delete';
     $ch = $this->getCurlHandle($urlParam, $post);
     $cr = curl_exec($ch);
     file_put_contents('api_response.html', $cr);
     $this->assertResponseCodeIs(400, $ch, 'Failed asserting proper error code in a delete operation missing primary key.');
     $urlParam['{action}'] = 'view';
     $ch = $this->getCurlHandle($urlParam, $post);
     $cr = curl_exec($ch);
     file_put_contents('api_response.html', $cr);
     $this->assertResponseCodeIs(400, $ch, 'Failed asserting proper error code in a view operation missing primary key.');
     // Test deletion.
     $urlParam['{action}'] = 'delete';
     $urlParam['{params}'] = '';
     foreach ($pkValues as $class => $pk) {
         $urlParam['{model}'] = $class;
         $post = $param;
         if (is_array($pk)) {
             // Composite primary key
             $post = array_merge($post, $pk);
         } else {
             // Single-column primary key
             $post[$models[$class]->tableSchema->primaryKey] = $pk;
         }
         $ch = $this->getCurlHandle($urlParam, $post);
         $cr = curl_exec($ch);
         file_put_contents('api_response.html', $cr);
         $this->assertResponseCodeIs(200, $ch, 'Failed asserting that deletion request succeeded.');
         $model = X2Model::model($class)->findByPk($pk);
         // No more model matching PK?
         $this->assertFalse((bool) $model, 'Failed asserting that the deletion target exists.');
     }
 }