diff -u b/misc/autocomplete.js b/misc/autocomplete.js --- b/misc/autocomplete.js +++ b/misc/autocomplete.js @@ -287,7 +287,8 @@ this.timer = setTimeout(function () { db.owner.setStatus('begin'); - // Ajax GET request for autocompletion. + // Ajax GET request for autocompletion. We use Drupal.encodePath instead of + // encodeURIComponent to allow autocomplete search terms to contain slashes. $.ajax({ type: 'GET', url: db.uri + '/' + Drupal.encodePath(searchString), diff -u b/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module --- b/modules/taxonomy/taxonomy.module +++ b/modules/taxonomy/taxonomy.module @@ -312,6 +312,7 @@ 'type' => MENU_CALLBACK, 'file' => 'taxonomy.pages.inc', ); + // We append /%menu_tail so the search text may contain slashes. $items['taxonomy/autocomplete/%/%menu_tail'] = array( 'title' => 'Autocomplete taxonomy', 'page callback' => 'taxonomy_autocomplete', @@ -322,9 +323,10 @@ // Needed for menu_tail_load(). 'load arguments' => array('%map', '%index'), ); - // This is needed because the autocomplete system relies on this path existing. - // See: http://drupal.org/node/93854 - $items['taxonomy/autocomplete'] = array( + // This matches the vocabulary name without any search text. Even though this + // path is never called, its existence is checked by theme_textfield() and + // tested in ProfileTestAutocomplete. + $items['taxonomy/autocomplete/%'] = array( 'title' => 'Autocomplete taxonomy', 'page callback' => 'taxonomy_autocomplete', 'access arguments' => array('access content'), diff -u b/modules/taxonomy/taxonomy.test b/modules/taxonomy/taxonomy.test --- b/modules/taxonomy/taxonomy.test +++ b/modules/taxonomy/taxonomy.test @@ -641,24 +641,38 @@ } /** - * Test term autocompletion edge cases. + * Test term autocompletion edge cases with slashes in the names. */ function testTermAutocompletion() { - $base = $this->randomName(2); // Add a term with a slash in the name. - $term = $this->createTerm($this->vocabulary); - $term->name = $base . '/' . $this->randomName(); - taxonomy_term_save($term); - // Add a term with a slash in the name. - $term = $this->createTerm($this->vocabulary); - $term->name = $base . '/' . $this->randomName(); - taxonomy_term_save($term); + $first_term = $this->createTerm($this->vocabulary); + $first_term->name = '10/16/2011'; + taxonomy_term_save($first_term); + // Add another term that differs after the slash character. + $second_term = $this->createTerm($this->vocabulary); + $second_term->name = '10/17/2011'; + taxonomy_term_save($second_term); + + // Try to autocomplete a term name that matches both terms. + // We should get both term in a json encoded string. + $input = '10/'; + $path = 'taxonomy/autocomplete/taxonomy_'; + $path .= $this->vocabulary->machine_name . '/' . $input; + // The result order is not guaranteed, so check each term separately. + $url = url($path, array('absolute' => TRUE)); + $result = drupal_http_request($url); + $data = drupal_json_decode($result->data); + $this->assertEqual($data[$first_term->name], check_plain($first_term->name), t('Autocomplete returned the first matching term')); + $this->assertEqual($data[$second_term->name], check_plain($second_term->name), t('Autocomplete returned the second matching term')); - // Try to autocomplete the term name, that contains a slash. - // We should only get a single term returned. - $input = substr($term->name, 0, 5); - $this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->machine_name . '/' . $input); - $this->assertRaw(drupal_json_encode(array($term->name => check_plain($term->name))), t('Autocomplete returns term %term_name after typing the first 4 letters, including a slash in the name.', array('%term_name' => $term->name))); + // Try to autocomplete a term name that matches 1st term. + // We should only get the first term in a json encoded string. + $input = '10/16'; + $url = 'taxonomy/autocomplete/taxonomy_'; + $url .= $this->vocabulary->machine_name . '/' . $input; + $this->drupalGet($url); + $target = array($first_term->name => check_plain($first_term->name)); + $this->assertRaw(drupal_json_encode($target), t('Autocomplete returns only the expected matching term.')); } /**