FIX: Clashing category slug.

This commit is contained in:
Guo Xiang Tan 2016-01-12 16:40:36 +08:00
parent 65e808b26d
commit c60e360c90
10 changed files with 65 additions and 14 deletions

View file

@ -255,7 +255,7 @@ export default Ember.Component.extend({
template: template, template: template,
key: '#', key: '#',
transformComplete(category) { transformComplete(category) {
return category.get('slug'); return Category.slugFor(category, ":");
}, },
dataSource(term) { dataSource(term) {
return Category.search(term); return Category.search(term);

View file

@ -4,7 +4,7 @@
**/ **/
Discourse.Dialect.inlineRegexp({ Discourse.Dialect.inlineRegexp({
start: '#', start: '#',
matcher: /^#([\w-]{1,50})/i, matcher: /^#([\w-:]{1,50})/i,
spaceOrTagBoundary: true, spaceOrTagBoundary: true,
emitter: function(matches) { emitter: function(matches) {

View file

@ -205,14 +205,14 @@ Category.reopenClass({
return _uncategorized; return _uncategorized;
}, },
slugFor(category) { slugFor(category, separator = "/") {
if (!category) return ""; if (!category) return "";
const parentCategory = Em.get(category, 'parentCategory'); const parentCategory = Em.get(category, 'parentCategory');
let result = ""; let result = "";
if (parentCategory) { if (parentCategory) {
result = Category.slugFor(parentCategory) + "/"; result = Category.slugFor(parentCategory) + separator;
} }
const id = Em.get(category, 'id'), const id = Em.get(category, 'id'),

View file

@ -5,8 +5,10 @@ class CategoryHashtagsController < ApplicationController
category_slugs = params[:category_slugs] category_slugs = params[:category_slugs]
category_slugs.each(&:downcase!) category_slugs.each(&:downcase!)
valid_categories = Category.secured(guardian).where(slug: category_slugs).map do |category| ids = category_slugs.map { |category_slug| Category.query_from_hashtag_slug(category_slug).try(:id) }
{ slug: category.slug, url: category.url_with_id }
valid_categories = Category.secured(guardian).where(id: ids).map do |category|
{ slug: category.hashtag_slug, url: category.url_with_id }
end.compact end.compact
render json: { valid: valid_categories } render json: { valid: valid_categories }

View file

@ -5,6 +5,7 @@ class Category < ActiveRecord::Base
include Positionable include Positionable
include HasCustomFields include HasCustomFields
include CategoryHashtag
belongs_to :topic, dependent: :destroy belongs_to :topic, dependent: :destroy
belongs_to :topic_only_relative_url, belongs_to :topic_only_relative_url,
@ -398,8 +399,8 @@ SQL
@@url_cache.clear @@url_cache.clear
end end
def full_slug def full_slug(separator = "-")
url[3..-1].gsub("/", "-") url[3..-1].gsub("/", separator)
end end
def url def url

View file

@ -0,0 +1,23 @@
module CategoryHashtag
extend ActiveSupport::Concern
SEPARATOR = ":".freeze
class_methods do
def query_from_hashtag_slug(category_slug)
parent_slug, child_slug = category_slug.split(":", 2)
category = Category.where(slug: parent_slug, parent_category_id: nil)
if child_slug
Category.where(slug: child_slug, parent_category_id: category.pluck(:id).first).first
else
category.first
end
end
end
def hashtag_slug
full_slug(SEPARATOR)
end
end

View file

@ -49,9 +49,8 @@ module PrettyText
end end
def category_hashtag_lookup(category_slug) def category_hashtag_lookup(category_slug)
if category_slug if category = Category.query_from_hashtag_slug(category_slug)
category = Category.find_by_slug(category_slug) ['category', category.url_with_id]
return ['category', category.url_with_id] if category
else else
nil nil
end end

View file

@ -0,0 +1,26 @@
require 'rails_helper'
describe CategoryHashtag do
describe '#query_from_hashtag_slug' do
let(:parent_category) { Fabricate(:category) }
let(:child_category) { Fabricate(:category, parent_category: parent_category) }
it "should return the right result for a parent category slug" do
expect(Category.query_from_hashtag_slug(parent_category.slug))
.to eq(parent_category)
end
it "should return the right result for a parent and child category slug" do
expect(Category.query_from_hashtag_slug("#{parent_category.slug}:#{child_category.slug}"))
.to eq(child_category)
end
it "should return nil for incorrect parent category slug" do
expect(Category.query_from_hashtag_slug("random-slug")).to eq(nil)
end
it "should return nil for incorrect parent and child category slug" do
expect(Category.query_from_hashtag_slug("random-slug:random-slug")).to eq(nil)
end
end
end

View file

@ -390,7 +390,7 @@ HTML
end end
it "doesn't replace unicode emoji if emoji is disabled" do it "doesn't replace unicode emoji if emoji is disabled" do
SiteSetting.enable_emoji = false SiteSetting.enable_emoji = false
expect(PrettyText.cook("💣")).not_to match(/\:bomb\:/) expect(PrettyText.cook("💣")).not_to match(/\:bomb\:/)
end end
end end

View file

@ -12,7 +12,7 @@ describe CategoryHashtagsController do
xhr :get, :check, category_slugs: [category.slug, 'none'] xhr :get, :check, category_slugs: [category.slug, 'none']
expect(JSON.parse(response.body)).to eq( expect(JSON.parse(response.body)).to eq(
{ "valid" => [{ "slug" => category.slug, "url" => category.url_with_id }] } { "valid" => [{ "slug" => category.hashtag_slug, "url" => category.url_with_id }] }
) )
end end
@ -32,7 +32,7 @@ describe CategoryHashtagsController do
xhr :get, :check, category_slugs: [private_category.slug] xhr :get, :check, category_slugs: [private_category.slug]
expect(JSON.parse(response.body)).to eq( expect(JSON.parse(response.body)).to eq(
{ "valid" => [{ "slug" => private_category.slug, "url" => private_category.url_with_id }] } { "valid" => [{ "slug" => private_category.hashtag_slug, "url" => private_category.url_with_id }] }
) )
end end
end end