Fix #4174: Don't allow invalid prefix combinations for autocomplete.
* Autocorrect duplicated operators (e.g. complete `--tag` as `-tag`). * Don't accept invalid metatag + prefix combinations (e.g. don't complete `char:rating:s` as `rating:safe`).
This commit is contained in:
@@ -10,8 +10,8 @@ Autocomplete.ORDER_METATAGS = <%= Tag::ORDER_METATAGS.to_json.html_safe %>;
|
||||
/* eslint-enable */
|
||||
|
||||
Autocomplete.TAG_PREFIXES = "-|~|" + Object.keys(Autocomplete.TAG_CATEGORIES).map(category => category + ":").join("|");
|
||||
Autocomplete.TAG_PREFIXES_REGEX = new RegExp("^(" + Autocomplete.TAG_PREFIXES + ")(.*)$", "i");
|
||||
Autocomplete.METATAGS_REGEX = new RegExp("^(" + Autocomplete.METATAGS.join("|") + "):(.*)$", "i");
|
||||
Autocomplete.METATAGS_REGEX = Autocomplete.METATAGS.concat(Object.keys(Autocomplete.TAG_CATEGORIES)).join("|");
|
||||
Autocomplete.TERM_REGEX = new RegExp(`([-~]*)(?:(${Autocomplete.METATAGS_REGEX}):)?(\\S*)$`, "i");
|
||||
|
||||
Autocomplete.initialize_all = function() {
|
||||
if (Utility.meta("enable-auto-complete") === "true") {
|
||||
@@ -271,34 +271,14 @@ Autocomplete.normal_source = function(term, resp) {
|
||||
}
|
||||
|
||||
Autocomplete.parse_query = function(text, caret) {
|
||||
var operator = "";
|
||||
var metatag = "";
|
||||
var term = "";
|
||||
let before_caret_text = text.substring(0, caret);
|
||||
let match = before_caret_text.match(Autocomplete.TERM_REGEX);
|
||||
|
||||
var before_caret_text = text.substring(0, caret);
|
||||
var match = before_caret_text.match(/\S+$/g);
|
||||
if (match) {
|
||||
term = match[0];
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
let operator = match[1];
|
||||
let metatag = match[2] ? match[2].toLowerCase() : "tag";
|
||||
let term = match[3];
|
||||
|
||||
match = term.match(/^([-~])(.*)$/);
|
||||
if (match) {
|
||||
operator = match[1];
|
||||
term = match[2];
|
||||
}
|
||||
|
||||
match = term.match(Autocomplete.TAG_PREFIXES_REGEX);
|
||||
if (match) {
|
||||
term = match[2];
|
||||
}
|
||||
|
||||
match = term.match(Autocomplete.METATAGS_REGEX);
|
||||
if (match) {
|
||||
metatag = match[1].toLowerCase();
|
||||
term = match[2];
|
||||
} else {
|
||||
if (metatag in Autocomplete.TAG_CATEGORIES) {
|
||||
metatag = "tag";
|
||||
}
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@ require "test_helper"
|
||||
|
||||
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
||||
include SystemTestHelper
|
||||
driven_by :selenium, using: :firefox, screen_size: [1400, 1400]
|
||||
driven_by :selenium, using: :headless_firefox, screen_size: [1400, 1400]
|
||||
end
|
||||
|
||||
@@ -30,6 +30,12 @@ class AutocompleteTest < ApplicationSystemTestCase
|
||||
assert_autocomplete_equals(values, text, id: "forum_post_body")
|
||||
end
|
||||
|
||||
def assert_inserted_completion(result, query, id: "tags")
|
||||
autocomplete(id, query)
|
||||
first("ul.ui-autocomplete li").click
|
||||
assert_equal(result, find_field(id: id).value)
|
||||
end
|
||||
|
||||
context "Autocomplete" do
|
||||
context "for post searches" do
|
||||
should "work for static metatags" do
|
||||
@@ -85,8 +91,6 @@ class AutocompleteTest < ApplicationSystemTestCase
|
||||
assert_search_autocomplete_equals(["bkub"], "char:bkub")
|
||||
assert_search_autocomplete_equals(["bkub"], "gen:bkub")
|
||||
assert_search_autocomplete_equals(["bkub"], "meta:bkub")
|
||||
assert_search_autocomplete_equals(["bkub"], "-char:bkub")
|
||||
assert_search_autocomplete_equals(["bkub"], "~char:bkub")
|
||||
|
||||
assert_search_autocomplete_equals(["bkub"], "b*")
|
||||
assert_search_autocomplete_equals(["bkub"], "B*")
|
||||
@@ -98,16 +102,38 @@ class AutocompleteTest < ApplicationSystemTestCase
|
||||
assert_search_autocomplete_equals([], "one two")
|
||||
end
|
||||
|
||||
should "correct invalid operator combinations" do
|
||||
create(:tag, name: "bkub", post_count: 42)
|
||||
|
||||
assert_search_autocomplete_equals(["bkub"], "foo ---bkub")
|
||||
assert_search_autocomplete_equals(["bkub"], "foo ~~~bkub")
|
||||
|
||||
assert_search_autocomplete_equals(["rating:safe"], "--rating:s")
|
||||
assert_search_autocomplete_equals(["rating:safe"], "-~rating:s")
|
||||
assert_search_autocomplete_equals(["rating:safe"], "~-rating:s")
|
||||
assert_search_autocomplete_equals(["rating:safe"], "~~rating:s")
|
||||
assert_search_autocomplete_equals(["rating:safe"], "---rating:s")
|
||||
assert_search_autocomplete_equals(["rating:safe"], "~~~rating:s")
|
||||
end
|
||||
|
||||
should "ignore invalid prefix + metatag combinations" do
|
||||
assert_search_autocomplete_equals([], "char:rating:s")
|
||||
end
|
||||
|
||||
should "insert completions on click" do
|
||||
visit posts_path
|
||||
|
||||
autocomplete("tags", "rating:s")
|
||||
first("ul.ui-autocomplete li").click
|
||||
assert_equal("rating:safe ", find_field(id: "tags").value)
|
||||
create(:tag, name: "bkub", post_count: 42)
|
||||
assert_inserted_completion("bkub ", "b")
|
||||
assert_inserted_completion("-bkub ", "-b")
|
||||
assert_inserted_completion("~bkub ", "~b")
|
||||
assert_inserted_completion("tag bkub ", "tag b")
|
||||
assert_inserted_completion("tag char:bkub ", "tag char:b")
|
||||
|
||||
autocomplete("tags", "one two rating:s")
|
||||
first("ul.ui-autocomplete li").click
|
||||
assert_equal("one two rating:safe ", find_field(id: "tags").value)
|
||||
assert_inserted_completion("rating:safe ", "rating:s")
|
||||
assert_inserted_completion("-rating:safe ", "-rating:s")
|
||||
assert_inserted_completion("-rating:safe ", "---rating:s")
|
||||
assert_inserted_completion("tag rating:safe ", "tag rating:s")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user