<?php

/**
 * @file
 * Test protected node bulk actions functionality.
 */

/**
 * Configure protected_node to use mixin password.
 */
class ProtectedNodeBulkPassword extends ProtectedNodeBaseTestCase {

  /**
   * {@inheritdoc}
   */
  public static function getInfo() {
    return array(
      'name' => 'Protected node bulk actions feature',
      'description' => "This tests bulk actions features",
      'group' => 'Protected Node',
    );
  }

  /**
   * {@inheritdoc}
   */
  public function setUp() {
    parent::setUp();
    // Generate random password.
    $this->global_password = $this->randomName(10);

    // Log in an Admin.
    $this->drupalLogin($this->adminUser);
    // Submit the configuration form.
    $protected_node_settings = array(
      'protected_node_use_global_password' => PROTECTED_NODE_PER_NODE_AND_GLOBAL_PASSWORD,
      'protected_node_global_password_field[pass1]' => $this->global_password,
      'protected_node_global_password_field[pass2]' => $this->global_password,
    );
    $this->drupalPost('admin/config/content/protected_node', $protected_node_settings, t('Save configuration'));
  }

  /**
   * Test function.
   *
   * Test that the password has to be re-entered after clearing the sessions.
   */
  public function testClearSessions() {
    // Log in as Admin.
    $this->drupalLogin($this->adminUser);
    // Create a new page node.
    $node = $this->createGlobalProtectedNode();
    // Once the node created logout the user.
    $this->drupalLogout();

    // An authenticated user sees the node.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $form = array('password' => $this->global_password);
    $this->drupalPost('node/' . $node->nid, $form, t('OK'));

    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission can access a protected node with right password", $this->group);

    // Log in as Admin to clear sessions.
    $this->drupalLogin($this->adminUser);
    $this->drupalPost('admin/config/content/protected_node', array(), t('Clear sessions'));
    $this->drupalLogout();

    // An authenticated user sees the node.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $this->drupalGet('node/' . $node->nid);

    $text = 'Protected page -- Enter password';
    $this->assertText($text, "User with right permission has to re-enter the password", $this->group);
  }

  /**
   * Test function.
   *
   * Test that the node password is changed after using reset passwords.
   */
  public function testResetPasswords() {
    // Log in as Admin.
    $this->drupalLogin($this->adminUser);
    // Generate random password.
    $password = $this->randomName(10);
    // Create a new page node.
    $node = $this->createByNodeProtectedNode($password);
    // Reset passwords.
    $new_password = $this->randomName(15);
    $form = array(
      'protected_node_reset_passwords_password[pass1]' => $new_password,
      'protected_node_reset_passwords_password[pass2]' => $new_password,
    );
    $this->drupalPost('admin/config/content/protected_node', $form, t('Reset all existing passwords'));
    // Once the node created logout the user.
    $this->drupalLogout();

    // An authenticated user can't see the node with the original node password.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $form = array('password' => $password);
    $this->drupalPost('node/' . $node->nid, $form, t('OK'));

    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertNoText($text, "User with right permission can't access a protected node with the node's password", $this->group);

    // An authenticated user can see the node with the new password.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $form = array('password' => $new_password);
    $this->drupalPost('node/' . $node->nid, $form, t('OK'));

    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission has to enter the new password", $this->group);
  }

  /**
   * Test function.
   *
   * Test that the node password is erased after using global password.
   */
  public function testUseGlobalPassword() {
    // Log in as Admin.
    $this->drupalLogin($this->adminUser);
    // Generate random password.
    $password = $this->randomName(10);
    // Create a new page node.
    $node = $this->createByNodeProtectedNode($password);
    // Use global password.
    $this->drupalPost('admin/config/content/protected_node', array(), t('Use global password on ALL nodes'));
    // Once the node created logout the user.
    $this->drupalLogout();

    // An authenticated user can't see the node with the node password.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $form = array('password' => $password);
    $this->drupalPost('node/' . $node->nid, $form, t('OK'));

    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertNoText($text, "User with right permission can't access a protected node with the node's password", $this->group);

    // An authenticated user can see the node with global password.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $form = array('password' => $this->global_password);
    $this->drupalPost('node/' . $node->nid, $form, t('OK'));

    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission has to enter the global password", $this->group);
  }

  /**
   * Test function.
   *
   * Test that a node is unprotected after using the bulk action to remove
   * protection.
   */
  public function testRemoveProtection() {
    // Log in as Admin.
    $this->drupalLogin($this->adminUser);
    // Create a new page node.
    $node = $this->createGlobalProtectedNode();
    // Once the node created logout the user.
    $this->drupalLogout();

    // An authenticated user can't see the node without password.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $this->drupalGet('node/' . $node->nid);
    $text = 'Protected page -- Enter password';
    $this->assertText($text, "User with right permission has to enter the password", $this->group);

    // Log in as Admin to remove protection.
    $this->drupalLogin($this->adminUser);
    $this->drupalPost('admin/config/content/protected_node', array(), t('Remove password protection from all nodes'));
    $this->drupalLogout();

    // An authenticated user can see the node without password.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $this->drupalGet('node/' . $node->nid);

    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission can access an unprotected node", $this->group);
  }

  /**
   * Test function.
   *
   * Test that a node is protected after using the bulk action to protect nodes.
   */
  public function testProtectNodes() {
    // Log in as Admin.
    $this->drupalLogin($this->adminUser);
    // Create a new page node.
    $node = $this->drupalCreateNode();
    // Once the node created logout the user.
    $this->drupalLogout();

    // An authenticated user can see the node without password.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $this->drupalGet('node/' . $node->nid);

    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission can see an unprotected node", $this->group);

    // Protect the node.
    $this->drupalLogin($this->adminUser);
    $this->drupalPost('admin/config/content/protected_node', array(), t('Protect ALL nodes'));
    $this->drupalLogout();

    // An authenticated user can't see the node without password.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $this->drupalGet('node/' . $node->nid);

    $text = 'Protected page -- Enter password';
    $this->assertText($text, "User with right permission has to enter the password to see a protected node", $this->group);
  }

  /**
   * Test function.
   *
   * Test that the password has to be entered after restoring protection.
   */
  public function testRestoreProtection() {
    // Log in as Admin.
    $this->drupalLogin($this->adminUser);
    // Generate random password.
    $password = $this->randomName(10);
    // Create a new page node.
    $node = $this->createByNodeProtectedNode($password);
    // Remove protection.
    $this->drupalPost('admin/config/content/protected_node', array(), t('Remove password protection from all nodes'));
    // Once the node created logout the user.
    $this->drupalLogout();

    // An authenticated user sees the node.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $this->drupalGet('node/' . $node->nid);
    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission can access an unprotected node", $this->group);

    // Log in as Admin to clear sessions.
    $this->drupalLogin($this->adminUser);
    $this->drupalPost('admin/config/content/protected_node', array(), t('Protect nodes that already have a password'));
    $this->drupalLogout();

    // An authenticated user has to enter the password to see the node.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $this->drupalGet('node/' . $node->nid);
    $text = 'Protected page -- Enter password';
    $this->assertText($text, "User with right permission has to enter the password", $this->group);
  }

  /**
   * Helper method to create a protected node.
   *
   * Please make sure the user has the permission to create the node before
   * calling the method.
   *
   * @return object
   *   A node object.
   */
  public function createGlobalProtectedNode() {
    // Add a new page node that is protected.
    $node_title = $this->randomName(8);
    $node_data = array(
      'title' => $node_title,
      'body[und][0][value]' => $this->randomName(32),
      'protected_node_is_protected' => TRUE,
    );
    $this->drupalPost('node/add/page', $node_data, t('Save'));

    return $this->drupalGetNodeByTitle($node_title);
  }

  /**
   * Helper method to create a protected node.
   *
   * Please make sure the user has the permission to create the node before
   * calling the method.
   *
   * @param string $password
   *   A password.
   *
   * @return object
   *   A node object.
   */
  public function createByNodeProtectedNode($password) {
    // Add a new page node that is protected.
    $node_title = $this->randomName(8);
    $node_data = array(
      'title' => $node_title,
      'body[und][0][value]' => $this->randomName(32),
      'protected_node_is_protected' => TRUE,
      'protected_node_passwd[pass1]' => $password,
      'protected_node_passwd[pass2]' => $password,
    );
    $this->drupalPost('node/add/page', $node_data, t('Save'));

    return $this->drupalGetNodeByTitle($node_title);
  }

}
