<?php

/**
 * @file
 * Administration menu functionality tests.
 *
 * Note: When using $this->assertPattern(), be sure to use the 's' modifier for
 * the PCRE pattern, since admin menu's output spans over multiple lines.
 */


/**
 * Test menu links depending on user permissions.
 */
class AdminMenuPermissionsTestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => t('Menu link permissions'),
      'description' => t('Verify that menu is displayed according to user permissions.'),
      'group' => t('Administration menu'),
    );
  }

  function setUp() {
    parent::setUp('admin_menu');
    admin_menu_exit();
  }

  /**
   * Test that the links are added to the page (no JS testing).
   */
  function testPermissions() {
    // Anonymous users should not see the menu.
    $this->assertNoRaw('<div id="admin-menu"', t('Admin menu not displayed to anonymous.'));

    // Create a new user who can access administration menu, but without the
    // permission 'display drupal links'.
    $admin_user = $this->drupalCreateUser(array('administer site configuration', 'access administration pages', 'administer nodes', 'access administration menu'));
    $this->drupalLogin($admin_user);

    // Check that the user can see the admin links, but not the drupal links.
    $this->assertRaw('<div id="admin-menu"', t('Administration menu is displayed.'));
    $this->drupalGet('node');
    $this->assertPattern('@<div id="admin-menu".*admin/content/node@s', t('Administer content link found.'));
    $this->assertNoPattern('@<div id="admin-menu".*http://drupal.org@s', t('Drupal links not found.'));
    $this->assertNoPattern('@<div id="admin-menu".*admin/build/contact@s', t('Contact module link not found.'));

    // Create a new user with the permission 'display drupal links'.
    $admin_user2 = $this->drupalCreateUser(array('administer site configuration', 'access administration pages', 'administer nodes', 'access administration menu', 'display drupal links'));
    $this->drupalLogin($admin_user2);
    $this->drupalGet('node');
    $this->assertPattern('@<div id="admin-menu".*http://drupal.org@s', t('Drupal links found.'));
    $this->assertNoPattern('@<div id="admin-menu".*admin/build/contact@s', t('Contact module link not found.'));
  }
}

/**
 * Test menu links depending on installed modules.
 */
class AdminMenuModulesTestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => t('Module menu links'),
      'description' => t('Verify that menu contains links according to enabled modules.'),
      'group' => t('Administration menu'),
    );
  }

  function setUp() {
    parent::setUp('admin_menu', 'contact');
    admin_menu_exit();
  }

  /**
   * Test that the links are added to the page (no JS testing).
   */
  function testContactModuleLinks() {
    // Create a new user without 'administer site-wide contact form' permission.
    $admin_user = $this->drupalCreateUser(array('access administration pages', 'access administration menu'));
    $this->drupalLogin($admin_user);

    // Verify that proper links are displayed.
    $this->assertRaw('<div id="admin-menu"', t('Administration menu is displayed.'));
    $this->drupalGet('node');
    $this->assertNoPattern('@<div id="admin-menu".*admin/build/contact@s', t('Contact module link not found.'));

    // Create a new user with 'administer site-wide contact form' permission.
    $admin_user = $this->drupalCreateUser(array('access administration pages', 'access administration menu', 'administer site-wide contact form'));
    $this->drupalLogin($admin_user);

    // Verify that proper links are displayed.
    $this->drupalGet('node');
    $this->assertPattern('@<div id="admin-menu".*admin/build/contact@s', t('Contact module link found.'));
  }
}

/**
 * Test contained links in administration menu.
 */
class AdminMenuLinksTestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => t('Menu links'),
      'description' => t('Verify that menu contains proper links.'),
      'group' => t('Administration menu'),
    );
  }

  function setUp() {
    parent::setUp('admin_menu');
    admin_menu_exit();
    // Create and log in a full-blown administrative user.
    $permissions = module_invoke_all('perm');
    $admin_user = $this->drupalCreateUser($permissions);
    $this->admin_user = $this->drupalLogin($admin_user);
  }

  /**
   * Test link contents.
   */
  function testLinkContents() {
    // Create a content-type with special characters.
    $info = array(
      'type' => 'special',
      'name' => 'Cool & Special',
      'module' => 'node',
      'description' => '',
    );
    $info = (object)_node_type_set_defaults($info);
    node_type_save($info);
    $this->drupalPost('admin/settings/performance', array(), t('Clear cached data'));

    // Fetch a page.
    $this->drupalGet('node');
    $this->assertRaw('<div id="admin-menu"', t('Administration menu is displayed.'));

    // Verify that proper links are displayed.
    // We are explicitly NOT using t() here, since the purpose is to test our
    // custom link titles and 't' option.
    $links = array(
      url('admin/content/node-type/page') => strtr('Edit !content-type', array('!content-type' => t('Page'))),
      url('admin/content/node-type/special') => strtr('Edit !content-type', array('!content-type' => t('Cool & Special'))),
    );
    foreach ($links as $url => $title) {
      $this->assertFieldByXPath('//div[@id="admin-menu"]//a[@href="' . $url . '"]', $title, t('!link-title content-type link found.', array('!link-title' => $title)));
    }
    $links = array(
      url('node/add/page') => t('Page'),
      url('node/add/special') => t('Cool & Special'),
    );
    foreach ($links as $url => $title) {
      $this->assertFieldByXPath('//div[@id="admin-menu"]//a[@href="' . $url . '"]', $title, t('Create content &raquo; !link-title link found.', array('!link-title' => $title)));
    }
  }
}

