? modules/shortcut/.DS_Store
? sites/all/modules/devel
? sites/default/files
? sites/default/private
? sites/default/settings.php
Index: modules/shortcut/shortcut.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/shortcut/shortcut.info,v
retrieving revision 1.3
diff -u -p -r1.3 shortcut.info
--- modules/shortcut/shortcut.info	19 Feb 2010 10:36:12 -0000	1.3
+++ modules/shortcut/shortcut.info	28 Feb 2010 21:29:52 -0000
@@ -7,4 +7,5 @@ core = 7.x
 files[] = shortcut.module
 files[] = shortcut.admin.inc
 files[] = shortcut.install
+files[] = shortcut.test
 configure = admin/config/user-interface/shortcut
Index: modules/shortcut/shortcut.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/shortcut/shortcut.module,v
retrieving revision 1.23
diff -u -p -r1.23 shortcut.module
--- modules/shortcut/shortcut.module	25 Feb 2010 15:58:54 -0000	1.23
+++ modules/shortcut/shortcut.module	28 Feb 2010 21:29:52 -0000
@@ -328,7 +328,7 @@ function shortcut_set_load($set_name) {
  *   - 'title': The title of the shortcut set.
  *   - 'set_name': (optional) The internal name of the shortcut set. If
  *     omitted, a new shortcut set will be created, and the 'set_name' property
- *     will be added to the passed-in array.
+ *     will be added to the passed-in object.
  *   - 'links': (optional) An array of menu links to save for the shortcut set.
  *     Each link is an array containing at least the following keys (which will
  *     be expanded to fill in other default values after the shortcut set is
Index: modules/shortcut/shortcut.test
===================================================================
RCS file: modules/shortcut/shortcut.test
diff -N modules/shortcut/shortcut.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/shortcut/shortcut.test	28 Feb 2010 21:29:52 -0000
@@ -0,0 +1,288 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Tests for the shortcut module.
+ */
+
+/**
+ * Defines shortcut test cases.
+ */
+class ShortcutTestCase extends DrupalWebTestCase {
+
+  protected $admin_user;
+  protected $shortcut_user;
+  protected $node;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Shortcut functionality',
+      'description' => 'Create, view, edit, delete, and change shortcuts and shortcut sets and verify their functionality.',
+      'group' => 'Shortcut',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('menu', 'toolbar', 'shortcut');
+    // Create users.
+    $this->admin_user = $this->drupalCreateUser(array('access toolbar', 'administer shortcuts', 'customize shortcut links', 'switch shortcut sets', 'administer site configuration', 'access content', 'create article content', 'create page content', 'edit any article content'));
+    $this->shortcut_user = $this->drupalCreateUser(array('access toolbar', 'customize shortcut links', 'switch shortcut sets', 'administer site configuration', 'access content', 'administer nodes', 'edit any article content'));
+    // Create a node.
+    $this->node = $this->drupalCreateNode(array('type' => 'article'));
+    // Log in as admin and grab the default shortcut set.
+    $this->drupalLogin($this->admin_user);
+    $this->set = shortcut_set_load('shortcut-set-1');
+    shortcut_set_assign_user($this->set, $this->admin_user);
+  }
+
+  /**
+   * Create a generic shortcut set.
+   */
+  function generateShortcutSet($title = '', $default_links = TRUE) {
+    $set = new stdClass;
+    $set->title = empty($title) ? $this->randomName(10) : $title;
+    if ($default_links){
+      $set->links = array();
+      $set->links[] = $this->generateShortcutLink('node/add');
+      $set->links[] = $this->generateShortcutLink('admin/content');
+    }
+    shortcut_set_save($set);
+
+    return $set;
+  }
+
+  /**
+   * Create a generic shortcut link.
+   */
+  function generateShortcutLink($path, $title = '') {
+    $link = array(
+      'link_path' => $path,
+      'link_title' => !empty($title) ? $title : $this->randomName(10),
+    );
+
+    return $link;
+  }
+
+  /**
+   * Return an array of mlids withint the given set.
+   */
+  function getShortcutIds($set) {
+    $mlids = array();
+    foreach ($set->links as $link) {
+      $mlids[] = $link['mlid'];
+    }
+    return $mlids;
+  }
+}
+
+class ShortcutLinksTestCase extends ShortcutTestCase {
+
+  protected $set;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Shortcut link functionality',
+      'description' => 'Create, view, edit, delete, and change shortcut links.',
+      'group' => 'Shortcut',
+    );
+  }
+
+  function setUp(){
+    parent::setUp();
+  }
+
+  /**
+   * Check that creating a shortcut works properly.
+   */
+  function testShortcutLinkAdd() {
+    $set = $this->set;
+
+    // @todo: add more paths to check.
+    $test_cases = array(
+      array('path' => 'admin'),
+      array('path' => 'admin/config/system/site-information'),
+      array('path' => "node/{$this->node->nid}/edit"),
+      // @todo: shortcuts to paths with query strings do not get added properly yet.
+      // see http://drupal.org/node/711448.
+    );
+
+    // Check that once each test case is added as a shortcut,
+    // that the shortcut links where it should.
+    foreach ($test_cases as $test){
+      $title = $this->randomName(10);
+      $form_data = array(
+        'shortcut_link[link_title]' => $title,
+        'shortcut_link[link_path]'  => $test['path']
+      );
+      $this->drupalPost('admin/config/user-interface/shortcut/'. $set->set_name .'/add-link', $form_data, t('Save'), isset($test['options']) ? $test['options'] : array());
+      $this->assertResponse(200);
+      $this->assertLink($title, 0, 'Shortcut created: '. $test['path']);
+    }
+  }
+
+  /**
+   * Check that the "add to shortcut" link changes to
+   * "remove shortcut" when appropriate.
+   */
+  function testShortcutQuickLink() {
+    $this->drupalGet($this->set->links[0]['link_path']);
+    $this->assertRaw(t('Remove from %title shortcuts', array('%title' => $this->set->title)), '"Add to shortcuts" link properly switched to "Remove from shortcuts".');
+  }
+
+  /**
+   * Check that shortcut links can be renamed.
+   */
+  function testShortcutLinkRename() {
+    $set = $this->set;
+
+    // Attempt to rename shortcut link.
+    $new_link_name = $this->randomName(10);
+
+    $this->drupalPost('admin/config/user-interface/shortcut/link/'. $set->links[0]['mlid'], array('shortcut_link[link_title]' => $new_link_name, 'shortcut_link[link_path]' => $set->links[0]['link_path']), t('Save'));
+    $this->assertLink($new_link_name, 0, 'Shortcut renamed: '. $new_link_name);
+  }
+
+  /**
+   * Check that changing path of shortcut link works.
+   */
+  function testShortcutLinkChangePath() {
+    $set = $this->set;
+
+    // Attempt to change a shortcut path.
+    $new_link_path = 'admin/config';
+
+    $this->drupalPost('admin/config/user-interface/shortcut/link/'. $set->links[0]['mlid'], array('shortcut_link[link_title]' => $set->links[0]['link_title'], 'shortcut_link[link_path]' => $new_link_path), t('Save'));
+    $this->assertLinkByHref($new_link_path, 0, 'Shortcut path changed: '. $new_link_path);
+  }
+
+  /**
+   * Attempt to delete a shortcut link.
+   */
+  function testShortcutLinkDelete() {
+    $set = $this->set;
+
+    $this->drupalPost('admin/config/user-interface/shortcut/link/'. $set->links[0]['mlid'] .'/delete', array(), 'Delete');
+    $saved_set = shortcut_set_load($set->set_name);
+    $mlids = array();
+    foreach($saved_set->links as $link) {
+      $mlids[] = $link['mlid'];
+    }
+    $this->assertFalse(in_array($set->links[0]['mlid'], $mlids), 'Successfully deleted a shortcut.');
+  }
+
+  //@todo: check that you cant add shortcuts on stupid pages (ex. confirmation page when deleting a shortcut).
+  //@todo: check that you cannot add a shortcut that already exists once that is possible.
+
+}
+
+class ShortcutSetsTestCase extends ShortcutTestCase {
+
+  protected $set;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Shortcut Set functionality',
+      'description' => 'Create, view, edit, delete, and change shortcut sets.',
+      'group' => 'Shortcut',
+    );
+  }
+
+  function setUp(){
+    parent::setUp();
+  }
+
+  /**
+   * Attempt to create a shortcut set.
+   */
+  function testSortcutSetAdd() {
+    $new_set = $this->generateShortcutSet($this->randomName(10));
+    $sets = shortcut_sets();
+    $this->assertTrue(isset($sets[$new_set->set_name]), 'Successfully created a shortcut set.');
+    $this->drupalGet('user/'. $this->admin_user->uid .'/shortcuts');
+    $this->assertText($new_set->title, 'Generated shortcut set was listed as choice.');
+  }
+
+  /**
+   * Attempt to switch a user's own shortcut set.
+   */
+  function testShortcutSetSwtichOwn() {
+    $new_set = $this->generateShortcutSet($this->randomName(10));
+
+    // Attempt to switch the default shortcut set to the newly created shortcut set.
+    $this->drupalPost('user/'. $this->admin_user->uid .'/shortcuts', array('set' => $new_set->set_name), t('Change set'));
+    $this->assertResponse(200);
+    $current_set = shortcut_current_displayed_set($this->admin_user);
+    $this->assertTrue($new_set->set_name == $current_set->set_name, 'Successfully switched default shortcut set.');
+  }
+
+  /**
+   * Attempt to switch another user's shortcut set.
+   */
+  function testShortcutSetAssign() {
+    $new_set = $this->generateShortcutSet($this->randomName(10));
+
+    shortcut_set_assign_user($new_set, $this->shortcut_user);
+    $this->drupalPost('user/'. $this->shortcut_user->uid .'/shortcuts', array('set' => $new_set->set_name), t('Change set'));
+    $this->drupalLogin($this->shortcut_user);
+    $current_set = shortcut_current_displayed_set($this->shortcut_user);
+    $this->assertTrue($new_set->set_name == $current_set->set_name, "Successfully switched another user's shortcut set.");
+  }
+
+  /**
+   * Check that shortcut_set_save correctly updates existing
+   * links and properly deletes unused links. 
+   * See http://drupal.org/node/609122#comment-2488694.
+   */
+  function testShortcutSetSave() {
+    $set = $this->set;
+    $old_mlids = $this->getShortcutIds($set);
+
+    /* 
+    @todo: Currently shortcut_set_save() does not handle deleted links
+           so the code below fails.
+    $link = array_pop($set->links);
+    $deleted_mlid = $link['mlid'];
+    shortcut_set_save($set);
+    $saved_set = shortcut_set_load($set->set_name);
+    */
+
+    $set->links[] = $this->generateShortcutLink('admin', $this->randomName(10));
+    shortcut_set_save($set);
+    $saved_set = shortcut_set_load($set->set_name);
+
+    $new_mlids = $this->getShortcutIds($saved_set);
+    $this->assertTrue(count(array_intersect($old_mlids, $new_mlids)) == count($old_mlids), 'shortcut_set_save() did not inadvertently change existing mlids.');
+  }
+
+  /**
+   * Attempt to rename a shortcut set.
+   */
+  function testShortcutSetRename() {
+    $set = $this->set;
+    
+    $new_title = $this->randomName(10);
+    $this->drupalPost('admin/config/user-interface/shortcut/'. $set->set_name .'/edit', array('title' => $new_title), t('Save'));
+    $set = shortcut_set_load($set->set_name);
+    $this->assertTrue($set->title == $new_title, 'Shortcut set has been successfully renamed.');
+  }
+
+  /**
+   * Attempt to delete a shortcut set.
+   */
+  function testShortcutSetDelete() {
+    $new_set = $this->generateShortcutSet($this->randomName(10));
+
+    $this->drupalPost('admin/config/user-interface/shortcut/'. $new_set->set_name .'/delete', array(), t('Delete'));
+    $sets = shortcut_sets();
+    $this->assertFalse(isset($sets[$new_set->set_name]), 'Successfully deleted a shortcut set.');
+  }
+
+  /**
+   * Attempt to delete the defailt shortcut set.
+   */
+  function testShortcutSetDeleteDefault() {
+    $this->drupalGet('admin/config/user-interface/shortcut/shortcut-set-1/delete');
+    $this->assertResponse(403);
+  }
+}
