<?php

/**
 * @file
 * Test protected node fork functionality.
 */

/**
 * Configure protected_node to use per node password.
 */
class ProtectedNodeFork extends ProtectedNodeBaseTestCase {

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

  /**
   * {@inheritdoc}
   */
  public function setUp() {
    parent::setUp();

    // 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_PASSWORD,
    );
    $this->drupalPost('admin/config/content/protected_node', $protected_node_settings, t('Save configuration'));
  }

  /**
   * Test function.
   *
   * Test that the fork feature password form is accessed only when the page has
   * the good parameters.
   */
  public function testForkPageAccess() {
    // Log in as Admin.
    $this->drupalLogin($this->adminUser);
    // Generate random password.
    $password = $this->randomName(10);
    // Create a new page node.
    $node = $this->createProtectedNode($password);
    // Once the node created logout the user.
    $this->drupalLogout();

    $this->drupalLogin($this->normalAccessAllowedUser);
    // Absence of protected_pages parameter.
    $this->drupalGet('protected-nodes');
    $this->assertResponse(403, "The protected-nodes page can't be accessed without the protected_pages parameter.");

    // Presence of protected_pages parameter and the first node does not exist.
    $this->drupalGet('protected-nodes', array('query' => array('protected_pages' => '')));
    $this->assertResponse(403, "The protected-nodes page can't be accessed without a first valid nid in the protected_pages parameter.");

    // Absence of destination parameter.
    $this->drupalGet('protected-nodes', array('query' => array('protected_pages' => $node->nid, 'destination' => '')));
    $this->assertResponse(403, "The protected-nodes page can't be accessed if there is a destination parameter.");

    // Normal access.
    $form = array('password' => $password);
    $this->drupalPost('protected-nodes', $form, t('OK'), array('query' => array('protected_pages' => $node->nid)));
    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission is redirected to a protected node with right password", $this->group);
  }

  /**
   * Test function.
   *
   * Test that the user is redirected to the node with the matching password.
   */
  public function testMatchingPassword() {
    // Log in as Admin.
    $this->drupalLogin($this->adminUser);
    // Generate random passwords.
    $password1 = $this->randomName(10);
    $password2 = $this->randomName(15);
    // Create two page nodes.
    $node1 = $this->createProtectedNode($password1);
    $node2 = $this->createProtectedNode($password2);
    // Once the nodes created logout the user.
    $this->drupalLogout();

    // Prepare protected_pages parameter.
    $protected_pages = implode(',', array($node1->nid, $node2->nid));

    // Access to node1.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $form = array('password' => $password1);
    $this->drupalPost('protected-nodes', $form, t('OK'), array('query' => array('protected_pages' => $protected_pages)));
    $text = $node1->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission is redirected to 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();

    // Access to node2.
    $this->drupalLogin($this->normalAccessAllowedUser);
    $form = array('password' => $password2);
    $this->drupalPost('protected-nodes', $form, t('OK'), array('query' => array('protected_pages' => $protected_pages)));
    $text = $node2->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission is redirected to a protected node with right password", $this->group);
  }

  /**
   * Test function.
   *
   * Test that the user it redirected to the node he/she has already entered the
   * password.
   */
  public function testAlreadyEnteredPassword() {
    // Log in as Admin.
    $this->drupalLogin($this->adminUser);
    // Generate random passwords.
    $password = $this->randomName(10);
    // Create a new page nodes.
    $node = $this->createProtectedNode($password);
    // Once the nodes created logout the user.
    $this->drupalLogout();

    $this->drupalLogin($this->normalAccessAllowedUser);
    // Access to the node the first time.
    $form = array('password' => $password);
    $this->drupalPost('protected-nodes', $form, t('OK'), array('query' => array('protected_pages' => $node->nid)));
    $text = $node->body[LANGUAGE_NONE][0]['value'];
    $this->assertText($text, "User with right permission is redirected to a protected node with right password", $this->group);

    // Access to the node the second time.
    $this->drupalGet('protected-nodes', array('query' => array('protected_pages' => $node->nid)));
    $this->assertText($text, "User with right permission is redirected to a protected node with right password previously entered", $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.
   *
   * @param string $password
   *   A password.
   *
   * @return object
   *   A node object.
   */
  public function createProtectedNode($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);
  }

}
