<?php
/*
 * @file
 * Base class for all biblio tests
 */
class BiblioWebTestCase extends DrupalWebTestCase {
  protected $kids = array();  //keep a list of all keyword id's created
  protected $cids = array();  //keep a list of all contributor id's created
  protected $nids = array();  //keep a list of all node id's created
  protected $admin_user;

//  function tearDown() {
//    if (!empty($this->kids)) {
//      db_delete('biblio_keyword')
//      ->condition('kid', $this->kids, 'IN')
//      ->execute();
//
//      db_delete('biblio_keyword_data')
//      ->condition('kid', $this->kids, 'IN')
//      ->execute();
//
//    }
//
//    foreach ($this->nids as $nid) {
//      node_delete($nid);
//    }
//
//    if (!empty($this->cids)) {
//      db_delete('biblio_contributor')
//      ->condition('cid', $this->cids, 'IN')
//      ->execute();
//
//      db_delete('biblio_contributor_data')
//      ->condition('cid', $this->cids, 'IN')
//      ->execute();
//
//    }
//    $this->cids = array();
//  }


  function createNode($type = 100) {
    $schema = drupal_get_schema('biblio');
    foreach ($schema['fields'] as $name => $values) {
      if ($values['type'] == 'int') continue;
      switch ($values['type']) {
        case 'varchar':
          $length = $values['length'];
          break;
        case 'text':
          $length = 1000;
          break;
      }
      $biblio_fields["$name"] = $name;
    }
    $settings = array(
      'title' => 'Biblio Title',
      'type' => 'biblio', // This replaces the default type
      'biblio_type' => $type, // This appends a new field.
      'biblio_year' => 2009,
      'biblio_contributors' => array(0 => array('name' => 'Ron J. Jeromezzzzzz',  'auth_type' => 1, 'auth_category' => 1),
                                     1 => array('name' => 'John Smithzzzzzz',  'auth_type' => 1, 'auth_category' => 1),
                                     2 => array('name' => 'George W. Bushzzzzzz',  'auth_type' => 1, 'auth_category' => 1)),
      'biblio_keywords' => array('biblio_keywords')
    );
    $settings = array_merge($biblio_fields, $settings);

    $node = $this->drupalCreateNode($settings);
    $node = node_load($node->nid, NULL, TRUE);
    foreach ($node->biblio_contributors as $author) {
      $this->cids[] = $author['cid'];
    }

    $this->nids[] = $node->nid;

    return $node;

  }
  function assertBiblioFields($node1, $node2, $fields = array()) {
    $count = 0;
    foreach ($fields as $field) {
      if ($field == 'biblio_contributors') {
        foreach ($node1->{$field} as $key => $auth) {
          unset($node1->{$field}[$key]['nid']);
          unset($node1->{$field}[$key]['vid']);
        }
        foreach ($node2->{$field} as $key => $auth) {
          unset($node2->{$field}[$key]['nid']);
          unset($node2->{$field}[$key]['vid']);
        }
      }
      if ($node1->$field != $node2->$field) {
        $this->assertIdentical($node1->$field, $node2->$field);
        $count++;
      }
    }
    $this->assertEqual($count, 0, "There were $count differences between the two nodes");
  }
}

class BiblioNodeCreationTestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Biblio node creation',
      'description' => 'Create a biblio node and test saving it.',
      'group' => 'Biblio',
    );
  }

  function setUp() {
    parent::setUp('biblio');
    $web_user = $this->drupalCreateUser(array('create biblio content'));
    $this->drupalLogin($web_user);
  }

  /**
   * Create a biblio node and verify its consistency in the database.
   */
  function testBiblioNodeCreation() {
    // Create a node.
    $edit = array();
    $edit["biblio_type"] = '101';
    $this->drupalPost('node/add/biblio', $edit, t('Next'));

    // Check that the next step of the form appears.
    $this->assertOptionSelected('edit-biblio-type', '101');
    $this->assertFieldById('edit-title');
    $this->assertFieldById('edit-biblio-year');

    $edit = array(
      'title' => $this->randomString(32),
      'biblio_year' => '2009',
      'biblio_contributors[0][name]' => 'Kevin Brown',
      'biblio_contributors[1][name]' => 'Martin Clark',
      'biblio_contributors[2][name]' => 'George Wei',
      'biblio_keywords' => 'architecture, building, wood',
    );
    $this->drupalPost(NULL, $edit, t('Save'));

    // Check that the Basic page has been created.
    $this->assertRaw(t('!post %title has been created.', array('!post' => 'Biblio', '%title' => $edit["title"])), t('Biblio entry created.'));
    // Check that the node exists in the database.
    $node = $this->drupalGetNodeByTitle($edit['title']);

    $keywordstring = implode(', ', $node->biblio_keywords);
    $this->assertIdentical($keywordstring, 'architecture, building, wood', t('Keywords are present on the biblio node.'));
    $this->assertTrue($node, t('Node found in database.'));
  }
}

class BiblioPageViewTestCase extends BiblioWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Biblio node view and edit permissions',
      'description' => 'Create a biblio node and test view / edit permissions.',
      'group' => 'Biblio',
    );
  }

  function setUp() {
    parent::setUp('biblio');
  }

  /**
   * Creates a node and then an anonymous and unpermissioned user attempt to edit the node.
   */
  function testBiblioPageView() {
    // Create a node to view.
    $node = $this->createNode('101');
    $this->assertTrue(node_load($node->nid), t('Node created.'));

    // Try to edit with anonymous user.
    $html = $this->drupalGet("node/$node->nid/edit");
    $this->assertResponse(403);

    // Create a user without permission to edit node.
    $web_user = $this->drupalCreateUser(array('access content'));
    $this->drupalLogin($web_user);

    // Attempt to access edit page.
    $this->drupalGet("node/$node->nid/edit");
    $this->assertResponse(403);

    // Create user with permission to edit node.
    $web_user = $this->drupalCreateUser(array('edit any biblio content'));
    $this->drupalLogin($web_user);

    // Attempt to access edit page.
    $this->drupalGet("node/$node->nid/edit");
    $this->assertResponse(200);
  }
}
