<?php

/**
 * @file
 * Unit tests for the override_node_options module.
 */

class OverrideNodeOptionsTestCase extends DrupalWebTestCase {
  protected $normal_user;
  protected $admin_user;
  protected $node;

  public static function getInfo() {
    return array(
      'name' => 'Override node options',
      'description' => 'Functional tests for overridding options on node forms.',
      'group' => 'Override node options',
    );
  }

  public function setUp() {
    parent::setUp('override_node_options');
    $this->normal_user = $this->drupalCreateUser(array('create page content', 'edit any page content'));
    $this->node = $this->drupalCreateNode();
  }

  /**
   * Assert that fields in a node were updated to certail values.
   *
   * @param $node
   *   The node object to check (will be reloaded from the database).
   * @param $fields
   *   An array of values to check equality, keyed by node object property.
   */
  function assertNodeFieldsUpdated(stdClass $node, array $fields) {
    // Re-load the node from the database to make sure we have the current
    // values.
    $node = node_load($node->nid, NULL, TRUE);
    foreach ($fields as $field => $value) {
      $this->assertEqual($node->$field, $value, t('Node @field was updated to !value, expected !expected.', array('@field' => $field, '!value' => var_export($node->$field, TRUE), '!expected' => var_export($value, TRUE))));
    }
  }

  /**
   * Assert that the user cannot access fields on node add and edit forms.
   *
   * @param $node
   *   The node object, will be used on the node edit form.
   * @param $fields
   *   An array of form fields to check.
   */
  function assertNodeFieldsNoAccess(stdClass $node, array $fields) {
    $this->drupalGet('node/add/' . $node->type);
    foreach ($fields as $field) {
      $this->assertNoFieldByName($field);
    }

    $this->drupalGet('node/' . $this->node->nid . '/edit');
    foreach ($fields as $field) {
      $this->assertNoFieldByName($field);
    }
  }

  /**
   * Test the 'Authoring information' fieldset.
   */
  function testNodeOptions() {
    $this->admin_user = $this->drupalCreateUser(array('create page content', 'edit any page content', 'override page published option', 'override page promote to front page option', 'override page sticky option'));
    $this->drupalLogin($this->admin_user);

    $fields = array(
      'status' => (bool) !$this->node->status,
      'promote' => (bool) !$this->node->promote,
      'sticky' => (bool) !$this->node->sticky,
    );
    $this->drupalPost('node/' . $this->node->nid . '/edit', $fields, t('Save'));
    $this->assertNodeFieldsUpdated($this->node, $fields);

    $this->drupalLogin($this->normal_user);
    $this->assertNodeFieldsNoAccess($this->node, array_keys($fields));
  }

  /**
   * Test the 'Revision information' fieldset.
   */
  function testNodeRevisions() {
    $this->admin_user = $this->drupalCreateUser(array('create page content', 'edit any page content', 'override page revision option'));
    $this->drupalLogin($this->admin_user);

    $fields = array(
      'revision' => TRUE,
    );
    $this->drupalPost('node/' . $this->node->nid . '/edit', $fields, t('Save'));
    $this->assertNodeFieldsUpdated($this->node, array('vid' => $this->node->vid + 1));

    $this->drupalLogin($this->normal_user);
    $this->assertNodeFieldsNoAccess($this->node, array_keys($fields));
  }

  /**
   * Test the 'Authoring information' fieldset.
   */
  function testNodeAuthor() {
    $this->admin_user = $this->drupalCreateUser(array('create page content', 'edit any page content', 'override page authored on option', 'override page authored by option'));
    $this->drupalLogin($this->admin_user);

    $this->drupalPost('node/' . $this->node->nid . '/edit', array('name' => 'invalid-user'), t('Save'));
    $this->assertText('The username invalid-user does not exist.');

    $this->drupalPost('node/' . $this->node->nid . '/edit', array('date' => 'invalid-date'), t('Save'));
    $this->assertText('You have to specify a valid date.');

    $time = time() + 500;
    $fields = array(
      'name' => '',
      'date' => format_date($time, 'custom', 'Y-m-d H:i:s O'),
    );
    $this->drupalPost('node/' . $this->node->nid . '/edit', $fields, t('Save'));
    $this->assertNodeFieldsUpdated($this->node, array('uid' => 0, 'created' => $time));

    $this->drupalLogin($this->normal_user);
    $this->assertNodeFieldsNoAccess($this->node, array_keys($fields));
  }
}
