DEV: Remove enable_experimental_hashtag_autocomplete logic (#22820)

This commit removes any logic in the app and in specs around
enable_experimental_hashtag_autocomplete and deletes some
old category hashtag code that is no longer necessary.

It also adds a `slug_ref` category instance method, which
will generate a reference like `parent:child` for a category,
with an optional depth, which hashtags use. Also refactors
PostRevisor which was using CategoryHashtagDataSource directly
which is a no-no.

Deletes the old hashtag markdown rule as well.
This commit is contained in:
Martin Brennan
2023-08-08 11:18:55 +10:00
committed by GitHub
parent 0c88bf341a
commit 09223e5ae7
43 changed files with 310 additions and 1001 deletions
+163 -284
View File
@@ -20,305 +20,184 @@ RSpec.describe HashtagsController do
end
describe "#lookup" do
context "when enable_experimental_hashtag_autocomplete disabled" do
# TODO (martin) Remove when enable_experimental_hashtag_autocomplete is default for all sites
before { SiteSetting.enable_experimental_hashtag_autocomplete = false }
context "when logged in" do
context "as regular user" do
before { sign_in(Fabricate(:user)) }
context "when logged in" do
context "as regular user" do
before { sign_in(Fabricate(:user)) }
it "returns only valid categories and tags" do
get "/hashtags.json",
params: {
slugs: [category.slug, private_category.slug, "none", tag.name, hidden_tag.name],
}
it "returns only valid categories and tags" do
get "/hashtags.json",
params: {
slugs: [category.slug, private_category.slug, "none", tag.name, hidden_tag.name],
order: %w[category tag],
}
expect(response.status).to eq(200)
expect(response.parsed_body).to eq(
"categories" => {
category.slug => category.url,
},
"tags" => {
tag.name => tag.full_url,
},
)
end
it "handles tags with the TAG_HASHTAG_POSTFIX" do
get "/hashtags.json",
params: {
slugs: ["#{tag.name}#{PrettyText::Helpers::TAG_HASHTAG_POSTFIX}"],
}
expect(response.status).to eq(200)
expect(response.parsed_body).to eq(
"categories" => {
},
"tags" => {
tag.name => tag.full_url,
},
)
end
it "does not return restricted categories or hidden tags" do
get "/hashtags.json", params: { slugs: [private_category.slug, hidden_tag.name] }
expect(response.status).to eq(200)
expect(response.parsed_body).to eq("categories" => {}, "tags" => {})
end
expect(response.status).to eq(200)
expect(response.parsed_body).to eq(
{
"category" => [
{
"relative_url" => category.url,
"text" => category.name,
"description" => nil,
"icon" => "folder",
"type" => "category",
"ref" => category.slug,
"slug" => category.slug,
"id" => category.id,
},
],
"tag" => [
{
"relative_url" => tag.url,
"text" => tag.name,
"description" => nil,
"icon" => "tag",
"type" => "tag",
"ref" => tag.name,
"slug" => tag.name,
"secondary_text" => "x0",
"id" => tag.id,
},
],
},
)
end
context "as admin" do
fab!(:admin) { Fabricate(:admin) }
it "handles tags with the ::tag type suffix" do
get "/hashtags.json", params: { slugs: ["#{tag.name}::tag"], order: %w[category tag] }
before { sign_in(admin) }
it "returns restricted categories and hidden tags" do
group.add(admin)
get "/hashtags.json", params: { slugs: [private_category.slug, hidden_tag.name] }
expect(response.status).to eq(200)
expect(response.parsed_body).to eq(
"categories" => {
private_category.slug => private_category.url,
},
"tags" => {
hidden_tag.name => hidden_tag.full_url,
},
)
end
expect(response.status).to eq(200)
expect(response.parsed_body).to eq(
{
"category" => [],
"tag" => [
{
"relative_url" => tag.url,
"text" => tag.name,
"description" => nil,
"icon" => "tag",
"type" => "tag",
"ref" => "#{tag.name}::tag",
"slug" => tag.name,
"secondary_text" => "x0",
"id" => tag.id,
},
],
},
)
end
context "with sub-sub-categories" do
before do
SiteSetting.max_category_nesting = 3
sign_in(Fabricate(:user))
end
it "does not return restricted categories or hidden tags" do
get "/hashtags.json",
params: {
slugs: [private_category.slug, hidden_tag.name],
order: %w[category tag],
}
it "works" do
foo = Fabricate(:category_with_definition, slug: "foo")
foobar = Fabricate(:category_with_definition, slug: "bar", parent_category_id: foo.id)
foobarbaz =
Fabricate(:category_with_definition, slug: "baz", parent_category_id: foobar.id)
qux = Fabricate(:category_with_definition, slug: "qux")
quxbar = Fabricate(:category_with_definition, slug: "bar", parent_category_id: qux.id)
quxbarbaz =
Fabricate(:category_with_definition, slug: "baz", parent_category_id: quxbar.id)
invalid_slugs = [":"]
child_slugs = %w[bar baz]
deeply_nested_slugs = %w[foo:bar:baz qux:bar:baz]
get "/hashtags.json",
params: {
slugs:
invalid_slugs + child_slugs + deeply_nested_slugs +
%w[foo foo:bar bar:baz qux qux:bar],
}
expect(response.status).to eq(200)
expect(response.parsed_body["categories"]).to eq(
"foo" => foo.url,
"foo:bar" => foobar.url,
"bar:baz" => foobarbaz.id < quxbarbaz.id ? foobarbaz.url : quxbarbaz.url,
"qux" => qux.url,
"qux:bar" => quxbar.url,
)
end
expect(response.status).to eq(200)
expect(response.parsed_body).to eq({ "category" => [], "tag" => [] })
end
end
context "when not logged in" do
it "returns invalid access" do
get "/hashtags.json", params: { slugs: [] }
expect(response.status).to eq(403)
context "as admin" do
fab!(:admin) { Fabricate(:admin) }
before { sign_in(admin) }
it "returns restricted categories and hidden tags" do
group.add(admin)
get "/hashtags.json",
params: {
slugs: [private_category.slug, hidden_tag.name],
order: %w[category tag],
}
expect(response.status).to eq(200)
expect(response.parsed_body).to eq(
{
"category" => [
{
"relative_url" => private_category.url,
"text" => private_category.name,
"description" => nil,
"icon" => "folder",
"type" => "category",
"ref" => private_category.slug,
"slug" => private_category.slug,
"id" => private_category.id,
},
],
"tag" => [
{
"relative_url" => hidden_tag.url,
"text" => hidden_tag.name,
"description" => nil,
"icon" => "tag",
"type" => "tag",
"ref" => hidden_tag.name,
"slug" => hidden_tag.name,
"secondary_text" => "x0",
"id" => hidden_tag.id,
},
],
},
)
end
end
context "with sub-sub-categories" do
before do
SiteSetting.max_category_nesting = 3
sign_in(Fabricate(:user))
end
it "works" do
foo = Fabricate(:category_with_definition, slug: "foo")
foobar = Fabricate(:category_with_definition, slug: "bar", parent_category_id: foo.id)
foobarbaz =
Fabricate(:category_with_definition, slug: "baz", parent_category_id: foobar.id)
qux = Fabricate(:category_with_definition, slug: "qux")
quxbar = Fabricate(:category_with_definition, slug: "bar", parent_category_id: qux.id)
quxbarbaz =
Fabricate(:category_with_definition, slug: "baz", parent_category_id: quxbar.id)
invalid_slugs = [":"]
child_slugs = %w[bar baz]
deeply_nested_slugs = %w[foo:bar:baz qux:bar:baz]
get "/hashtags.json",
params: {
slugs:
invalid_slugs + child_slugs + deeply_nested_slugs +
%w[foo foo:bar bar:baz qux qux:bar],
order: %w[category tag],
}
expect(response.status).to eq(200)
found_categories = response.parsed_body["category"]
expect(found_categories.map { |c| c["ref"] }).to match_array(
%w[foo foo:bar bar:baz qux qux:bar],
)
expect(found_categories.find { |c| c["ref"] == "foo" }["relative_url"]).to eq(foo.url)
expect(found_categories.find { |c| c["ref"] == "foo:bar" }["relative_url"]).to eq(
foobar.url,
)
expect(found_categories.find { |c| c["ref"] == "bar:baz" }["relative_url"]).to eq(
foobarbaz.url,
)
expect(found_categories.find { |c| c["ref"] == "qux" }["relative_url"]).to eq(qux.url)
expect(found_categories.find { |c| c["ref"] == "qux:bar" }["relative_url"]).to eq(
quxbar.url,
)
end
end
end
context "when enable_experimental_hashtag_autocomplete enabled" do
before { SiteSetting.enable_experimental_hashtag_autocomplete = true }
context "when logged in" do
context "as regular user" do
before { sign_in(Fabricate(:user)) }
it "returns only valid categories and tags" do
get "/hashtags.json",
params: {
slugs: [category.slug, private_category.slug, "none", tag.name, hidden_tag.name],
order: %w[category tag],
}
expect(response.status).to eq(200)
expect(response.parsed_body).to eq(
{
"category" => [
{
"relative_url" => category.url,
"text" => category.name,
"description" => nil,
"icon" => "folder",
"type" => "category",
"ref" => category.slug,
"slug" => category.slug,
"id" => category.id,
},
],
"tag" => [
{
"relative_url" => tag.url,
"text" => tag.name,
"description" => nil,
"icon" => "tag",
"type" => "tag",
"ref" => tag.name,
"slug" => tag.name,
"secondary_text" => "x0",
"id" => tag.id,
},
],
},
)
end
it "handles tags with the ::tag type suffix" do
get "/hashtags.json", params: { slugs: ["#{tag.name}::tag"], order: %w[category tag] }
expect(response.status).to eq(200)
expect(response.parsed_body).to eq(
{
"category" => [],
"tag" => [
{
"relative_url" => tag.url,
"text" => tag.name,
"description" => nil,
"icon" => "tag",
"type" => "tag",
"ref" => "#{tag.name}::tag",
"slug" => tag.name,
"secondary_text" => "x0",
"id" => tag.id,
},
],
},
)
end
it "does not return restricted categories or hidden tags" do
get "/hashtags.json",
params: {
slugs: [private_category.slug, hidden_tag.name],
order: %w[category tag],
}
expect(response.status).to eq(200)
expect(response.parsed_body).to eq({ "category" => [], "tag" => [] })
end
end
context "as admin" do
fab!(:admin) { Fabricate(:admin) }
before { sign_in(admin) }
it "returns restricted categories and hidden tags" do
group.add(admin)
get "/hashtags.json",
params: {
slugs: [private_category.slug, hidden_tag.name],
order: %w[category tag],
}
expect(response.status).to eq(200)
expect(response.parsed_body).to eq(
{
"category" => [
{
"relative_url" => private_category.url,
"text" => private_category.name,
"description" => nil,
"icon" => "folder",
"type" => "category",
"ref" => private_category.slug,
"slug" => private_category.slug,
"id" => private_category.id,
},
],
"tag" => [
{
"relative_url" => hidden_tag.url,
"text" => hidden_tag.name,
"description" => nil,
"icon" => "tag",
"type" => "tag",
"ref" => hidden_tag.name,
"slug" => hidden_tag.name,
"secondary_text" => "x0",
"id" => hidden_tag.id,
},
],
},
)
end
end
context "with sub-sub-categories" do
before do
SiteSetting.max_category_nesting = 3
sign_in(Fabricate(:user))
end
it "works" do
foo = Fabricate(:category_with_definition, slug: "foo")
foobar = Fabricate(:category_with_definition, slug: "bar", parent_category_id: foo.id)
foobarbaz =
Fabricate(:category_with_definition, slug: "baz", parent_category_id: foobar.id)
qux = Fabricate(:category_with_definition, slug: "qux")
quxbar = Fabricate(:category_with_definition, slug: "bar", parent_category_id: qux.id)
quxbarbaz =
Fabricate(:category_with_definition, slug: "baz", parent_category_id: quxbar.id)
invalid_slugs = [":"]
child_slugs = %w[bar baz]
deeply_nested_slugs = %w[foo:bar:baz qux:bar:baz]
get "/hashtags.json",
params: {
slugs:
invalid_slugs + child_slugs + deeply_nested_slugs +
%w[foo foo:bar bar:baz qux qux:bar],
order: %w[category tag],
}
expect(response.status).to eq(200)
found_categories = response.parsed_body["category"]
expect(found_categories.map { |c| c["ref"] }).to match_array(
%w[foo foo:bar bar:baz qux qux:bar],
)
expect(found_categories.find { |c| c["ref"] == "foo" }["relative_url"]).to eq(foo.url)
expect(found_categories.find { |c| c["ref"] == "foo:bar" }["relative_url"]).to eq(
foobar.url,
)
expect(found_categories.find { |c| c["ref"] == "bar:baz" }["relative_url"]).to eq(
foobarbaz.url,
)
expect(found_categories.find { |c| c["ref"] == "qux" }["relative_url"]).to eq(qux.url)
expect(found_categories.find { |c| c["ref"] == "qux:bar" }["relative_url"]).to eq(
quxbar.url,
)
end
end
end
context "when not logged in" do
it "returns invalid access" do
get "/hashtags.json", params: { slugs: [], order: %w[category tag] }
expect(response.status).to eq(403)
end
context "when not logged in" do
it "returns invalid access" do
get "/hashtags.json", params: { slugs: [], order: %w[category tag] }
expect(response.status).to eq(403)
end
end
end