FEATURE: remove star concept from Discourse

This commit is contained in:
Sam 2015-01-07 12:19:23 +11:00
parent fa8493118b
commit efc717c14a
35 changed files with 50 additions and 448 deletions

View File

@ -57,7 +57,6 @@
{{ render 'admin_report_counts' likes }}
{{ render 'admin_report_counts' flags }}
{{ render 'admin_report_counts' bookmarks }}
{{ render 'admin_report_counts' starred }}
{{ render 'admin_report_counts' emails }}
{{/unless}}
</table>

View File

@ -165,7 +165,7 @@ var controllerOpts = {
var split = this.get('filter').split('/');
if (split[0] !== 'new' && split[0] !== 'unread' && split[0] !== 'starred') { return; }
if (split[0] !== 'new' && split[0] !== 'unread') { return; }
return I18n.t("topics.none.educate." + split[0], {
userPrefsUrl: Discourse.getURL("/users/") + (Discourse.User.currentProp("username_lower")) + "/preferences"

View File

@ -3,7 +3,6 @@ var PATH_BINDINGS = {
'g l': '/latest',
'g n': '/new',
'g u': '/unread',
'g f': '/starred',
'g c': '/categories',
'g t': '/top'
},

View File

@ -74,7 +74,7 @@ Discourse.NavItem.reopenClass({
if (!Discourse.Category.list() && testName === "categories") return null;
if (!Discourse.Site.currentProp('top_menu_items').contains(testName)) return null;
var args = { name: name, hasIcon: name === "unread" || name === "starred" };
var args = { name: name, hasIcon: name === "unread" };
if (opts.category) { args.category = opts.category; }
if (opts.noSubcategories) { args.noSubcategories = true; }
return Discourse.NavItem.create(args);

View File

@ -172,14 +172,6 @@ Discourse.Topic = Discourse.Model.extend({
.then(function () { self.set('archetype', 'regular'); });
},
starTooltipKey: function() {
return this.get('starred') ? 'starred.help.unstar' : 'starred.help.star';
}.property('starred'),
starTooltip: function() {
return I18n.t(this.get('starTooltipKey'));
}.property('starTooltipKey'),
estimatedReadingTime: function() {
var wordCount = this.get('word_count');
if (!wordCount) return;
@ -188,15 +180,15 @@ Discourse.Topic = Discourse.Model.extend({
return Math.floor(wordCount / 500.0);
}.property('word_count'),
toggleStar: function() {
toggleBookmark: function() {
var topic = this;
topic.toggleProperty('starred');
topic.toggleProperty('bookmarked');
return Discourse.ajax({
url: "" + (this.get('url')) + "/star",
url: "" + (this.get('url')) + "/bookmark",
type: 'PUT',
data: { starred: topic.get('starred') ? true : false }
data: { bookmarked: topic.get('bookmarked') ? true : false }
}).then(null, function (error) {
topic.toggleProperty('starred');
topic.toggleProperty('bookmarked');
if (error && error.responseText) {
bootbox.alert($.parseJSON(error.responseText).errors);

View File

@ -16,7 +16,6 @@ var UserActionTypes = {
replies: 6,
mentions: 7,
quotes: 9,
starred: 10,
edits: 11,
messages_sent: 12,
messages_received: 13
@ -127,8 +126,6 @@ Discourse.UserAction = Discourse.Model.extend({
case UserActionTypes.likes_given:
case UserActionTypes.likes_received:
return "likes";
case UserActionTypes.starred:
return "stars";
case UserActionTypes.edits:
return "edits";
case UserActionTypes.bookmarks:
@ -205,7 +202,6 @@ Discourse.UserAction.reopenClass({
TO_COLLAPSE: [
UserActionTypes.likes_given,
UserActionTypes.likes_received,
UserActionTypes.starred,
UserActionTypes.edits,
UserActionTypes.bookmarks
],
@ -213,7 +209,6 @@ Discourse.UserAction.reopenClass({
TO_SHOW: [
UserActionTypes.likes_given,
UserActionTypes.likes_received,
UserActionTypes.starred,
UserActionTypes.edits,
UserActionTypes.bookmarks,
UserActionTypes.messages_sent,

View File

@ -1,9 +0,0 @@
import UserTopicListRoute from "discourse/routes/user-topic-list";
export default UserTopicListRoute.extend({
userActionType: Discourse.UserAction.TYPES.starred,
model: function() {
return Discourse.TopicList.find('starred', { user_id: this.modelFor('user').get('id') });
}
});

View File

@ -7,7 +7,6 @@
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.latest'}}}</li>
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.new'}}}</li>
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.unread'}}}</li>
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.starred'}}}</li>
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.categories'}}}</li>
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.top'}}}</li>
</ul>

View File

@ -54,7 +54,6 @@ export default Ember.Component.extend(StringBuffer, {
case Discourse.UserAction.TYPES.bookmarks: return "bookmark";
case Discourse.UserAction.TYPES.edits: return "pencil";
case Discourse.UserAction.TYPES.replies: return "reply";
case Discourse.UserAction.TYPES.starred: return "star";
}
}.property("content.action_type")
});

View File

@ -1,21 +0,0 @@
import ButtonView from 'discourse/views/button';
export default ButtonView.extend({
classNames: ['star'],
textKey: 'starred.title',
helpKeyBinding: 'controller.starTooltipKey',
attributeBindings: ['disabled'],
rerenderTriggers: ['controller.starred'],
click: function() {
this.get('controller').send('toggleStar');
},
renderIcon: function(buffer) {
buffer.push("<i class='fa fa-star " +
(this.get('controller.starred') ? ' starred' : '') +
"'></i>");
}
});

View File

@ -1,7 +1,6 @@
import TopicAdminMenuButton from 'discourse/views/topic-admin-menu-button';
import LoginReplyButton from 'discourse/views/login-reply-button';
import FlagTopicButton from 'discourse/views/flag-topic-button';
import StarButton from 'discourse/views/star-button';
import ShareButton from 'discourse/views/share-button';
import InviteReplyButton from 'discourse/views/invite-reply-button';
import ReplyButton from 'discourse/views/reply-button';
@ -30,7 +29,6 @@ export default DiscourseContainerView.extend({
if (this.get('topic.details.can_invite_to')) {
this.attachViewClass(InviteReplyButton);
}
this.attachViewClass(StarButton);
this.attachViewClass(ShareButton);
if (this.get('topic.details.can_flag_topic')) {
this.attachViewClass(FlagTopicButton);

View File

@ -10,9 +10,6 @@
margin-right: 4px;
font: 1.071em/0.9 "FontAwesome";
}
.has-icon .starred:before {
content: "\f005";
}
}
}

View File

@ -36,24 +36,12 @@ body {
}
}
#main {
.fa-star.starred {
color: $danger;
}
a.star {
color: dark-light-diff($secondary, $primary, 80%, -20%);
&:before {
font-family: "FontAwesome";
content: "\f005";
}
&.starred {
color: $danger;
@include hover {
opacity: 1;
&:before {
content: "\f005";
}
}
}
@include hover {
opacity: 0.6;
}

View File

@ -551,12 +551,6 @@ video {
line-height: 1.3em;
}
a.star {
margin: 0 7px 20px 2px;
color: dark-light-diff($secondary, $primary, 80%, -20%) !important;
}
a.star.starred {color: $danger !important;}
.topic-statuses {
margin-top: -2px;
}

View File

@ -18,36 +18,6 @@ body {
}
}
#main {
.fa-star.starred {
color: $danger;
}
a.star {
display: inline-block;
font-size: 1.429em;
color: scale-color($primary, $lightness: 75%);
margin-right: 8px;
margin-top: 4px;
&:before {
font-family: "FontAwesome";
content: "\f005";
}
&.starred {
color: $danger;
@include hover {
opacity: 1;
&:before {
content: "\f005";
}
}
}
@include hover {
opacity: 0.6;
}
&:active {
opacity: 1;
}
}
img.avatar {
&.header {
width: 45px;

View File

@ -166,14 +166,6 @@ class TopicsController < ApplicationController
render nothing: true
end
def star
@topic = Topic.find_by(id: params[:topic_id].to_i)
guardian.ensure_can_see!(@topic)
@topic.toggle_star(current_user, params[:starred] == 'true')
render nothing: true
end
def mute
toggle_mute
end

View File

@ -11,7 +11,6 @@ class AdminDashboardData
'users_by_trust_level',
'likes',
'bookmarks',
'starred',
'emails',
'user_to_user_private_messages',
'system_private_messages',

View File

@ -91,13 +91,7 @@ class Report
end
end
def self.report_starred(report)
basic_report_about report, Topic, :starred_counts_per_day, default_days
add_counts report, TopicUser.where(starred: true), 'topic_users.starred_at'
end
# Post action counts:
def self.report_flags(report)
basic_report_about report, PostAction, :flag_count_by_date, report.start_date, report.end_date
add_counts report, PostAction.where(post_action_type_id: PostActionType.flag_types.values), 'post_actions.created_at'

View File

@ -141,13 +141,6 @@ class Topic < ActiveRecord::Base
WHERE #{condition[0]})", condition[1])
}
# Helps us limit how many topics can be starred in a day
class StarLimiter < RateLimiter
def initialize(user)
super(user, "starred:#{Date.today}", SiteSetting.max_stars_per_day, 1.day.to_i)
end
end
attr_accessor :ignore_category_auto_close
attr_accessor :skip_callbacks
@ -612,27 +605,6 @@ class Topic < ActiveRecord::Base
@participants_summary ||= TopicParticipantsSummary.new(self, options).summary
end
# Enable/disable the star on the topic
def toggle_star(user, starred)
Topic.transaction do
TopicUser.change(user, id, {starred: starred}.merge( starred ? {starred_at: DateTime.now, unstarred_at: nil} : {unstarred_at: DateTime.now}))
# Update the star count
exec_sql "UPDATE topics
SET star_count = (SELECT COUNT(*)
FROM topic_users AS ftu
WHERE ftu.topic_id = topics.id
AND ftu.starred = true)
WHERE id = ?", id
if starred
StarLimiter.new(user).performed!
else
StarLimiter.new(user).rollback!
end
end
end
def make_banner!(user)
# only one banner at the same time
previous_banner = Topic.where(archetype: Archetype.banner).first
@ -662,10 +634,6 @@ class Topic < ActiveRecord::Base
}
end
def self.starred_counts_per_day(sinceDaysAgo=30)
TopicUser.starred_since(sinceDaysAgo).by_date_starred.count
end
# Even if the slug column in the database is null, topic.slug will return something:
def slug
unless slug = read_attribute(:slug)

View File

@ -2,9 +2,6 @@ class TopicUser < ActiveRecord::Base
belongs_to :user
belongs_to :topic
scope :starred_since, lambda { |sinceDaysAgo| where('starred_at > ?', sinceDaysAgo.days.ago) }
scope :by_date_starred, -> { group('date(starred_at)').order('date(starred_at)') }
scope :tracking, lambda { |topic_id|
where(topic_id: topic_id)
.where("COALESCE(topic_users.notification_level, :regular) >= :tracking",
@ -86,8 +83,6 @@ class TopicUser < ActiveRecord::Base
TopicUser.transaction do
attrs = attrs.dup
attrs[:starred_at] = DateTime.now if attrs[:starred_at].nil? && attrs[:starred]
if attrs[:notification_level]
attrs[:notifications_changed_at] ||= DateTime.now
attrs[:notifications_reason_id] ||= TopicUser.notification_reasons[:user_changed]

View File

@ -14,7 +14,6 @@ class UserAction < ActiveRecord::Base
RESPONSE= 6
MENTION = 7
QUOTE = 9
STAR = 10
EDIT = 11
NEW_PRIVATE_MESSAGE = 12
GOT_PRIVATE_MESSAGE = 13
@ -30,7 +29,6 @@ class UserAction < ActiveRecord::Base
MENTION,
QUOTE,
BOOKMARK,
STAR,
EDIT
].each_with_index.to_a.flatten]
@ -240,35 +238,8 @@ SQL
builder.exec
end
def self.synchronize_starred
exec_sql("
DELETE FROM user_actions ua
WHERE action_type = :star
AND NOT EXISTS (
SELECT 1 FROM topic_users tu
WHERE
tu.user_id = ua.user_id AND
tu.topic_id = ua.target_topic_id AND
starred
)", star: UserAction::STAR)
exec_sql("INSERT INTO user_actions
(action_type, user_id, target_topic_id, target_post_id, acting_user_id, created_at, updated_at)
SELECT :star, tu.user_id, tu.topic_id, -1, tu.user_id, tu.starred_at, tu.starred_at
FROM topic_users tu
WHERE starred AND NOT EXISTS(
SELECT 1 FROM user_actions ua
WHERE tu.user_id = ua.user_id AND
tu.topic_id = ua.target_topic_id AND
ua.action_type = :star
)
", star: UserAction::STAR)
end
def self.ensure_consistency!
self.synchronize_target_topic_ids
self.synchronize_starred
end
def self.update_like_count(user_id, action_type, delta)
@ -294,7 +265,7 @@ SQL
end
unless (guardian.user && guardian.user.id == user_id) || guardian.is_staff?
builder.where("a.action_type not in (#{BOOKMARK},#{STAR})")
builder.where("a.action_type not in (#{BOOKMARK})")
builder.where("t.visible")
end

View File

@ -9,27 +9,6 @@ class UserActionObserver < ActiveRecord::Observer
log_topic(model)
when (model.is_a?(Post))
log_post(model)
when (model.is_a?(TopicUser))
log_topic_user(model)
end
end
def log_topic_user(model)
action = UserAction::STAR
row = {
action_type: action,
user_id: model.user_id,
acting_user_id: model.user_id,
target_topic_id: model.topic_id,
target_post_id: -1,
created_at: model.starred_at
}
if model.starred
UserAction.log_action!(row)
else
UserAction.remove_action!(row)
end
end

View File

@ -2,7 +2,6 @@ class TopicListItemSerializer < ListableTopicSerializer
attributes :views,
:like_count,
:starred,
:has_summary,
:archetype,
:last_poster_username,
@ -13,12 +12,6 @@ class TopicListItemSerializer < ListableTopicSerializer
has_many :posters, serializer: TopicPosterSerializer, embed: :objects
has_many :participants, serializer: TopicPosterSerializer, embed: :objects
def starred
object.user_data.starred?
end
alias :include_starred? :has_user_data
def posters
object.posters || []
end

View File

@ -29,7 +29,6 @@ class TopicViewSerializer < ApplicationSerializer
attributes :draft,
:draft_key,
:draft_sequence,
:starred,
:posted,
:unpinned,
:pinned_globally,
@ -145,11 +144,6 @@ class TopicViewSerializer < ApplicationSerializer
object.topic_user.present?
end
def starred
object.topic_user.starred?
end
alias_method :include_starred?, :has_topic_user?
def highest_post_number
object.highest_post_number
end

View File

@ -785,12 +785,6 @@ en:
not_logged_in_user: 'user page with summary of current activity and preferences'
current_user: 'go to your user page'
starred:
title: 'Star'
help:
star: 'add this topic to your starred list'
unstar: 'remove this topic from your starred list'
topics:
bulk:
reset_read: "Reset Read"
@ -811,7 +805,6 @@ en:
other: "You have selected <b>{{count}}</b> topics."
none:
starred: "You have no starred topics."
unread: "You have no unread topics."
new: "You have no new topics."
read: "You haven't read any topics yet."
@ -823,7 +816,6 @@ en:
educate:
new: '<p>Your new topics appear here.</p><p>By default, topics are considered new and will show a <span class="badge new-topic badge-notification" style="vertical-align:middle;line-height:inherit;">new</span> indicator if they were created in the last 2 days.</p><p>You can change this in your <a href="%{userPrefsUrl}">preferences</a>.</p>'
unread: '<p>Your unread topics appear here.</p><p>By default, topics are considered unread and will show unread counts <span class="badge new-posts badge-notification">1</span> if you:</p><ul><li>Created the topic</li><li>Replied to the topic</li><li>Read the topic for more than 4 minutes</li></ul><p>Or if you have explicitly set the topic to Tracked or Watched via the notification control at the bottom of each topic.</p><p>You can change this in your <a href="%{userPrefsUrl}">preferences</a>.</p>'
starred: '<p>Your starred topics appear here.</p><p>To star or unstar a topic, use:</p><ul><li>the <i class="fa fa-star"></i> next to any topic title</li><li>the Star button at the bottom of each topic</li></ul>'
bottom:
latest: "There are no more latest topics."
hot: "There are no more hot topics."
@ -831,7 +823,6 @@ en:
read: "There are no more read topics."
new: "There are no more new topics."
unread: "There are no more unread topics."
starred: "There are no more starred topics."
category: "There are no more {{category}} topics."
top: "There are no more top topics."
@ -1433,9 +1424,6 @@ en:
hot:
title: "Hot"
help: "a selection of the hottest topics"
starred:
title: "Starred"
help: "topics you starred"
read:
title: "Read"
help: "topics you've read, in the order that you last read them"
@ -2217,7 +2205,6 @@ en:
latest: '<b>g</b>, <b>l</b> Latest'
new: '<b>g</b>, <b>n</b> New'
unread: '<b>g</b>, <b>u</b> Unread'
starred: '<b>g</b>, <b>f</b> Starred'
categories: '<b>g</b>, <b>c</b> Categories'
top: '<b>g</b>, <b>t</b> Top'
navigation:

View File

@ -0,0 +1,29 @@
class RemoveStars < ActiveRecord::Migration
def up
r = execute <<SQL
INSERT INTO post_actions(user_id, post_id, post_action_type_id, created_at, updated_at)
SELECT tu.user_id, p.id, 1, coalesce(tu.starred_at, now()), coalesce(tu.starred_at, now())
FROM topic_users tu
JOIN posts p ON p.topic_id = tu.topic_id AND p.post_number = 1
LEFT JOIN post_actions pa ON
pa.post_id = p.id AND
pa.user_id = tu.user_id AND
pa.post_action_type_id = 1
WHERE pa.post_id IS NULL AND tu.starred
SQL
puts "#{r.cmd_tuples} stars were converted to bookmarks!"
execute <<SQL
DELETE FROM user_actions WHERE action_type = 10
SQL
remove_column :topic_users, :starred
remove_column :topic_users, :starred_at
remove_column :topic_users, :unstarred_at
remove_column :topics, :star_count
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -56,7 +56,7 @@ module Discourse
class CSRF < Exception; end
def self.filters
@filters ||= [:latest, :unread, :new, :starred, :read, :posted]
@filters ||= [:latest, :unread, :new, :read, :posted]
end
def self.feed_filters

View File

@ -69,11 +69,6 @@ class TopicQuery
create_list(:latest, {}, latest_results)
end
# The starred topics
def list_starred
create_list(:starred) {|topics| topics.where('tu.starred') }
end
def list_read
create_list(:read, unordered: true) do |topics|
topics.order('COALESCE(tu.last_visited_at, topics.bumped_at) DESC')

View File

@ -285,27 +285,6 @@ describe TopicQuery do
end
context 'list_starred' do
let(:topic) { Fabricate(:topic) }
it "returns no results when the user hasn't starred any topics" do
topic_query.list_starred.topics.should be_blank
end
context 'with a starred topic' do
before do
topic.toggle_star(user, true)
end
it "returns the topic after it has been starred" do
topic_query.list_starred.topics.should == [topic]
end
end
end
context 'list_new' do
context 'without a new topic' do
@ -386,11 +365,6 @@ describe TopicQuery do
end
context "but interacted with" do
it "is not included if starred" do
other_users_topic.toggle_star(user, true)
topics.should be_blank
end
it "is not included if read" do
TopicUser.update_last_read(user, other_users_topic.id, 0, 0)

View File

@ -184,22 +184,6 @@ describe ListController do
end
end
context 'starred' do
it 'raises an error when not logged in' do
lambda { xhr :get, :starred }.should raise_error(Discourse::NotLoggedIn)
end
context 'when logged in' do
before do
log_in_user(@user)
xhr :get, :starred
end
it { should respond_with(:success) }
end
end
context 'read' do
it 'raises an error when not logged in' do
lambda { xhr :get, :read }.should raise_error(Discourse::NotLoggedIn)

View File

@ -436,49 +436,10 @@ describe TopicsController do
@topic = Fabricate(:topic, user: log_in)
end
it "changes the user's starred flag when the parameter is present" do
Topic.any_instance.expects(:toggle_mute).with(@topic.user)
xhr :put, :mute, topic_id: @topic.id, starred: 'true'
end
it "removes the user's starred flag when the parameter is not true" do
Topic.any_instance.expects(:toggle_mute).with(@topic.user)
xhr :put, :unmute, topic_id: @topic.id, starred: 'false'
end
end
end
describe 'star' do
it 'needs you to be logged in' do
lambda { xhr :put, :star, topic_id: 1, starred: true }.should raise_error(Discourse::NotLoggedIn)
end
describe 'when logged in' do
before do
@topic = Fabricate(:topic, user: log_in)
end
it "ensures the user can see the topic" do
Guardian.any_instance.expects(:can_see?).with(@topic).returns(false)
xhr :put, :star, topic_id: @topic.id, starred: 'true'
response.should be_forbidden
end
it "changes the user's starred flag when the parameter is present" do
Topic.any_instance.expects(:toggle_star).with(@topic.user, true)
xhr :put, :star, topic_id: @topic.id, starred: 'true'
end
it "removes the user's starred flag when the parameter is not true" do
Topic.any_instance.expects(:toggle_star).with(@topic.user, false)
xhr :put, :star, topic_id: @topic.id, starred: 'false'
end
end
end
describe 'recover' do
it "won't allow us to recover a topic when we're not logged in" do
lambda { xhr :put, :recover, topic_id: 1 }.should raise_error(Discourse::NotLoggedIn)

View File

@ -1,4 +1,4 @@
Fabricator(:user_action) do
user
action_type UserAction::STAR
action_type UserAction::BOOKMARK
end

View File

@ -562,70 +562,6 @@ describe Topic do
end
end
describe 'toggle_star' do
shared_examples_for "adding a star to a topic" do
it 'triggers a forum topic user change with true' do
# otherwise no chance the mock will work
freeze_time
TopicUser.expects(:change).with(@user, @topic.id, starred: true, starred_at: DateTime.now, unstarred_at: nil)
@topic.toggle_star(@user, true)
end
it 'increases the star_count of the forum topic' do
expect {
@topic.toggle_star(@user, true)
@topic.reload
}.to change(@topic, :star_count).by(1)
end
it 'triggers the rate limiter' do
Topic::StarLimiter.any_instance.expects(:performed!)
@topic.toggle_star(@user, true)
end
end
before do
@topic = Fabricate(:topic)
@user = @topic.user
end
it_should_behave_like "adding a star to a topic"
describe 'removing a star' do
before do
@topic.toggle_star(@user, true)
@topic.reload
end
it 'rolls back the rate limiter' do
Topic::StarLimiter.any_instance.expects(:rollback!)
@topic.toggle_star(@user, false)
end
it 'triggers a forum topic user change with false' do
freeze_time
TopicUser.expects(:change).with(@user, @topic.id, starred: false, unstarred_at: DateTime.now)
@topic.toggle_star(@user, false)
end
it 'reduces the star_count' do
expect {
@topic.toggle_star(@user, false)
@topic.reload
}.to change(@topic, :star_count).by(-1)
end
describe 'and adding a star again' do
before do
@topic.toggle_star(@user, false)
@topic.reload
end
it_should_behave_like "adding a star to a topic"
end
end
end
describe "banner" do
let(:topic) { Fabricate(:topic) }

View File

@ -20,14 +20,14 @@ describe TopicUser do
let(:topic_new_user) { TopicUser.get(topic, new_user)}
let(:yesterday) { DateTime.now.yesterday }
def ensure_topic_user
TopicUser.change(user, topic, last_emailed_post_number: 1)
end
describe "unpinned" do
before do
TopicUser.change(user, topic, {starred_at: yesterday})
end
it "defaults to blank" do
ensure_topic_user
topic_user.cleared_pinned_at.should be_blank
end
@ -37,19 +37,19 @@ describe TopicUser do
it 'should be set to tracking if auto_track_topics is enabled' do
user.update_column(:auto_track_topics_after_msecs, 0)
TopicUser.change(user, topic, {starred_at: yesterday})
ensure_topic_user
TopicUser.get(topic, user).notification_level.should == TopicUser.notification_levels[:tracking]
end
it 'should reset regular topics to tracking topics if auto track is changed' do
TopicUser.change(user, topic, {starred_at: yesterday})
ensure_topic_user
user.auto_track_topics_after_msecs = 0
user.save
topic_user.notification_level.should == TopicUser.notification_levels[:tracking]
end
it 'should be set to "regular" notifications, by default on non creators' do
TopicUser.change(user, topic, {starred_at: yesterday})
ensure_topic_user
TopicUser.get(topic,user).notification_level.should == TopicUser.notification_levels[:regular]
end
@ -195,37 +195,20 @@ describe TopicUser do
describe 'change a flag' do
it 'creates a forum topic user record' do
user; topic
lambda {
TopicUser.change(user, topic.id, starred: true)
}.should change(TopicUser, :count).by(1)
end
it "only inserts a row once, even on repeated calls" do
topic; user
lambda {
TopicUser.change(user, topic.id, starred: true)
TopicUser.change(user, topic.id, starred: false)
TopicUser.change(user, topic.id, starred: true)
TopicUser.change(user, topic.id, total_msecs_viewed: 1)
TopicUser.change(user, topic.id, total_msecs_viewed: 2)
TopicUser.change(user, topic.id, total_msecs_viewed: 3)
}.should change(TopicUser, :count).by(1)
end
it 'triggers the observer callbacks when updating' do
UserActionObserver.instance.expects(:after_save).twice
3.times { TopicUser.change(user, topic.id, starred: true) }
end
describe 'after creating a row' do
before do
TopicUser.change(user, topic.id, starred: true)
end
it 'has the correct starred value' do
TopicUser.get(topic, user).should be_starred
ensure_topic_user
end
it 'has a lookup' do

View File

@ -257,38 +257,6 @@ describe UserAction do
end
describe 'synchronize_starred' do
it 'corrects out of sync starred' do
post = Fabricate(:post)
post.topic.toggle_star(post.user, true)
UserAction.delete_all
UserAction.log_action!(
action_type: UserAction::STAR,
user_id: post.user.id,
acting_user_id: post.user.id,
target_topic_id: 99,
target_post_id: -1,
)
UserAction.log_action!(
action_type: UserAction::STAR,
user_id: Fabricate(:user).id,
acting_user_id: post.user.id,
target_topic_id: post.topic_id,
target_post_id: -1,
)
UserAction.synchronize_starred
actions = UserAction.all.to_a
expect(actions.length).to eq(1)
expect(actions.first.action_type).to eq(UserAction::STAR)
expect(actions.first.user_id).to eq(post.user.id)
end
end
describe 'synchronize_target_topic_ids' do
it 'correct target_topic_id' do
post = Fabricate(:post)