From 84ce1acfefbdef9897ab6e52c43bc122b788bcae Mon Sep 17 00:00:00 2001 From: Vinoth Kannan Date: Wed, 14 Feb 2018 02:16:25 +0530 Subject: [PATCH] FEATURE: Allow staffs to tag PMs --- .../components/topic-category.js.es6 | 9 +++- .../discourse/controllers/composer.js.es6 | 3 +- .../discourse/controllers/topic.js.es6 | 2 +- .../discourse/lib/render-tag.js.es6 | 7 ++- .../discourse/lib/render-tags.js.es6 | 3 +- .../discourse/routes/app-route-map.js.es6 | 1 + .../routes/user-private-messages-tag.js.es6 | 10 +++++ .../templates/components/topic-category.hbs | 14 +++--- .../javascripts/discourse/templates/topic.hbs | 4 +- .../stylesheets/common/base/compose.scss | 4 +- app/assets/stylesheets/common/base/topic.scss | 4 ++ app/controllers/list_controller.rb | 2 + app/models/tag.rb | 17 +------ app/models/topic_tag.rb | 22 +++++---- app/serializers/post_revision_serializer.rb | 4 +- .../search_topic_list_item_serializer.rb | 11 +---- app/serializers/site_serializer.rb | 9 +++- app/serializers/suggested_topic_serializer.rb | 11 +---- app/serializers/topic_list_item_serializer.rb | 10 +---- app/serializers/topic_tags_mixin.rb | 13 ++++++ app/serializers/topic_view_serializer.rb | 2 +- config/locales/server.en.yml | 1 + config/routes.rb | 27 +++++------ config/site_settings.yml | 2 + lib/discourse_tagging.rb | 4 +- lib/guardian.rb | 6 +++ lib/guardian/tag_guardian.rb | 6 ++- lib/topic_query.rb | 8 ++++ spec/models/tag_spec.rb | 45 ------------------- .../serializers/topic_view_serializer_spec.rb | 43 +++++++++++++++--- 30 files changed, 163 insertions(+), 141 deletions(-) create mode 100644 app/assets/javascripts/discourse/routes/user-private-messages-tag.js.es6 create mode 100644 app/serializers/topic_tags_mixin.rb diff --git a/app/assets/javascripts/discourse/components/topic-category.js.es6 b/app/assets/javascripts/discourse/components/topic-category.js.es6 index 97fcde13cda..58e58e0d1be 100644 --- a/app/assets/javascripts/discourse/components/topic-category.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-category.js.es6 @@ -1,2 +1,7 @@ -// Injections don't occur without a class -export default Ember.Component.extend(); +import computed from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + + @computed('topic.isPrivateMessage') + +}); diff --git a/app/assets/javascripts/discourse/controllers/composer.js.es6 b/app/assets/javascripts/discourse/controllers/composer.js.es6 index 68b5a75bac4..9416e8df576 100644 --- a/app/assets/javascripts/discourse/controllers/composer.js.es6 +++ b/app/assets/javascripts/discourse/controllers/composer.js.es6 @@ -140,7 +140,8 @@ export default Ember.Controller.extend({ return !this.site.mobileView && this.site.get('can_tag_topics') && canEditTitle && - !creatingPrivateMessage; + !creatingPrivateMessage && + (!this.get('model.topic.isPrivateMessage') || this.site.get('can_tag_pms')); }, @computed('model.whisper', 'model.unlistTopic') diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 49110ce83bf..a4e6b2e08d8 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -104,7 +104,7 @@ export default Ember.Controller.extend(BufferedContent, { @computed('model.isPrivateMessage') canEditTags(isPrivateMessage) { - return !isPrivateMessage && this.site.get('can_tag_topics'); + return this.site.get('can_tag_topics') && (!isPrivateMessage || this.site.get('can_tag_pms')); }, actions: { diff --git a/app/assets/javascripts/discourse/lib/render-tag.js.es6 b/app/assets/javascripts/discourse/lib/render-tag.js.es6 index 127dc5c9fe4..70fa81179f3 100644 --- a/app/assets/javascripts/discourse/lib/render-tag.js.es6 +++ b/app/assets/javascripts/discourse/lib/render-tag.js.es6 @@ -3,7 +3,12 @@ export default function renderTag(tag, params) { tag = Handlebars.Utils.escapeExpression(tag); const classes = ['tag-' + tag, 'discourse-tag']; const tagName = params.tagName || "a"; - const href = (tagName === "a" && !params.noHref) ? " href='" + Discourse.getURL("/tags/" + tag) + "' " : ""; + let path; + if (tagName === "a" && !params.noHref) { + const current_user = Discourse.User.current(); + path = params.isPrivateMessage ? `/u/${current_user.username}/messages/tag/${tag}` : `/tags/${tag}`; + } + const href = path ? ` href='${Discourse.getURL(path)}' ` : ""; if (Discourse.SiteSettings.tag_style || params.style) { classes.push(params.style || Discourse.SiteSettings.tag_style); diff --git a/app/assets/javascripts/discourse/lib/render-tags.js.es6 b/app/assets/javascripts/discourse/lib/render-tags.js.es6 index 6989eab57b1..ef86b502d31 100644 --- a/app/assets/javascripts/discourse/lib/render-tags.js.es6 +++ b/app/assets/javascripts/discourse/lib/render-tags.js.es6 @@ -20,6 +20,7 @@ export function addTagsHtmlCallback(callback, options) { export default function(topic, params){ let tags = topic.tags; let buffer = ""; + const isPrivateMessage = topic.get('isPrivateMessage'); if (params && params.mode === "list") { tags = topic.get("visibleListTags"); @@ -43,7 +44,7 @@ export default function(topic, params){ buffer = "
"; if (tags) { for(let i=0; i {{#if siteSettings.tagging_enabled}}
- {{#each topic.tags as |t|}} - {{discourse-tag t}} - {{/each}} + {{discourse-tags topic mode="list"}}
{{/if}} {{#if siteSettings.topic_featured_link_enabled}} diff --git a/app/assets/javascripts/discourse/templates/topic.hbs b/app/assets/javascripts/discourse/templates/topic.hbs index ef2d4912ccd..167ffcf138b 100644 --- a/app/assets/javascripts/discourse/templates/topic.hbs +++ b/app/assets/javascripts/discourse/templates/topic.hbs @@ -63,9 +63,7 @@ {{/if}} - {{#unless model.isPrivateMessage}} - {{topic-category topic=model class="topic-category"}} - {{/unless}} + {{topic-category topic=model class="topic-category"}} {{/if}} {{/topic-title}} {{/if}} diff --git a/app/assets/stylesheets/common/base/compose.scss b/app/assets/stylesheets/common/base/compose.scss index 1a93bad72d4..ad742d5971a 100644 --- a/app/assets/stylesheets/common/base/compose.scss +++ b/app/assets/stylesheets/common/base/compose.scss @@ -189,7 +189,7 @@ .category-input { display: flex; flex: 1 0 35%; - margin: 0 0 5px 10px; + margin: 0 5px 5px 10px; @media screen and (max-width: 955px) { flex: 1 0 100%; margin-left: 0; @@ -223,7 +223,7 @@ .mini-tag-chooser { flex: 1 1 25%; - margin: 0 0 5px 5px; + margin: 0 0 5px 0; background: $secondary; @media all and (max-width: 900px) { margin: 0; diff --git a/app/assets/stylesheets/common/base/topic.scss b/app/assets/stylesheets/common/base/topic.scss index 5b267622e3e..d8b25930d35 100644 --- a/app/assets/stylesheets/common/base/topic.scss +++ b/app/assets/stylesheets/common/base/topic.scss @@ -122,6 +122,10 @@ a.badge-category { } } +.archetype-private_message #topic-title .edit-topic-title .tag-chooser { + margin-left: 19px; +} + .private_message { #topic-title { .edit-topic-title { diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb index 905f0077cb2..384d5a00c20 100644 --- a/app/controllers/list_controller.rb +++ b/app/controllers/list_controller.rb @@ -151,6 +151,7 @@ class ListController < ApplicationController private_messages_archive private_messages_group private_messages_group_archive + private_messages_tag }.each do |action| generate_message_route(action) end @@ -332,6 +333,7 @@ class ListController < ApplicationController def build_topic_list_options options = {} params[:page] = params[:page].to_i rescue 1 + params[:tags] = [params[:tag_id]] if params[:tag_id].present? && guardian.can_tag_pms? TopicQuery.public_valid_options.each do |key| options[key] = params[key] diff --git a/app/models/tag.rb b/app/models/tag.rb index 45d900d4222..500ba8e6e3a 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -16,21 +16,6 @@ class Tag < ActiveRecord::Base after_save :index_search - COUNT_ARG = "topics.id" - - # Apply more activerecord filters to the tags_by_count_query, and then - # fetch the result with .count(Tag::COUNT_ARG). - # - # e.g., Tag.tags_by_count_query.where("topics.category_id = ?", category.id).count(Tag::COUNT_ARG) - def self.tags_by_count_query(opts = {}) - q = Tag.joins("LEFT JOIN topic_tags ON tags.id = topic_tags.tag_id") - .joins("LEFT JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL") - .group("tags.id, tags.name") - .order('count_topics_id DESC') - q = q.limit(opts[:limit]) if opts[:limit] - q - end - def self.ensure_consistency! update_topic_counts # topic_count counter cache can miscount end @@ -43,7 +28,7 @@ class Tag < ActiveRecord::Base SELECT COUNT(topics.id) AS topic_count, tags.id AS tag_id FROM tags LEFT JOIN topic_tags ON tags.id = topic_tags.tag_id - LEFT JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL + LEFT JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL AND topics.archetype != "private_message" GROUP BY tags.id ) x WHERE x.tag_id = t.id diff --git a/app/models/topic_tag.rb b/app/models/topic_tag.rb index 2dc203290bc..de53e4cf8ad 100644 --- a/app/models/topic_tag.rb +++ b/app/models/topic_tag.rb @@ -1,22 +1,28 @@ class TopicTag < ActiveRecord::Base belongs_to :topic - belongs_to :tag, counter_cache: "topic_count" + belongs_to :tag after_create do - if topic.category_id - if stat = CategoryTagStat.where(tag_id: tag_id, category_id: topic.category_id).first - stat.increment!(:topic_count) - else - CategoryTagStat.create(tag_id: tag_id, category_id: topic.category_id, topic_count: 1) + if topic.archetype != Archetype.private_message + tag.increment!(:topic_count) + + if topic.category_id + if stat = CategoryTagStat.where(tag_id: tag_id, category_id: topic.category_id).first + stat.increment!(:topic_count) + else + CategoryTagStat.create(tag_id: tag_id, category_id: topic.category_id, topic_count: 1) + end end end end after_destroy do - if topic.category_id - if stat = CategoryTagStat.where(tag_id: tag_id, category: topic.category_id).first + if topic.archetype != Archetype.private_message + if topic.category_id && stat = CategoryTagStat.where(tag_id: tag_id, category: topic.category_id).first stat.topic_count == 1 ? stat.destroy : stat.decrement!(:topic_count) end + + tag.decrement!(:topic_count) end end end diff --git a/app/serializers/post_revision_serializer.rb b/app/serializers/post_revision_serializer.rb index 11b13677f4e..7ed34769ae5 100644 --- a/app/serializers/post_revision_serializer.rb +++ b/app/serializers/post_revision_serializer.rb @@ -164,7 +164,7 @@ class PostRevisionSerializer < ApplicationSerializer end def include_tags_changes? - SiteSetting.tagging_enabled && previous["tags"] != current["tags"] + SiteSetting.tagging_enabled && previous["tags"] != current["tags"] && (!topic.private_message? || scope.can_tag_pms?) end protected @@ -206,7 +206,7 @@ class PostRevisionSerializer < ApplicationSerializer latest_modifications["featured_link"] = [post.topic.featured_link] end - if SiteSetting.tagging_enabled + if SiteSetting.tagging_enabled && (!topic.private_message? || scope.can_tag_pms?) latest_modifications["tags"] = [post.topic.tags.map(&:name)] end diff --git a/app/serializers/search_topic_list_item_serializer.rb b/app/serializers/search_topic_list_item_serializer.rb index abe002899a3..29640c13d05 100644 --- a/app/serializers/search_topic_list_item_serializer.rb +++ b/app/serializers/search_topic_list_item_serializer.rb @@ -1,12 +1,5 @@ class SearchTopicListItemSerializer < ListableTopicSerializer - attributes :tags, - :category_id + include TopicTagsMixin - def include_tags? - SiteSetting.tagging_enabled - end - - def tags - object.tags.map(&:name) - end + attributes :category_id end diff --git a/app/serializers/site_serializer.rb b/app/serializers/site_serializer.rb index 850a8dd8dd3..1a81501d5eb 100644 --- a/app/serializers/site_serializer.rb +++ b/app/serializers/site_serializer.rb @@ -21,6 +21,7 @@ class SiteSerializer < ApplicationSerializer :topic_flag_types, :can_create_tag, :can_tag_topics, + :can_tag_pms, :tags_filter_regexp, :top_tags, :wizard_required, @@ -106,11 +107,15 @@ class SiteSerializer < ApplicationSerializer end def can_create_tag - SiteSetting.tagging_enabled && scope.can_create_tag? + scope.can_create_tag? end def can_tag_topics - SiteSetting.tagging_enabled && scope.can_tag_topics? + scope.can_tag_topics? + end + + def can_tag_pms + scope.can_tag_pms? end def include_tags_filter_regexp? diff --git a/app/serializers/suggested_topic_serializer.rb b/app/serializers/suggested_topic_serializer.rb index 85eeea94996..a2dcdef6b17 100644 --- a/app/serializers/suggested_topic_serializer.rb +++ b/app/serializers/suggested_topic_serializer.rb @@ -1,4 +1,5 @@ class SuggestedTopicSerializer < ListableTopicSerializer + include TopicTagsMixin # need to embed so we have users # front page json gets away without embedding @@ -7,21 +8,13 @@ class SuggestedTopicSerializer < ListableTopicSerializer has_one :user, serializer: BasicUserSerializer, embed: :objects end - attributes :archetype, :like_count, :views, :category_id, :tags, :featured_link, :featured_link_root_domain + attributes :archetype, :like_count, :views, :category_id, :featured_link, :featured_link_root_domain has_many :posters, serializer: SuggestedPosterSerializer, embed: :objects def posters object.posters || [] end - def include_tags? - SiteSetting.tagging_enabled - end - - def tags - object.tags.map(&:name) - end - def include_featured_link? SiteSetting.topic_featured_link_enabled end diff --git a/app/serializers/topic_list_item_serializer.rb b/app/serializers/topic_list_item_serializer.rb index 0ce4f4cd500..66092c62466 100644 --- a/app/serializers/topic_list_item_serializer.rb +++ b/app/serializers/topic_list_item_serializer.rb @@ -1,4 +1,5 @@ class TopicListItemSerializer < ListableTopicSerializer + include TopicTagsMixin attributes :views, :like_count, @@ -10,7 +11,6 @@ class TopicListItemSerializer < ListableTopicSerializer :pinned_globally, :bookmarked_post_numbers, :liked_post_numbers, - :tags, :featured_link, :featured_link_root_domain @@ -66,14 +66,6 @@ class TopicListItemSerializer < ListableTopicSerializer object.association(:first_post).loaded? end - def include_tags? - SiteSetting.tagging_enabled - end - - def tags - object.tags.map(&:name) - end - def include_featured_link? SiteSetting.topic_featured_link_enabled end diff --git a/app/serializers/topic_tags_mixin.rb b/app/serializers/topic_tags_mixin.rb new file mode 100644 index 00000000000..2257ebac126 --- /dev/null +++ b/app/serializers/topic_tags_mixin.rb @@ -0,0 +1,13 @@ +module TopicTagsMixin + def self.included(klass) + klass.attributes :tags + end + + def include_tags? + SiteSetting.tagging_enabled && (!object.private_message? || scope.can_tag_pms?) + end + + def tags + object.tags.pluck(:name) + end +end diff --git a/app/serializers/topic_view_serializer.rb b/app/serializers/topic_view_serializer.rb index 839a9311346..86a57abef64 100644 --- a/app/serializers/topic_view_serializer.rb +++ b/app/serializers/topic_view_serializer.rb @@ -239,7 +239,7 @@ class TopicViewSerializer < ApplicationSerializer end def include_tags? - SiteSetting.tagging_enabled + SiteSetting.tagging_enabled && (!object.topic.private_message? || scope.can_tag_pms?) end def topic_timer diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index d5ef33a877f..74845543404 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1609,6 +1609,7 @@ en: tags_listed_by_group: "List tags by tag group on the Tags page (/tags)." tag_style: "Visual style for tag badges." staff_tags: "A list of tags that can only be applied by staff members" + allow_staff_to_tag_in_pm: "Allow staff members to tag any personal message" min_trust_level_to_tag_topics: "Minimum trust level required to tag topics" suppress_overlapping_tags_in_list: "If tags match exact words in topic titles, don't show the tag" remove_muted_tags_from_latest: "Don't show topics tagged with muted tags in the latest topic list." diff --git a/config/routes.rb b/config/routes.rb index 11edecf0f9c..5c0e947df68 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -360,6 +360,7 @@ Discourse::Application.routes.draw do get "#{root_path}/:username/messages/:filter" => "user_actions#private_messages", constraints: { username: RouteFormat.username } get "#{root_path}/:username/messages/group/:group_name" => "user_actions#private_messages", constraints: { username: RouteFormat.username, group_name: RouteFormat.username } get "#{root_path}/:username/messages/group/:group_name/archive" => "user_actions#private_messages", constraints: { username: RouteFormat.username, group_name: RouteFormat.username } + get "#{root_path}/:username/messages/tag/:tag_id" => "user_actions#private_messages", constraints: StaffConstraint.new get "#{root_path}/:username.json" => "users#show", constraints: { username: RouteFormat.username }, defaults: { format: :json } get({ "#{root_path}/:username" => "users#show", constraints: { username: RouteFormat.username, format: /(json|html)/ } }.merge(index == 1 ? { as: 'user' } : {})) put "#{root_path}/:username" => "users#update", constraints: { username: RouteFormat.username }, defaults: { format: :json } @@ -589,20 +590,20 @@ Discourse::Application.routes.draw do resources :similar_topics get "topics/feature_stats" - get "topics/created-by/:username" => "list#topics_by", as: "topics_by", constraints: { username: RouteFormat.username } - get "topics/private-messages/:username" => "list#private_messages", as: "topics_private_messages", constraints: { username: RouteFormat.username } - get "topics/private-messages-sent/:username" => "list#private_messages_sent", as: "topics_private_messages_sent", constraints: { username: RouteFormat.username } - get "topics/private-messages-archive/:username" => "list#private_messages_archive", as: "topics_private_messages_archive", constraints: { username: RouteFormat.username } - get "topics/private-messages-unread/:username" => "list#private_messages_unread", as: "topics_private_messages_unread", constraints: { username: RouteFormat.username } - get "topics/private-messages-group/:username/:group_name.json" => "list#private_messages_group", as: "topics_private_messages_group", constraints: { - username: RouteFormat.username, - group_name: RouteFormat.username - } - get "topics/private-messages-group/:username/:group_name/archive.json" => "list#private_messages_group_archive", as: "topics_private_messages_group_archive", constraints: { - username: RouteFormat.username, - group_name: RouteFormat.username - } + scope "/topics", username: RouteFormat.username do + get "created-by/:username" => "list#topics_by", as: "topics_by" + get "private-messages/:username" => "list#private_messages", as: "topics_private_messages" + get "private-messages-sent/:username" => "list#private_messages_sent", as: "topics_private_messages_sent" + get "private-messages-archive/:username" => "list#private_messages_archive", as: "topics_private_messages_archive" + get "private-messages-unread/:username" => "list#private_messages_unread", as: "topics_private_messages_unread" + get "private-messages-tag/:username/:tag_id.json" => "list#private_messages_tag", as: "topics_private_messages_tag", constraints: StaffConstraint.new + + scope "/private-messages-group/:username", group_name: RouteFormat.username do + get ":group_name.json" => "list#private_messages_group", as: "topics_private_messages_group" + get ":group_name/archive.json" => "list#private_messages_group_archive", as: "topics_private_messages_group_archive" + end + end get 'embed/comments' => 'embed#comments' get 'embed/count' => 'embed#count' diff --git a/config/site_settings.yml b/config/site_settings.yml index 55163cd323b..e68b1000ec0 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -1560,6 +1560,8 @@ tags: type: list client: true default: '' + allow_staff_to_tag_in_pm: + default: false suppress_overlapping_tags_in_list: default: false client: true diff --git a/lib/discourse_tagging.rb b/lib/discourse_tagging.rb index 0fcf8bda9b7..e30457035af 100644 --- a/lib/discourse_tagging.rb +++ b/lib/discourse_tagging.rb @@ -4,10 +4,10 @@ module DiscourseTagging TAGS_FILTER_REGEXP = /[\/\?#\[\]@!\$&'\(\)\*\+,;=\.%\\`^\s|\{\}"<>]+/ # /?#[]@!$&'()*+,;=.%\`^|{}"<> def self.tag_topic_by_names(topic, guardian, tag_names_arg, append: false) - if SiteSetting.tagging_enabled + if can_tag?(topic) tag_names = DiscourseTagging.tags_for_saving(tag_names_arg, guardian) || [] - old_tag_names = topic.tags.map(&:name) || [] + old_tag_names = topic.tags.pluck(:name) || [] new_tag_names = tag_names - old_tag_names removed_tag_names = old_tag_names - tag_names diff --git a/lib/guardian.rb b/lib/guardian.rb index 19d9fe78231..1b658ef888b 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -129,6 +129,12 @@ class Guardian alias :can_see_flags? :can_moderate? alias :can_close? :can_moderate? + def can_tag?(obj) + return false unless obj && obj.is_a?(Topic) + + obj.private_message? ? can_tag_pms? : can_tag_topics? + end + def can_send_activation_email?(user) user && is_staff? && !SiteSetting.must_approve_users? end diff --git a/lib/guardian/tag_guardian.rb b/lib/guardian/tag_guardian.rb index b9315078df3..8f60c8223c3 100644 --- a/lib/guardian/tag_guardian.rb +++ b/lib/guardian/tag_guardian.rb @@ -5,7 +5,11 @@ module TagGuardian end def can_tag_topics? - user && user.has_trust_level?(SiteSetting.min_trust_level_to_tag_topics.to_i) + user && SiteSetting.tagging_enabled && user.has_trust_level?(SiteSetting.min_trust_level_to_tag_topics.to_i) + end + + def can_tag_pms? + is_staff? && SiteSetting.tagging_enabled && SiteSetting.allow_staff_to_tag_in_pm end def can_admin_tags? diff --git a/lib/topic_query.rb b/lib/topic_query.rb index 34ca3f32ddc..fd9464fffc3 100644 --- a/lib/topic_query.rb +++ b/lib/topic_query.rb @@ -269,6 +269,14 @@ class TopicQuery create_list(:private_messages, {}, list) end + def list_private_messages_tag(user) + list = private_messages_for(user, :all) + tag_id = Tag.where('name ilike ?', @options[:tags][0]).pluck(:id).first + list = list.joins("JOIN topic_tags tt ON tt.topic_id = topics.id AND + tt.tag_id = #{tag_id}") + create_list(:private_messages, {}, list) + end + def list_category_topic_ids(category) query = default_results(category: category.id) pinned_ids = query.where('pinned_at IS NOT NULL AND category_id = ?', category.id).limit(nil).order('pinned_at DESC').pluck(:id) diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb index 6cea43f3052..faa6145a80c 100644 --- a/spec/models/tag_spec.rb +++ b/spec/models/tag_spec.rb @@ -15,51 +15,6 @@ describe Tag do SiteSetting.min_trust_level_to_tag_topics = 0 end - describe '#tags_by_count_query' do - it "returns empty hash if nothing is tagged" do - expect(described_class.tags_by_count_query.count(Tag::COUNT_ARG)).to eq({}) - end - - context "with some tagged topics" do - before do - @topics = [] - 3.times { @topics << Fabricate(:topic) } - make_some_tags(count: 2) - @topics[0].tags << @tags[0] - @topics[0].tags << @tags[1] - @topics[1].tags << @tags[0] - end - - it "returns tag names with topic counts in a hash" do - counts = described_class.tags_by_count_query.count(Tag::COUNT_ARG) - expect(counts[@tags[0].name]).to eq(2) - expect(counts[@tags[1].name]).to eq(1) - end - - it "can be used to filter before doing the count" do - counts = described_class.tags_by_count_query.where("topics.id = ?", @topics[1].id).count(Tag::COUNT_ARG) - expect(counts).to eq(@tags[0].name => 1) - end - - it "returns unused tags too" do - unused = Fabricate(:tag) - counts = described_class.tags_by_count_query.count(Tag::COUNT_ARG) - expect(counts[unused.name]).to eq(0) - end - - it "doesn't include deleted topics in counts" do - deleted_topic_tag = Fabricate(:tag) - delete_topic = Fabricate(:topic) - post = Fabricate(:post, topic: delete_topic, user: delete_topic.user) - delete_topic.tags << deleted_topic_tag - PostDestroyer.new(Fabricate(:admin), post).destroy - - counts = described_class.tags_by_count_query.count(Tag::COUNT_ARG) - expect(counts[deleted_topic_tag.name]).to eq(0) - end - end - end - describe '#top_tags' do it "returns nothing if nothing has been tagged" do make_some_tags(tag_a_topic: false) diff --git a/spec/serializers/topic_view_serializer_spec.rb b/spec/serializers/topic_view_serializer_spec.rb index c2970db194f..90d3e7a5fc4 100644 --- a/spec/serializers/topic_view_serializer_spec.rb +++ b/spec/serializers/topic_view_serializer_spec.rb @@ -1,6 +1,11 @@ require 'rails_helper' describe TopicViewSerializer do + def serialize_topic(topic, user) + topic_view = TopicView.new(topic.id, user) + described_class.new(topic_view, scope: Guardian.new(user), root: false).as_json + end + let(:topic) { Fabricate(:topic) } let(:user) { Fabricate(:user) } @@ -12,8 +17,7 @@ describe TopicViewSerializer do topic.update!(featured_link: featured_link) SiteSetting.topic_featured_link_enabled = false - topic_view = TopicView.new(topic.id, user) - json = described_class.new(topic_view, scope: Guardian.new(user), root: false).as_json + json = serialize_topic(topic, user) expect(json[:featured_link]).to eq(nil) expect(json[:featured_link_root_domain]).to eq(nil) @@ -24,8 +28,7 @@ describe TopicViewSerializer do it 'should return the right attributes' do topic.update!(featured_link: featured_link) - topic_view = TopicView.new(topic.id, user) - json = described_class.new(topic_view, scope: Guardian.new(user), root: false).as_json + json = serialize_topic(topic, user) expect(json[:featured_link]).to eq(featured_link) expect(json[:featured_link_root_domain]).to eq('discourse.org') @@ -42,8 +45,7 @@ describe TopicViewSerializer do describe 'when loading last chunk' do it 'should include suggested topics' do - topic_view = TopicView.new(topic.id, user) - json = described_class.new(topic_view, scope: Guardian.new(user), root: false).as_json + json = serialize_topic(topic, user) expect(json[:suggested_topics].first.id).to eq(topic2.id) end @@ -64,4 +66,33 @@ describe TopicViewSerializer do end end end + + let(:user) { Fabricate(:user) } + let(:moderator) { Fabricate(:moderator) } + let(:tag) { Fabricate(:tag) } + let(:pm) do + Fabricate(:private_message_topic, tags: [tag], topic_allowed_users: [ + Fabricate.build(:topic_allowed_user, user: moderator), + Fabricate.build(:topic_allowed_user, user: user) + ]) + end + + describe 'when tags added to private message topics' do + before do + SiteSetting.tagging_enabled = true + end + + it "should not include the tag for normal users" do + json = serialize_topic(pm, user) + expect(json[:tags]).to eq(nil) + end + + it "should include the tag for staff users" do + json = serialize_topic(pm, moderator) + expect(json[:tags]).to eq([tag.name]) + + json = serialize_topic(pm, Fabricate(:admin)) + expect(json[:tags]).to eq([tag.name]) + end + end end