FEATURE: suppress categories from the homepage
This commit is contained in:
parent
a76d1079b2
commit
a501947d67
|
@ -77,7 +77,8 @@ Discourse.Category = Discourse.Model.extend({
|
|||
background_url: this.get('background_url'),
|
||||
allow_badges: this.get('allow_badges'),
|
||||
custom_fields: this.get('custom_fields'),
|
||||
topic_template: this.get('topic_template')
|
||||
topic_template: this.get('topic_template'),
|
||||
suppress_from_homepage: this.get('suppress_from_homepage'),
|
||||
},
|
||||
type: this.get('id') ? 'PUT' : 'POST'
|
||||
});
|
||||
|
|
|
@ -40,7 +40,6 @@ function findTopicList(store, filter, filterParams, extras) {
|
|||
session.setProperties({topicList: null, topicListScrollPosition: null});
|
||||
}
|
||||
|
||||
|
||||
// Clean up any string parameters that might slip through
|
||||
filterParams = filterParams || {};
|
||||
Ember.keys(filterParams).forEach(function(k) {
|
||||
|
@ -50,17 +49,7 @@ function findTopicList(store, filter, filterParams, extras) {
|
|||
}
|
||||
});
|
||||
|
||||
const findParams = {};
|
||||
Discourse.SiteSettings.top_menu.split('|').forEach(function (i) {
|
||||
if (i.indexOf(filter) === 0) {
|
||||
const exclude = i.split("-");
|
||||
if (exclude && exclude.length === 2) {
|
||||
findParams.exclude_category = exclude[1];
|
||||
}
|
||||
}
|
||||
});
|
||||
return resolve(store.findFiltered('topicList', { filter, params:_.extend(findParams, filterParams || {})}));
|
||||
|
||||
return resolve(store.findFiltered('topicList', { filter, params: filterParams || {} }));
|
||||
}).then(function(list) {
|
||||
list.set('listParams', filterParams);
|
||||
if (tracking) {
|
||||
|
|
|
@ -44,4 +44,11 @@
|
|||
{{/if}}
|
||||
</section>
|
||||
|
||||
<section class="field">
|
||||
<label class="checkbox-label">
|
||||
{{input type="checkbox" checked=category.suppress_from_homepage}}
|
||||
{{i18n "category.suppress_from_homepage"}}
|
||||
</label>
|
||||
</section>
|
||||
|
||||
{{plugin-outlet "category-custom-settings"}}
|
||||
|
|
|
@ -16,6 +16,7 @@ class CategoriesController < ApplicationController
|
|||
options = {}
|
||||
options[:latest_posts] = params[:latest_posts] || SiteSetting.category_featured_topics
|
||||
options[:parent_category_id] = params[:parent_category_id]
|
||||
options[:is_homepage] = current_homepage == "categories".freeze
|
||||
|
||||
@list = CategoryList.new(guardian, options)
|
||||
@list.draft_key = Draft::NEW_TOPIC
|
||||
|
@ -24,7 +25,7 @@ class CategoriesController < ApplicationController
|
|||
|
||||
discourse_expires_in 1.minute
|
||||
|
||||
unless current_homepage == 'categories'
|
||||
unless current_homepage == "categories"
|
||||
@title = I18n.t('js.filters.categories.title')
|
||||
end
|
||||
|
||||
|
@ -139,6 +140,7 @@ class CategoriesController < ApplicationController
|
|||
:position,
|
||||
:email_in,
|
||||
:email_in_allow_strangers,
|
||||
:suppress_from_homepage,
|
||||
:parent_category_id,
|
||||
:auto_close_hours,
|
||||
:auto_close_based_on_last_post,
|
||||
|
|
|
@ -5,36 +5,34 @@ class ListController < ApplicationController
|
|||
|
||||
skip_before_filter :check_xhr
|
||||
|
||||
@@categories = [
|
||||
before_filter :set_category, only: [
|
||||
# filtered topics lists
|
||||
Discourse.filters.map { |f| "category_#{f}".to_sym },
|
||||
Discourse.filters.map { |f| "category_none_#{f}".to_sym },
|
||||
Discourse.filters.map { |f| "parent_category_category_#{f}".to_sym },
|
||||
Discourse.filters.map { |f| "parent_category_category_none_#{f}".to_sym },
|
||||
Discourse.filters.map { |f| :"category_#{f}" },
|
||||
Discourse.filters.map { |f| :"category_none_#{f}" },
|
||||
Discourse.filters.map { |f| :"parent_category_category_#{f}" },
|
||||
Discourse.filters.map { |f| :"parent_category_category_none_#{f}" },
|
||||
# top summaries
|
||||
:category_top,
|
||||
:category_none_top,
|
||||
:parent_category_category_top,
|
||||
# top pages (ie. with a period)
|
||||
TopTopic.periods.map { |p| "category_top_#{p}".to_sym },
|
||||
TopTopic.periods.map { |p| "category_none_top_#{p}".to_sym },
|
||||
TopTopic.periods.map { |p| "parent_category_category_top_#{p}".to_sym },
|
||||
TopTopic.periods.map { |p| :"category_top_#{p}" },
|
||||
TopTopic.periods.map { |p| :"category_none_top_#{p}" },
|
||||
TopTopic.periods.map { |p| :"parent_category_category_top_#{p}" },
|
||||
# category feeds
|
||||
:category_feed,
|
||||
].flatten
|
||||
|
||||
before_filter :set_category, only: @@categories
|
||||
|
||||
before_filter :ensure_logged_in, except: [
|
||||
:topics_by,
|
||||
# anonymous filters
|
||||
Discourse.anonymous_filters,
|
||||
Discourse.anonymous_filters.map { |f| "#{f}_feed".to_sym },
|
||||
Discourse.anonymous_filters.map { |f| "#{f}_feed" },
|
||||
# anonymous categorized filters
|
||||
Discourse.anonymous_filters.map { |f| "category_#{f}".to_sym },
|
||||
Discourse.anonymous_filters.map { |f| "category_none_#{f}".to_sym },
|
||||
Discourse.anonymous_filters.map { |f| "parent_category_category_#{f}".to_sym },
|
||||
Discourse.anonymous_filters.map { |f| "parent_category_category_none_#{f}".to_sym },
|
||||
Discourse.anonymous_filters.map { |f| :"category_#{f}" },
|
||||
Discourse.anonymous_filters.map { |f| :"category_none_#{f}" },
|
||||
Discourse.anonymous_filters.map { |f| :"parent_category_category_#{f}" },
|
||||
Discourse.anonymous_filters.map { |f| :"parent_category_category_none_#{f}" },
|
||||
# category feeds
|
||||
:category_feed,
|
||||
# top summaries
|
||||
|
@ -43,14 +41,14 @@ class ListController < ApplicationController
|
|||
:category_none_top,
|
||||
:parent_category_category_top,
|
||||
# top pages (ie. with a period)
|
||||
TopTopic.periods.map { |p| "top_#{p}".to_sym },
|
||||
TopTopic.periods.map { |p| "category_top_#{p}".to_sym },
|
||||
TopTopic.periods.map { |p| "category_none_top_#{p}".to_sym },
|
||||
TopTopic.periods.map { |p| "parent_category_category_top_#{p}".to_sym },
|
||||
TopTopic.periods.map { |p| :"top_#{p}" },
|
||||
TopTopic.periods.map { |p| :"category_top_#{p}" },
|
||||
TopTopic.periods.map { |p| :"category_none_top_#{p}" },
|
||||
TopTopic.periods.map { |p| :"parent_category_category_top_#{p}" },
|
||||
].flatten
|
||||
|
||||
# Create our filters
|
||||
Discourse.filters.each_with_index do |filter, idx|
|
||||
Discourse.filters.each do |filter|
|
||||
define_method(filter) do |options = nil|
|
||||
list_opts = build_topic_list_options
|
||||
list_opts.merge!(options) if options
|
||||
|
@ -60,6 +58,10 @@ class ListController < ApplicationController
|
|||
list_opts[:no_definitions] = true
|
||||
end
|
||||
|
||||
if filter.to_s == current_homepage
|
||||
list_opts.merge!(exclude_category_ids: get_excluded_category_ids(list_opts[:category]))
|
||||
end
|
||||
|
||||
list = TopicQuery.new(user, list_opts).public_send("list_#{filter}")
|
||||
list.more_topics_url = construct_url_with(:next, list_opts)
|
||||
list.prev_topics_url = construct_url_with(:prev, list_opts)
|
||||
|
@ -83,34 +85,20 @@ class ListController < ApplicationController
|
|||
|
||||
define_method("category_#{filter}") do
|
||||
canonical_url "#{Discourse.base_url}#{@category.url}"
|
||||
self.send(filter, { category: @category.id })
|
||||
self.send(filter, category: @category.id)
|
||||
end
|
||||
|
||||
define_method("category_none_#{filter}") do
|
||||
self.send(filter, { category: @category.id, no_subcategories: true })
|
||||
self.send(filter, category: @category.id, no_subcategories: true)
|
||||
end
|
||||
|
||||
define_method("parent_category_category_#{filter}") do
|
||||
canonical_url "#{Discourse.base_url}#{@category.url}"
|
||||
self.send(filter, { category: @category.id })
|
||||
self.send(filter, category: @category.id)
|
||||
end
|
||||
|
||||
define_method("parent_category_category_none_#{filter}") do
|
||||
self.send(filter, { category: @category.id })
|
||||
end
|
||||
end
|
||||
|
||||
Discourse.feed_filters.each do |filter|
|
||||
define_method("#{filter}_feed") do
|
||||
discourse_expires_in 1.minute
|
||||
|
||||
@title = "#{SiteSetting.title} - #{I18n.t("rss_description.#{filter}")}"
|
||||
@link = "#{Discourse.base_url}/#{filter}"
|
||||
@description = I18n.t("rss_description.#{filter}")
|
||||
@atom_link = "#{Discourse.base_url}/#{filter}.rss"
|
||||
@topic_list = TopicQuery.new(nil, order: 'created').public_send("list_#{filter}")
|
||||
|
||||
render 'list', formats: [:rss]
|
||||
self.send(filter, category: @category.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -127,14 +115,26 @@ class ListController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def latest_feed
|
||||
discourse_expires_in 1.minute
|
||||
|
||||
@title = "#{SiteSetting.title} - #{I18n.t("rss_description.latest")}"
|
||||
@link = "#{Discourse.base_url}/latest"
|
||||
@atom_link = "#{Discourse.base_url}/latest.rss"
|
||||
@description = I18n.t("rss_description.latest")
|
||||
@topic_list = TopicQuery.new(nil, order: 'created').list_latest
|
||||
|
||||
render 'list', formats: [:rss]
|
||||
end
|
||||
|
||||
def category_feed
|
||||
guardian.ensure_can_see!(@category)
|
||||
discourse_expires_in 1.minute
|
||||
|
||||
@title = @category.name
|
||||
@link = "#{Discourse.base_url}#{@category.url}"
|
||||
@description = "#{I18n.t('topics_in_category', category: @category.name)} #{@category.description}"
|
||||
@atom_link = "#{Discourse.base_url}#{@category.url}.rss"
|
||||
@description = "#{I18n.t('topics_in_category', category: @category.name)} #{@category.description}"
|
||||
@topic_list = TopicQuery.new.list_new_in_category(@category)
|
||||
|
||||
render 'list', formats: [:rss]
|
||||
|
@ -147,15 +147,15 @@ class ListController < ApplicationController
|
|||
end
|
||||
|
||||
def category_top
|
||||
top({ category: @category.id })
|
||||
top(category: @category.id)
|
||||
end
|
||||
|
||||
def category_none_top
|
||||
top({ category: @category.id, no_subcategories: true })
|
||||
top(category: @category.id, no_subcategories: true)
|
||||
end
|
||||
|
||||
def parent_category_category_top
|
||||
top({ category: @category.id })
|
||||
top(category: @category.id)
|
||||
end
|
||||
|
||||
TopTopic.periods.each do |period|
|
||||
|
@ -163,6 +163,11 @@ class ListController < ApplicationController
|
|||
top_options = build_topic_list_options
|
||||
top_options.merge!(options) if options
|
||||
top_options[:per_page] = SiteSetting.topics_per_period_in_top_page
|
||||
|
||||
if "top".freeze == current_homepage
|
||||
top_options.merge!(exclude_category_ids: get_excluded_category_ids(top_options[:category]))
|
||||
end
|
||||
|
||||
user = list_target_user
|
||||
list = TopicQuery.new(user, top_options).list_top_for(period)
|
||||
list.for_period = period
|
||||
|
@ -177,15 +182,15 @@ class ListController < ApplicationController
|
|||
end
|
||||
|
||||
define_method("category_top_#{period}") do
|
||||
self.send("top_#{period}", { category: @category.id })
|
||||
self.send("top_#{period}", category: @category.id)
|
||||
end
|
||||
|
||||
define_method("category_none_top_#{period}") do
|
||||
self.send("top_#{period}", { category: @category.id, no_subcategories: true })
|
||||
self.send("top_#{period}", category: @category.id, no_subcategories: true)
|
||||
end
|
||||
|
||||
define_method("parent_category_category_top_#{period}") do
|
||||
self.send("top_#{period}", { category: @category.id })
|
||||
self.send("top_#{period}", category: @category.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -204,16 +209,15 @@ class ListController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def page_params(opts = nil)
|
||||
opts ||= {}
|
||||
route_params = {format: 'json'}
|
||||
route_params[:category] = @category.slug_for_url if @category
|
||||
route_params = { format: 'json' }
|
||||
route_params[:category] = @category.slug_for_url if @category
|
||||
route_params[:parent_category] = @category.parent_category.slug_for_url if @category && @category.parent_category
|
||||
route_params[:order] = opts[:order] if opts[:order].present?
|
||||
route_params[:ascending] = opts[:ascending] if opts[:ascending].present?
|
||||
route_params[:order] = opts[:order] if opts[:order].present?
|
||||
route_params[:ascending] = opts[:ascending] if opts[:ascending].present?
|
||||
route_params
|
||||
end
|
||||
|
||||
|
@ -235,11 +239,10 @@ class ListController < ApplicationController
|
|||
end
|
||||
|
||||
def build_topic_list_options
|
||||
# exclude_category = 1. from params / 2. parsed from top menu / 3. nil
|
||||
options = {
|
||||
page: params[:page],
|
||||
topic_ids: param_to_integer_list(:topic_ids),
|
||||
exclude_category: (params[:exclude_category] || select_menu_item.try(:filter)),
|
||||
exclude_category_ids: params[:exclude_category_ids],
|
||||
category: params[:category],
|
||||
order: params[:order],
|
||||
ascending: params[:ascending],
|
||||
|
@ -257,17 +260,6 @@ class ListController < ApplicationController
|
|||
options
|
||||
end
|
||||
|
||||
def select_menu_item
|
||||
menu_item = SiteSetting.top_menu_items.select do |mu|
|
||||
(mu.has_specific_category? && mu.specific_category == @category.try(:slug)) ||
|
||||
action_name == mu.name ||
|
||||
(action_name.include?("top") && mu.name == "top")
|
||||
end.first
|
||||
|
||||
menu_item = nil if menu_item.try(:has_specific_category?) && menu_item.specific_category == @category.try(:slug)
|
||||
menu_item
|
||||
end
|
||||
|
||||
def list_target_user
|
||||
if params[:user_id] && guardian.is_staff?
|
||||
User.find(params[:user_id].to_i)
|
||||
|
@ -290,25 +282,16 @@ class ListController < ApplicationController
|
|||
url.sub('.json?','?')
|
||||
end
|
||||
|
||||
def generate_top_lists(options)
|
||||
top = TopLists.new
|
||||
|
||||
options[:per_page] = SiteSetting.topics_per_period_in_top_summary
|
||||
topic_query = TopicQuery.new(current_user, options)
|
||||
|
||||
periods = [ListController.best_period_for(current_user.try(:previous_visit_at), options[:category])]
|
||||
|
||||
periods.each { |period| top.send("#{period}=", topic_query.list_top_for(period)) }
|
||||
|
||||
top
|
||||
def get_excluded_category_ids(current_category=nil)
|
||||
exclude_category_ids = Category.where(suppress_from_homepage: true)
|
||||
exclude_category_ids = exclude_category_ids.where.not(id: current_category) if current_category
|
||||
exclude_category_ids.pluck(:id)
|
||||
end
|
||||
|
||||
def self.best_period_for(previous_visit_at, category_id=nil)
|
||||
best_periods_for(previous_visit_at).each do |period|
|
||||
top_topics = TopTopic.where("#{period}_score > 0")
|
||||
if category_id
|
||||
top_topics = top_topics.joins(:topic).where("topics.category_id = ?", category_id)
|
||||
end
|
||||
top_topics = top_topics.joins(:topic).where("topics.category_id = ?", category_id) if category_id
|
||||
return period if top_topics.count >= SiteSetting.topics_per_period_in_top_page
|
||||
end
|
||||
# default period is yearly
|
||||
|
@ -318,8 +301,8 @@ class ListController < ApplicationController
|
|||
def self.best_periods_for(date)
|
||||
date ||= 1.year.ago
|
||||
periods = []
|
||||
periods << :daily if date > 8.days.ago
|
||||
periods << :weekly if date > 35.days.ago
|
||||
periods << :daily if date > 8.days.ago
|
||||
periods << :weekly if date > 35.days.ago
|
||||
periods << :monthly if date > 180.days.ago
|
||||
periods << :yearly
|
||||
periods
|
||||
|
|
|
@ -66,6 +66,8 @@ class CategoryList
|
|||
@categories = @categories.where('categories.parent_category_id = ?', @options[:parent_category_id].to_i)
|
||||
end
|
||||
|
||||
@categories = @categories.where(suppress_from_homepage: false) if @options[:is_homepage]
|
||||
|
||||
if SiteSetting.fixed_category_positions
|
||||
@categories = @categories.order('position ASC').order('id ASC')
|
||||
else
|
||||
|
|
|
@ -8,6 +8,7 @@ class CategorySerializer < BasicCategorySerializer
|
|||
:position,
|
||||
:email_in,
|
||||
:email_in_allow_strangers,
|
||||
:suppress_from_homepage,
|
||||
:can_delete,
|
||||
:cannot_delete_reason,
|
||||
:allow_badges,
|
||||
|
@ -56,4 +57,8 @@ class CategorySerializer < BasicCategorySerializer
|
|||
scope && scope.can_edit?(object)
|
||||
end
|
||||
|
||||
def include_suppress_from_homepage?
|
||||
scope && scope.can_edit?(object)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1539,6 +1539,7 @@ en:
|
|||
email_in_allow_strangers: "Accept emails from anonymous users with no accounts"
|
||||
email_in_disabled: "Posting new topics via email is disabled in the Site Settings. To enable posting new topics via email, "
|
||||
email_in_disabled_click: 'enable the "email in" setting.'
|
||||
suppress_from_homepage: "Suppress this category from the homepage."
|
||||
allow_badges_label: "Allow badges to be awarded in this category"
|
||||
edit_permissions: "Edit Permissions"
|
||||
add_permission: "Add Permission"
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddSuppressFromHomepageToCategory < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :categories, :suppress_from_homepage, :boolean, default: false
|
||||
end
|
||||
end
|
|
@ -64,18 +64,10 @@ module Discourse
|
|||
@filters ||= [:latest, :unread, :new, :read, :posted, :bookmarks]
|
||||
end
|
||||
|
||||
def self.feed_filters
|
||||
@feed_filters ||= [:latest]
|
||||
end
|
||||
|
||||
def self.anonymous_filters
|
||||
@anonymous_filters ||= [:latest, :top, :categories]
|
||||
end
|
||||
|
||||
def self.logged_in_filters
|
||||
@logged_in_filters ||= Discourse.filters - Discourse.anonymous_filters
|
||||
end
|
||||
|
||||
def self.top_menu_items
|
||||
@top_menu_items ||= Discourse.filters + [:category, :categories, :top]
|
||||
end
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
#
|
||||
# Helps us find topics. Returns a TopicList object containing the topics
|
||||
# found.
|
||||
# Helps us find topics.
|
||||
# Returns a TopicList object containing the topics found.
|
||||
#
|
||||
|
||||
require_dependency 'topic_list'
|
||||
require_dependency 'suggested_topics_builder'
|
||||
require_dependency 'topic_query_sql'
|
||||
|
||||
class TopicQuery
|
||||
# Could be rewritten to %i if Ruby 1.9 is no longer supported
|
||||
VALID_OPTIONS = %w(except_topic_ids
|
||||
exclude_category
|
||||
VALID_OPTIONS = %i(except_topic_ids
|
||||
exclude_category_ids
|
||||
limit
|
||||
page
|
||||
per_page
|
||||
|
@ -27,8 +28,7 @@ class TopicQuery
|
|||
search
|
||||
slow_platform
|
||||
filter
|
||||
q
|
||||
).map(&:to_sym)
|
||||
q)
|
||||
|
||||
# Maps `order` to a columns in `topics`
|
||||
SORTABLE_MAPPING = {
|
||||
|
@ -301,14 +301,17 @@ class TopicQuery
|
|||
if options[:no_subcategories]
|
||||
result = result.where('categories.id = ?', category_id)
|
||||
else
|
||||
result = result.where('categories.id = ? or (categories.parent_category_id = ? AND categories.topic_id <> topics.id)', category_id, category_id)
|
||||
result = result.where('categories.id = :category_id OR (categories.parent_category_id = :category_id AND categories.topic_id <> topics.id)', category_id: category_id)
|
||||
end
|
||||
result = result.references(:categories)
|
||||
end
|
||||
|
||||
result = apply_ordering(result, options)
|
||||
result = result.listable_topics.includes(:category)
|
||||
result = result.where('categories.name is null or categories.name <> ?', options[:exclude_category]).references(:categories) if options[:exclude_category]
|
||||
|
||||
if options[:exclude_category_ids] && options[:exclude_category_ids].is_a?(Array) && options[:exclude_category_ids].size > 0
|
||||
result = result.where("categories.id NOT IN (?)", options[:exclude_category_ids]).references(:categories)
|
||||
end
|
||||
|
||||
# Don't include the category topics if excluded
|
||||
if options[:no_definitions]
|
||||
|
@ -393,19 +396,20 @@ class TopicQuery
|
|||
|
||||
def remove_muted_categories(list, user, opts=nil)
|
||||
category_id = get_category_id(opts[:exclude]) if opts
|
||||
|
||||
if user
|
||||
list = list.where("NOT EXISTS(
|
||||
SELECT 1 FROM category_users cu
|
||||
WHERE cu.user_id = ? AND
|
||||
cu.category_id = topics.category_id AND
|
||||
cu.notification_level = ? AND
|
||||
cu.category_id <> ?
|
||||
)",
|
||||
user.id,
|
||||
CategoryUser.notification_levels[:muted],
|
||||
category_id || -1
|
||||
)
|
||||
.references('cu')
|
||||
list = list.references("cu")
|
||||
.where("
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM category_users cu
|
||||
WHERE cu.user_id = :user_id
|
||||
AND cu.category_id = topics.category_id
|
||||
AND cu.notification_level = :muted
|
||||
AND cu.category_id <> :category_id
|
||||
)", user_id: user.id,
|
||||
muted: CategoryUser.notification_levels[:muted],
|
||||
category_id: category_id || -1)
|
||||
end
|
||||
|
||||
list
|
||||
|
|
|
@ -32,12 +32,6 @@ describe ListController do
|
|||
end
|
||||
end
|
||||
|
||||
Discourse.logged_in_filters.each do |filter|
|
||||
context "#{filter}" do
|
||||
it { expect { xhr :get, filter }.to raise_error(Discourse::NotLoggedIn) }
|
||||
end
|
||||
end
|
||||
|
||||
it 'allows users to filter on a set of topic ids' do
|
||||
p = create_post
|
||||
|
||||
|
@ -51,14 +45,10 @@ describe ListController do
|
|||
|
||||
describe 'RSS feeds' do
|
||||
|
||||
Discourse.feed_filters.each do |filter|
|
||||
|
||||
it 'renders RSS' do
|
||||
get "#{filter}_feed", format: :rss
|
||||
expect(response).to be_success
|
||||
expect(response.content_type).to eq('application/rss+xml')
|
||||
end
|
||||
|
||||
it 'renders RSS' do
|
||||
get "latest_feed", format: :rss
|
||||
expect(response).to be_success
|
||||
expect(response.content_type).to eq('application/rss+xml')
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue