conflict.test in Conflict 7
Tests for conflict.module.
File
conflict.testView source
<?php
/**
* @file
* Tests for conflict.module.
*/
class ConflictWebTestCase extends DrupalWebTestCase {
/**
* First drupal user for Concurrent sessions tricks.
*
* @var stdClass
*/
protected $user1;
/**
* Second drupal user for Concurrent sessions tricks.
*
* @var stdClass
*/
protected $user2;
/**
* {@inheritdoc}
*/
protected function setUp() {
$modules = func_get_args();
$modules = isset($modules[0]) && is_array($modules[0]) ? $modules[0] : $modules;
parent::setUp($modules);
// Create two web users.
$this->user1 = $this
->drupalCreateUser(array(
'create page content',
'edit own page content',
));
$this->user2 = $this
->drupalCreateUser(array(
'create page content',
'edit own page content',
));
}
/**
* Helper function to switch between user1 and user2.
*
* @param stdClass $account
* Link to drupal user.
*
* @return bool
* As we are supporting concurrent session we are expecting valid session in
* given account. So try to work with existed.
*/
protected function drupalSwitchUser(stdClass $account) {
if (isset($account->session)) {
// Switch to the user session.
$this->loggedInUser = $account;
$this->curlHandle = $account->session->curlHandle;
// Restore internal browser state of the user.
// Updates content properties on $this as well as $this->loggedInUser.
$this
->drupalSetContent($account->session->content, $account->session->url);
return TRUE;
}
return FALSE;
}
/**
* Overrides DrupalWebTestCase::drupalLogin().
*
* @param stdClass $user
* The user account to log in.
* @param bool $create_concurrent_session
* (optional) Whether to create a new, concurrent user session. Pass TRUE
* for first login. Defaults to FALSE, which means that the currently logged
* in user, if logged in, is logged out and back in (default behavior).
*/
protected function drupalLogin(stdClass $user, $create_concurrent_session = FALSE) {
// If we're asked to create a new session, unset the current.
if ($create_concurrent_session) {
unset($this->curlHandle);
$this->loggedInUser = FALSE;
}
elseif ($this
->drupalSwitchUser($user)) {
$this
->verbose($this
->drupalGetcontent());
$this
->pass(t('User %name is still logged in.', array(
'%name' => $user->name,
)), t('User login'));
return;
}
// If we are logged in already and are asked to re-login, log out first.
if ($this->loggedInUser && $this->loggedInUser->uid == $user->uid) {
$this
->drupalLogout();
}
$edit = array(
'name' => $user->name,
'pass' => $user->pass_raw,
);
$this
->drupalPost('user', $edit, t('Log in'));
// If a "log out" link appears on the page, it is almost certainly because
// the login was successful.
$pass = $this
->assertLink(t('Log out'), 0, t('User %name successfully logged in.', array(
'%name' => $user->name,
)), t('User login'));
if ($pass) {
// Save the user's session on the account itself.
if (!isset($user->session)) {
$user->session = new stdClass();
}
$user->session->curlHandle = $this->curlHandle;
// Switch the currently logged in user.
$this->loggedInUser = $user;
}
}
/**
* Overrides DrupalWebTestCase::drupalLogout().
*
* @param stdClass $account
* (optional) The user account to log out.
*/
protected function drupalLogout(stdClass $account = NULL) {
// If a specific account was passed, ensure that we are operating on that
// user's session first.
if (isset($account) && (!$this->loggedInUser || $account->uid != $this->loggedInUser)) {
$this
->drupalSwitchUser($account);
}
// Make a request to the logout page, and redirect to the user page, the
// idea being if you were properly logged out you should be seeing a login
// screen.
$this
->drupalGet('user/logout');
$this
->drupalGet('user');
$pass = $this
->assertField('name', t('Username field found.'), t('Logout'));
$pass = $pass && $this
->assertField('pass', t('Password field found.'), t('Logout'));
if ($pass) {
// Remove the user's session on the account itself.
if (isset($account->session->curlHandle)) {
curl_close($account->session->curlHandle);
}
unset($account->session);
// Switch to no session.
$this->loggedInUser = FALSE;
}
}
/**
* Overrides DrupalWebTestCase::drupalSetContent().
*
* {@inheritdoc}
*/
protected function drupalSetContent($content, $url = 'internal:') {
parent::drupalSetContent($content, $url);
// Clone the relevant results onto the currently logged in user
// account/session.
if (isset($this->loggedInUser->session)) {
$this->loggedInUser->session->url = $this->url;
$this->loggedInUser->session->content = $this->content;
$this->loggedInUser->session->drupalSettings = $this->drupalSettings;
}
}
protected function createFieldWithInstance($suffix, $field_type = 'text', $entity_type = 'node', $bundle = 'page') {
$field_name = 'field_' . $suffix;
$field = field_create_field(array(
'field_name' => $field_name,
'type' => $field_type,
'cardinality' => 1,
));
$instance = array(
'field_name' => $field_name,
'entity_type' => $entity_type,
'bundle' => $bundle,
'label' => $field_name,
'description' => $this
->randomName() . '_description',
'weight' => mt_rand(0, 127),
'widget' => array(
'type' => 'text_textfield',
),
);
field_create_instance($instance);
}
}
class ConflictSwitchExampleTestCase extends ConflictWebTestCase {
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'drupalSwitchUser() example',
'description' => 'Demonstrates drupalSwitchUser() usage.',
'group' => 'Conflict',
);
}
/**
* Test internal concurrent session functional.
*/
function testConcurrentLogin() {
// Login first user.
$this
->drupalLogin($this->user1);
$this
->assertText($this->user1->name);
$this
->clickLink(t('Edit'));
// Login second user.
// Without passing TRUE, the first user would be logged out.
$this
->drupalLogin($this->user2, TRUE);
$this
->assertText($this->user2->name);
$this
->clickLink(t('Edit'));
// Switch to first user.
$this
->drupalLogin($this->user1);
// Verify that we ARE user1 and SEE what user1 saw before.
$this
->assertText($this->user1->name);
$this
->assertFieldByName('mail', $this->user1->mail);
// Switch to second user.
$this
->drupalLogin($this->user2);
// Verify that we ARE user2 and SEE what user2 saw before.
$this
->assertText($this->user2->name);
$this
->assertFieldByName('mail', $this->user2->mail);
// Log out second user.
$this
->drupalLogout();
// Switch back to first user and confirm that we're still logged in.
$this
->drupalLogin($this->user1);
// Verify that we ARE user1 and SEE what user1 saw before.
$this
->assertText($this->user1->name);
$this
->assertFieldByName('mail', $this->user1->mail);
// Log the second user back in (was logged out above).
// Without passing TRUE, the first user would be logged out.
$this
->drupalLogin($this->user2, TRUE);
$this
->assertText($this->user2->name);
$this
->clickLink(t('Edit'));
// Switch back to first user once more.
$this
->drupalLogin($this->user1);
// Verify that we ARE user1 and SEE what user1 saw before.
$this
->assertText($this->user1->name);
$this
->assertFieldByName('mail', $this->user1->mail);
}
}
class ConflictTestCase extends ConflictWebTestCase {
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'Exercise node conflicts',
'description' => 'Force conflicts while editing nodes.',
'group' => 'Conflict',
);
}
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp(array(
'conflict',
));
// Enable conflict highlights for Page content type.
variable_set('conflict_enable_page', TRUE);
$this
->drupalLogin($this->user1);
}
/**
* Test case when user should get conflicts.
*
* Emulates conflicts for title and body fields.
*/
public function testConflictCase() {
$orig_title = $this
->randomName();
$orig_body = $this
->randomString();
$conflict_title = $this
->randomName();
$conflict_body = $this
->randomString();
// Create the node to work with.
$node = $this
->drupalCreateNode(array(
'title' => $this
->randomName(),
'body' => array(
LANGUAGE_NONE => array(
array(
'value' => $this
->randomString(),
'summary' => '',
),
),
),
));
// Load the edit page up.
$this
->drupalGet("node/{$node->nid}/edit");
// Before submitting the form, make changes to the node from somewhere else.
$conflict = clone $node;
$conflict->title = $orig_title;
$conflict->body['und'][0]['value'] = $orig_body;
node_save($conflict);
// Fudge the timestamps in the database.
db_query('UPDATE {node} SET changed = changed + 100 WHERE nid = :nid', array(
':nid' => $conflict->nid,
));
db_query('UPDATE {node_revision} SET timestamp = timestamp + 100 WHERE nid = :nid', array(
':nid' => $conflict->nid,
));
// Attempt to make changes.
$edit['title'] = $conflict_title;
$edit['body[und][0][value]'] = $conflict_body;
$this
->drupalPost(NULL, $edit, t('Save'));
$this
->assertText(t('The Title field was changed by another user while you were editing it. Save again to overwrite it.'));
$this
->assertText(t('The Body field was changed by another user while you were editing it. Save again to overwrite it.'));
$this
->assertFieldByXPath('//*[@id="edit-title" and contains(@class, "error")]', $conflict_title, 'Title field was highlighted with error and contains conflicted data.');
$this
->assertFieldByXPath('//*[@id="edit-body-und-0-value" and contains(@class, "error")]', $conflict_body, 'Body field was highlighted with error and contains conflicted data.');
}
/**
* Test case for outdated values.
*
* Emulates that title and body fields are outdated.
*/
public function testNeedUpdateCase() {
$orig_title = $this
->randomName();
$orig_body = $this
->randomString();
$their_title = $this
->randomName();
$their_body = $this
->randomString();
// Create the node to work with.
$node = $this
->drupalCreateNode(array(
'title' => $orig_title,
'body' => array(
LANGUAGE_NONE => array(
array(
'value' => $orig_body,
'summary' => '',
),
),
),
));
// Load the edit page up.
$this
->drupalGet("node/{$node->nid}/edit");
// Before submitting the form, make changes to the node from somewhere else.
$conflict = clone $node;
$conflict->title = $their_title;
$conflict->body['und'][0]['value'] = $their_body;
node_save($conflict);
// Fudge the timestamps in the database.
db_query('UPDATE {node} SET changed = changed + 100 WHERE nid = :nid', array(
':nid' => $conflict->nid,
));
db_query('UPDATE {node_revision} SET timestamp = timestamp + 100 WHERE nid = :nid', array(
':nid' => $conflict->nid,
));
// Attempt to make changes.
$edit['title'] = $orig_title;
$edit['body[und][0][value]'] = $orig_body;
$this
->drupalPost(NULL, $edit, t('Save'));
$this
->assertText(t('The Title field was changed by another user. Please verify the updated value.'));
$this
->assertText(t('The Body field was changed by another user. Please verify the updated value.'));
$this
->assertFieldByXPath('//*[@id="edit-title" and contains(@class, "error")]', $their_title, 'Title field was highlighted with error and contains conflicted data.');
$this
->assertFieldByXPath('//*[@id="edit-body-und-0-value" and contains(@class, "error")]', $their_body, 'Body field was highlighted with error and contains conflicted data.');
}
/**
* Test case for complex errors.
*
* Emulates that title field has conflict; body field is outdated and
* custom field_text is not modified and not outdated.
*/
public function testComplexTroublesCase() {
$this
->createFieldWithInstance('text');
$orig_title = $this
->randomName();
$orig_body = $this
->randomString();
$orig_text = $this
->randomString();
$their_title = $this
->randomName();
$their_body = $this
->randomString();
// Create the node to work with.
$node = $this
->drupalCreateNode(array(
'title' => $this
->randomName(),
'body' => array(
LANGUAGE_NONE => array(
array(
'value' => $orig_body,
'summary' => '',
),
),
),
'field_text' => array(
LANGUAGE_NONE => array(
array(
'value' => $orig_text,
),
),
),
));
// Load the edit page up.
$this
->drupalGet("node/{$node->nid}/edit");
// Before submitting the form, make changes to the node from somewhere else.
$conflict = clone $node;
$conflict->title = $their_title;
$conflict->body['und'][0]['value'] = $their_body;
$conflict->field_text['und'][0]['value'] = $orig_text;
node_save($conflict);
// Fudge the timestamps in the database.
db_query('UPDATE {node} SET changed = changed + 100 WHERE nid = :nid', array(
':nid' => $conflict->nid,
));
db_query('UPDATE {node_revision} SET timestamp = timestamp + 100 WHERE nid = :nid', array(
':nid' => $conflict->nid,
));
// Attempt to make changes.
$edit['title'] = $orig_title;
$edit['body[und][0][value]'] = $orig_body;
$edit['field_text[und][0][value]'] = $orig_text;
$this
->drupalPost(NULL, $edit, t('Save'));
$this
->assertNoText('The content on this page has either been modified by another user, or you have already submitted modifications using this form. As a result, your changes cannot be saved.');
$this
->assertText(t('The Title field was changed by another user while you were editing it. Save again to overwrite it.'));
$this
->assertText('The Body field was changed by another user. Please verify the updated value.');
$this
->assertNoText('The field_text field was changed by another user. Please verify the updated value.');
$this
->assertFieldByXPath('//*[@id="edit-title" and contains(@class, "error")]', $orig_title, 'Title field was highlighted with error and contains conflicted data.');
$this
->assertFieldByXPath('//*[@id="edit-body-und-0-value" and contains(@class, "error")]', $their_body, 'Body field was highlighted with error and contains conflicted data.');
$this
->assertNoFieldByXPath('//*[@id="edit-field_text-und-0-value" and contains(@class, "error")]', $orig_text, 'Custom field was not highlighted with error and contains conflicted data.');
}
}
Classes
Name | Description |
---|---|
ConflictSwitchExampleTestCase | |
ConflictTestCase | |
ConflictWebTestCase | @file Tests for conflict.module. |