2013-02-05 14:16:51 -05:00
require 'spec_helper'
describe TopicUser do
it { should belong_to :user }
it { should belong_to :topic }
2013-12-30 13:02:12 +11:00
let ( :user ) { Fabricate ( :user ) }
2013-03-06 15:17:07 -05:00
2013-12-30 13:02:12 +11:00
let ( :topic ) {
u = Fabricate ( :user )
guardian = Guardian . new ( u )
TopicCreator . create ( u , guardian , title : " this is my topic title " )
2013-07-22 11:40:39 +10:00
}
2013-03-06 15:17:07 -05:00
let ( :topic_user ) { TopicUser . get ( topic , user ) }
let ( :topic_creator_user ) { TopicUser . get ( topic , topic . user ) }
let ( :post ) { Fabricate ( :post , topic : topic , user : user ) }
let ( :new_user ) { Fabricate ( :user , auto_track_topics_after_msecs : 1000 ) }
let ( :topic_new_user ) { TopicUser . get ( topic , new_user ) }
2013-12-30 13:02:12 +11:00
let ( :yesterday ) { DateTime . now . yesterday }
2013-03-06 15:17:07 -05:00
describe " unpinned " do
before do
2013-03-23 20:32:59 +05:30
TopicUser . change ( user , topic , { starred_at : yesterday } )
2013-03-06 15:17:07 -05:00
end
it " defaults to blank " do
topic_user . cleared_pinned_at . should be_blank
end
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
describe 'notifications' do
2013-02-05 14:16:51 -05:00
2013-02-25 19:42:20 +03:00
it 'should be set to tracking if auto_track_topics is enabled' do
2013-03-06 15:17:07 -05:00
user . update_column ( :auto_track_topics_after_msecs , 0 )
2013-03-23 20:32:59 +05:30
TopicUser . change ( user , topic , { starred_at : yesterday } )
2013-03-06 15:17:07 -05:00
TopicUser . get ( topic , user ) . notification_level . should == TopicUser . notification_levels [ :tracking ]
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'should reset regular topics to tracking topics if auto track is changed' do
2013-03-23 20:32:59 +05:30
TopicUser . change ( user , topic , { starred_at : yesterday } )
2013-03-06 15:17:07 -05:00
user . auto_track_topics_after_msecs = 0
user . save
topic_user . notification_level . should == TopicUser . notification_levels [ :tracking ]
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'should be set to "regular" notifications, by default on non creators' do
2013-03-23 20:32:59 +05:30
TopicUser . change ( user , topic , { starred_at : yesterday } )
2013-03-06 15:17:07 -05:00
TopicUser . get ( topic , user ) . notification_level . should == TopicUser . notification_levels [ :regular ]
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'reason should reset when changed' do
2013-03-06 15:17:07 -05:00
topic . notify_muted! ( topic . user )
TopicUser . get ( topic , topic . user ) . notifications_reason_id . should == TopicUser . notification_reasons [ :user_changed ]
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'should have the correct reason for a user change when watched' do
2013-03-06 15:17:07 -05:00
topic . notify_watch! ( user )
topic_user . notification_level . should == TopicUser . notification_levels [ :watching ]
topic_user . notifications_reason_id . should == TopicUser . notification_reasons [ :user_changed ]
topic_user . notifications_changed_at . should_not be_nil
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'should have the correct reason for a user change when set to regular' do
2013-03-06 15:17:07 -05:00
topic . notify_regular! ( user )
topic_user . notification_level . should == TopicUser . notification_levels [ :regular ]
topic_user . notifications_reason_id . should == TopicUser . notification_reasons [ :user_changed ]
topic_user . notifications_changed_at . should_not be_nil
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'should have the correct reason for a user change when set to regular' do
2013-03-06 15:17:07 -05:00
topic . notify_muted! ( user )
topic_user . notification_level . should == TopicUser . notification_levels [ :muted ]
topic_user . notifications_reason_id . should == TopicUser . notification_reasons [ :user_changed ]
topic_user . notifications_changed_at . should_not be_nil
2013-02-05 14:16:51 -05:00
end
it 'should watch topics a user created' do
2013-03-06 15:17:07 -05:00
topic_creator_user . notification_level . should == TopicUser . notification_levels [ :watching ]
topic_creator_user . notifications_reason_id . should == TopicUser . notification_reasons [ :created_topic ]
2013-02-05 14:16:51 -05:00
end
end
describe 'visited at' do
2013-03-06 15:17:07 -05:00
before do
TopicUser . track_visit! ( topic , user )
2013-02-25 19:42:20 +03:00
end
it 'set upon initial visit' do
2013-12-30 13:02:12 +11:00
freeze_time yesterday do
topic_user . first_visited_at . to_i . should == yesterday . to_i
topic_user . last_visited_at . to_i . should == yesterday . to_i
end
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'updates upon repeat visit' do
2013-03-06 15:17:07 -05:00
today = yesterday . tomorrow
2013-02-25 19:42:20 +03:00
2013-12-30 13:02:12 +11:00
freeze_time today do
TopicUser . track_visit! ( topic , user )
# reload is a no go
topic_user = TopicUser . get ( topic , user )
topic_user . first_visited_at . to_i . should == yesterday . to_i
topic_user . last_visited_at . to_i . should == today . to_i
end
2013-02-05 14:16:51 -05:00
end
2013-05-21 20:45:03 -07:00
it 'triggers the observer callbacks when updating' do
UserActionObserver . instance . expects ( :after_save ) . twice
2 . times { TopicUser . track_visit! ( topic , user ) }
end
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
describe 'read tracking' do
2013-02-05 14:16:51 -05:00
2013-03-06 15:17:07 -05:00
context " without auto tracking " do
before do
TopicUser . update_last_read ( user , topic . id , 1 , 0 )
end
2013-02-25 19:42:20 +03:00
2013-03-06 15:17:07 -05:00
let ( :topic_user ) { TopicUser . get ( topic , user ) }
it 'should create a new record for a visit' do
2013-12-30 13:02:12 +11:00
freeze_time yesterday do
topic_user . last_read_post_number . should == 1
topic_user . last_visited_at . to_i . should == yesterday . to_i
topic_user . first_visited_at . to_i . should == yesterday . to_i
end
2013-03-06 15:17:07 -05:00
end
it 'should update the record for repeat visit' do
2013-12-30 13:02:12 +11:00
freeze_time yesterday do
Fabricate ( :post , topic : topic , user : user )
TopicUser . update_last_read ( user , topic . id , 2 , 0 )
topic_user = TopicUser . get ( topic , user )
topic_user . last_read_post_number . should == 2
topic_user . last_visited_at . to_i . should == yesterday . to_i
topic_user . first_visited_at . to_i . should == yesterday . to_i
end
2013-03-06 15:17:07 -05:00
end
2013-02-05 14:16:51 -05:00
end
2014-01-22 17:46:52 +11:00
context 'private messages' do
it 'should ensure recepients and senders are watching' do
ActiveRecord :: Base . observers . enable :all
target_user = Fabricate ( :user )
post = create_post ( archetype : Archetype . private_message , target_usernames : target_user . username ) ;
TopicUser . get ( post . topic , post . user ) . notification_level . should == TopicUser . notification_levels [ :watching ]
TopicUser . get ( post . topic , target_user ) . notification_level . should == TopicUser . notification_levels [ :watching ]
end
end
2013-02-25 19:42:20 +03:00
context 'auto tracking' do
2013-03-06 15:17:07 -05:00
2013-03-18 13:55:34 -04:00
let ( :post_creator ) { PostCreator . new ( new_user , raw : Fabricate . build ( :post ) . raw , topic_id : topic . id ) }
2013-02-05 14:16:51 -05:00
before do
2013-03-06 15:17:07 -05:00
TopicUser . update_last_read ( new_user , topic . id , 2 , 0 )
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
2013-02-05 14:16:51 -05:00
it 'should automatically track topics you reply to' do
2013-03-18 13:55:34 -04:00
post_creator . create
2013-03-06 15:17:07 -05:00
topic_new_user . notification_level . should == TopicUser . notification_levels [ :tracking ]
topic_new_user . notifications_reason_id . should == TopicUser . notification_reasons [ :created_post ]
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
2013-02-05 14:16:51 -05:00
it 'should not automatically track topics you reply to and have set state manually' do
2013-03-18 13:55:34 -04:00
post_creator . create
2013-03-06 15:17:07 -05:00
TopicUser . change ( new_user , topic , notification_level : TopicUser . notification_levels [ :regular ] )
topic_new_user . notification_level . should == TopicUser . notification_levels [ :regular ]
topic_new_user . notifications_reason_id . should == TopicUser . notification_reasons [ :user_changed ]
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'should automatically track topics after they are read for long enough' do
2013-03-06 15:17:07 -05:00
topic_new_user . notification_level . should == TopicUser . notification_levels [ :regular ]
TopicUser . update_last_read ( new_user , topic . id , 2 , 1001 )
TopicUser . get ( topic , new_user ) . notification_level . should == TopicUser . notification_levels [ :tracking ]
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'should not automatically track topics after they are read for long enough if changed manually' do
2013-03-06 15:17:07 -05:00
TopicUser . change ( new_user , topic , notification_level : TopicUser . notification_levels [ :regular ] )
TopicUser . update_last_read ( new_user , topic , 2 , 1001 )
topic_new_user . notification_level . should == TopicUser . notification_levels [ :regular ]
2013-02-05 14:16:51 -05:00
end
end
end
describe 'change a flag' do
it 'creates a forum topic user record' do
2013-12-30 13:02:12 +11:00
user ; topic
2013-02-05 14:16:51 -05:00
lambda {
2013-03-06 15:17:07 -05:00
TopicUser . change ( user , topic . id , starred : true )
2013-02-05 14:16:51 -05:00
} . should change ( TopicUser , :count ) . by ( 1 )
end
it " only inserts a row once, even on repeated calls " do
2013-12-30 13:02:12 +11:00
topic ; user
2013-02-05 14:16:51 -05:00
lambda {
2013-03-06 15:17:07 -05:00
TopicUser . change ( user , topic . id , starred : true )
TopicUser . change ( user , topic . id , starred : false )
TopicUser . change ( user , topic . id , starred : true )
2013-02-05 14:16:51 -05:00
} . should change ( TopicUser , :count ) . by ( 1 )
end
2013-02-25 19:42:20 +03:00
2013-05-21 20:43:43 -07:00
it 'triggers the observer callbacks when updating' do
UserActionObserver . instance . expects ( :after_save ) . twice
3 . times { TopicUser . change ( user , topic . id , starred : true ) }
end
2013-02-05 14:16:51 -05:00
describe 'after creating a row' do
before do
2013-03-06 15:17:07 -05:00
TopicUser . change ( user , topic . id , starred : true )
2013-02-05 14:16:51 -05:00
end
it 'has the correct starred value' do
2013-03-06 15:17:07 -05:00
TopicUser . get ( topic , user ) . should be_starred
2013-02-05 14:16:51 -05:00
end
it 'has a lookup' do
2013-03-06 15:17:07 -05:00
TopicUser . lookup_for ( user , [ topic ] ) . should be_present
2013-02-05 14:16:51 -05:00
end
it 'has a key in the lookup for this forum topic' do
2013-03-06 15:17:07 -05:00
TopicUser . lookup_for ( user , [ topic ] ) . has_key? ( topic . id ) . should be_true
2013-02-05 14:16:51 -05:00
end
end
end
2013-05-29 18:11:04 +10:00
it " can scope by tracking " do
TopicUser . create! ( user_id : 1 , topic_id : 1 , notification_level : TopicUser . notification_levels [ :tracking ] )
TopicUser . create! ( user_id : 2 , topic_id : 1 , notification_level : TopicUser . notification_levels [ :watching ] )
TopicUser . create! ( user_id : 3 , topic_id : 1 , notification_level : TopicUser . notification_levels [ :regular ] )
TopicUser . tracking ( 1 ) . count . should == 2
TopicUser . tracking ( 10 ) . count . should == 0
end
2013-04-05 15:29:46 +11:00
it " is able to self heal " do
p1 = Fabricate ( :post )
p2 = Fabricate ( :post , user : p1 . user , topic : p1 . topic , post_number : 2 )
2013-07-22 15:06:53 +10:00
p1 . topic . notifier . watch_topic! ( p1 . user_id )
2013-04-05 15:29:46 +11:00
2013-04-08 13:01:58 +10:00
TopicUser . exec_sql ( " UPDATE topic_users set seen_post_count=100, last_read_post_number=0
2013-04-05 15:29:46 +11:00
WHERE topic_id = :topic_id AND user_id = :user_id " , topic_id: p1.topic_id, user_id: p1.user_id)
[ p1 , p2 ] . each do | p |
PostTiming . create ( topic_id : p . topic_id , post_number : p . post_number , user_id : p . user_id , msecs : 100 )
end
TopicUser . ensure_consistency!
2014-05-06 14:41:59 +01:00
tu = TopicUser . find_by ( user_id : p1 . user_id , topic_id : p1 . topic_id )
2013-04-05 15:29:46 +11:00
tu . last_read_post_number . should == p2 . post_number
tu . seen_post_count . should == 2
end
2014-02-07 11:06:35 +11:00
describe " mailing_list_mode " do
2013-12-30 13:02:12 +11:00
2014-02-07 11:06:35 +11:00
it " will receive email notification for every topic " do
user1 = Fabricate ( :user )
user2 = Fabricate ( :user , mailing_list_mode : true )
post = create_post
user3 = Fabricate ( :user , mailing_list_mode : true )
create_post ( topic_id : post . topic_id )
# mails posts from earlier topics
2014-05-06 14:41:59 +01:00
tu = TopicUser . find_by ( user_id : user3 . id , topic_id : post . topic_id )
2014-02-07 11:06:35 +11:00
tu . last_emailed_post_number . should == 2
# mails nothing to random users
2014-05-06 14:41:59 +01:00
tu = TopicUser . find_by ( user_id : user1 . id , topic_id : post . topic_id )
2014-02-07 11:06:35 +11:00
tu . should be_nil
# mails other user
2014-05-06 14:41:59 +01:00
tu = TopicUser . find_by ( user_id : user2 . id , topic_id : post . topic_id )
2014-02-07 11:06:35 +11:00
tu . last_emailed_post_number . should == 2
2013-12-30 13:02:12 +11:00
end
end
2013-02-25 19:42:20 +03:00
end