2020-05-27 14:28:38 -04:00
# coding: utf-8
2019-04-29 20:27:42 -04:00
# frozen_string_literal: true
2017-08-23 23:01:11 -04:00
RSpec . describe TopicsController do
2019-05-06 23:12:20 -04:00
fab! ( :topic ) { Fabricate ( :topic ) }
2021-12-13 14:44:55 -05:00
fab! ( :dest_topic ) { Fabricate ( :topic ) }
fab! ( :invisible_topic ) { Fabricate ( :topic , visible : false ) }
fab! ( :pm ) { Fabricate ( :private_message_topic ) }
2021-03-17 11:25:43 -04:00
2019-05-06 23:12:20 -04:00
fab! ( :user ) { Fabricate ( :user ) }
2021-12-13 14:44:55 -05:00
fab! ( :user_2 ) { Fabricate ( :user ) }
2021-12-14 13:09:07 -05:00
fab! ( :post_author1 ) { Fabricate ( :user ) }
fab! ( :post_author2 ) { Fabricate ( :user ) }
fab! ( :post_author3 ) { Fabricate ( :user ) }
fab! ( :post_author4 ) { Fabricate ( :user ) }
fab! ( :post_author5 ) { Fabricate ( :user ) }
fab! ( :post_author6 ) { Fabricate ( :user ) }
2019-05-08 05:06:54 -04:00
fab! ( :moderator ) { Fabricate ( :moderator ) }
2019-05-06 06:00:22 -04:00
fab! ( :admin ) { Fabricate ( :admin ) }
2021-08-05 05:38:39 -04:00
fab! ( :trust_level_0 ) { Fabricate ( :trust_level_0 ) }
fab! ( :trust_level_1 ) { Fabricate ( :trust_level_1 ) }
2019-05-06 07:19:50 -04:00
fab! ( :trust_level_4 ) { Fabricate ( :trust_level_4 ) }
2017-08-23 23:01:11 -04:00
2021-03-17 11:25:43 -04:00
fab! ( :category ) { Fabricate ( :category ) }
2021-12-13 14:44:55 -05:00
fab! ( :tracked_category ) { Fabricate ( :category ) }
fab! ( :shared_drafts_category ) { Fabricate ( :category ) }
2021-03-17 11:25:43 -04:00
fab! ( :staff_category ) {
Fabricate ( :category ) . tap { | staff_category |
staff_category . set_permissions ( staff : :full )
staff_category . save!
}
}
fab! ( :group_user ) { Fabricate ( :group_user ) }
2021-12-13 14:44:55 -05:00
fab! ( :tag ) { Fabricate ( :tag ) }
2018-05-31 10:45:32 -04:00
describe '#wordpress' do
2021-12-21 13:28:12 -05:00
before do
sign_in ( moderator )
end
2021-03-17 11:25:43 -04:00
fab! ( :p1 ) { Fabricate ( :post , user : moderator ) }
2021-12-21 13:28:12 -05:00
fab! ( :p2 ) { Fabricate ( :post , topic : p1 . topic , user : moderator ) }
2018-05-31 10:45:32 -04:00
it " returns the JSON in the format our wordpress plugin needs " do
SiteSetting . external_system_avatars_enabled = false
2021-12-21 13:28:12 -05:00
get " /t/ #{ p1 . topic . id } /wordpress.json " , params : { best : 3 }
2018-05-31 10:45:32 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-31 10:45:32 -04:00
# The JSON has the data the wordpress plugin needs
2021-12-21 13:28:12 -05:00
expect ( json [ 'id' ] ) . to eq ( p1 . topic . id )
2018-05-31 10:45:32 -04:00
expect ( json [ 'posts_count' ] ) . to eq ( 2 )
expect ( json [ 'filtered_posts_count' ] ) . to eq ( 2 )
# Posts
expect ( json [ 'posts' ] . size ) . to eq ( 1 )
post = json [ 'posts' ] [ 0 ]
expect ( post [ 'id' ] ) . to eq ( p2 . id )
2021-12-21 13:28:12 -05:00
expect ( post [ 'username' ] ) . to eq ( moderator . username )
expect ( post [ 'avatar_template' ] ) . to eq ( " #{ Discourse . base_url_no_prefix } #{ moderator . avatar_template } " )
expect ( post [ 'name' ] ) . to eq ( moderator . name )
2018-05-31 10:45:32 -04:00
expect ( post [ 'created_at' ] ) . to be_present
expect ( post [ 'cooked' ] ) . to eq ( p2 . cooked )
# Participants
expect ( json [ 'participants' ] . size ) . to eq ( 1 )
participant = json [ 'participants' ] [ 0 ]
2021-12-21 13:28:12 -05:00
expect ( participant [ 'id' ] ) . to eq ( moderator . id )
expect ( participant [ 'username' ] ) . to eq ( moderator . username )
expect ( participant [ 'avatar_template' ] ) . to eq ( " #{ Discourse . base_url_no_prefix } #{ moderator . avatar_template } " )
2018-05-31 10:45:32 -04:00
end
end
describe '#move_posts' do
before do
SiteSetting . min_topic_title_length = 2
2018-07-06 12:21:32 -04:00
SiteSetting . tagging_enabled = true
2018-05-31 10:45:32 -04:00
end
it 'needs you to be logged in' do
post " /t/111/move-posts.json " , params : {
title : 'blah' ,
post_ids : [ 1 , 2 , 3 ]
}
expect ( response . status ) . to eq ( 403 )
end
describe 'moving to a new topic' do
2021-03-17 11:25:43 -04:00
fab! ( :p1 ) { Fabricate ( :post , user : user , post_number : 1 ) }
2018-05-31 10:45:32 -04:00
let ( :p2 ) { Fabricate ( :post , user : user , post_number : 2 , topic : p1 . topic ) }
2021-03-17 11:25:43 -04:00
let ( :topic ) { p1 . topic }
2018-05-31 10:45:32 -04:00
it " raises an error without post_ids " do
sign_in ( moderator )
post " /t/ #{ topic . id } /move-posts.json " , params : { title : 'blah' }
expect ( response . status ) . to eq ( 400 )
end
it " raises an error when the user doesn't have permission to move the posts " do
sign_in ( user )
post " /t/ #{ topic . id } /move-posts.json " , params : {
title : 'blah' , post_ids : [ p1 . post_number , p2 . post_number ]
}
expect ( response ) . to be_forbidden
end
it " raises an error when the OP is not a regular post " do
sign_in ( moderator )
2021-12-14 13:09:07 -05:00
p2 = Fabricate ( :post , user : post_author1 , topic : topic , post_number : 2 , post_type : Post . types [ :whisper ] )
p3 = Fabricate ( :post , user : post_author2 , topic : topic , post_number : 3 )
2018-05-31 10:45:32 -04:00
post " /t/ #{ topic . id } /move-posts.json " , params : {
title : 'blah' , post_ids : [ p2 . id , p3 . id ]
}
expect ( response . status ) . to eq ( 422 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( result [ 'errors' ] ) . to be_present
end
context 'success' do
2020-08-05 10:33:25 -04:00
2019-05-06 06:00:22 -04:00
before { sign_in ( admin ) }
2018-05-31 10:45:32 -04:00
it " returns success " do
expect do
post " /t/ #{ topic . id } /move-posts.json " , params : {
title : 'Logan is a good movie' ,
post_ids : [ p2 . id ] ,
2020-08-05 10:33:25 -04:00
category_id : category . id ,
2021-12-13 14:44:55 -05:00
tags : [ " foo " , " bar " ]
2018-05-31 10:45:32 -04:00
}
2021-12-13 14:44:55 -05:00
end . to change { Topic . count } . by ( 1 ) . and change { Tag . count } . by ( 2 )
2018-05-31 10:45:32 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( result [ 'success' ] ) . to eq ( true )
2020-08-13 02:00:14 -04:00
new_topic = Topic . last
expect ( result [ 'url' ] ) . to eq ( new_topic . relative_url )
expect ( new_topic . excerpt ) . to eq ( p2 . excerpt_for_topic )
2021-12-13 14:44:55 -05:00
expect ( Tag . all . pluck ( :name ) ) . to include ( " foo " , " bar " )
2018-05-31 10:45:32 -04:00
end
describe 'when topic has been deleted' do
it 'should still be able to move posts' do
2019-05-06 06:00:22 -04:00
PostDestroyer . new ( admin , topic . first_post ) . destroy
2018-05-31 10:45:32 -04:00
expect ( topic . reload . deleted_at ) . to_not be_nil
expect do
post " /t/ #{ topic . id } /move-posts.json " , params : {
title : 'Logan is a good movie' ,
post_ids : [ p2 . id ] ,
2020-08-05 10:33:25 -04:00
category_id : category . id
2018-05-31 10:45:32 -04:00
}
end . to change { Topic . count } . by ( 1 )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to eq ( Topic . last . relative_url )
end
end
end
context 'failure' do
it " returns JSON with a false success " do
sign_in ( moderator )
post " /t/ #{ topic . id } /move-posts.json " , params : {
post_ids : [ p2 . id ]
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( result [ 'success' ] ) . to eq ( false )
expect ( result [ 'url' ] ) . to be_blank
end
end
describe " moving replied posts " do
context 'success' do
it " moves the child posts too " do
2021-12-21 13:28:12 -05:00
sign_in ( moderator )
p1 = Fabricate ( :post , topic : topic , user : moderator )
p2 = Fabricate ( :post , topic : topic , user : moderator , reply_to_post_number : p1 . post_number )
2020-01-17 11:24:49 -05:00
PostReply . create ( post_id : p1 . id , reply_post_id : p2 . id )
2018-05-31 10:45:32 -04:00
post " /t/ #{ topic . id } /move-posts.json " , params : {
title : 'new topic title' ,
post_ids : [ p1 . id ] ,
reply_post_ids : [ p1 . id ]
}
expect ( response . status ) . to eq ( 200 )
p1 . reload
p2 . reload
2020-05-07 11:04:12 -04:00
new_topic_id = response . parsed_body [ " url " ] . split ( " / " ) . last . to_i
2018-05-31 10:45:32 -04:00
new_topic = Topic . find ( new_topic_id )
expect ( p1 . topic . id ) . to eq ( new_topic . id )
expect ( p2 . topic . id ) . to eq ( new_topic . id )
expect ( p2 . reply_to_post_number ) . to eq ( p1 . post_number )
end
end
end
end
2020-08-05 10:33:25 -04:00
describe " moving to a new topic as a group moderator " do
fab! ( :category ) { Fabricate ( :category , reviewable_by_group : group_user . group ) }
fab! ( :topic ) { Fabricate ( :topic , category : category ) }
fab! ( :p1 ) { Fabricate ( :post , user : group_user . user , post_number : 1 , topic : topic ) }
fab! ( :p2 ) { Fabricate ( :post , user : group_user . user , post_number : 2 , topic : topic ) }
2021-03-17 11:25:43 -04:00
let! ( :user ) { group_user . user }
2020-08-05 10:33:25 -04:00
before do
sign_in ( user )
SiteSetting . enable_category_group_moderation = true
end
it " moves the posts " do
expect do
post " /t/ #{ topic . id } /move-posts.json " , params : {
title : 'Logan is a good movie' ,
post_ids : [ p2 . id ] ,
category_id : category . id
}
end . to change { Topic . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
result = response . parsed_body
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to eq ( Topic . last . relative_url )
end
it " does not allow posts to be moved to a private category " do
post " /t/ #{ topic . id } /move-posts.json " , params : {
title : 'Logan is a good movie' ,
post_ids : [ p2 . id ] ,
category_id : staff_category . id
}
expect ( response ) . to be_forbidden
end
it " does not allow posts outside of the category to be moved " do
topic . update! ( category : nil )
post " /t/ #{ topic . id } /move-posts.json " , params : {
title : 'blah' , post_ids : [ p1 . post_number , p2 . post_number ]
}
expect ( response ) . to be_forbidden
end
end
2018-05-31 10:45:32 -04:00
describe 'moving to an existing topic' do
2021-12-21 13:28:12 -05:00
before do
sign_in ( moderator )
end
2021-03-17 11:25:43 -04:00
fab! ( :p1 ) { Fabricate ( :post , user : moderator ) }
fab! ( :topic ) { p1 . topic }
fab! ( :p2 ) { Fabricate ( :post , user : moderator , topic : topic ) }
2018-05-31 10:45:32 -04:00
context 'success' do
it " returns success " do
post " /t/ #{ topic . id } /move-posts.json " , params : {
post_ids : [ p2 . id ] ,
destination_topic_id : dest_topic . id
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to be_present
end
2018-07-09 21:48:57 -04:00
2018-07-09 21:28:57 -04:00
it " triggers an event on merge " do
2018-07-09 23:27:03 -04:00
begin
called = false
assert = - > ( original_topic , destination_topic ) do
called = true
expect ( original_topic ) . to eq ( topic )
expect ( destination_topic ) . to eq ( dest_topic )
end
DiscourseEvent . on ( :topic_merged , & assert )
post " /t/ #{ topic . id } /move-posts.json " , params : {
post_ids : [ p2 . id ] ,
destination_topic_id : dest_topic . id
}
expect ( called ) . to eq ( true )
expect ( response . status ) . to eq ( 200 )
ensure
DiscourseEvent . off ( :topic_merged , & assert )
2018-07-09 21:28:57 -04:00
end
end
2018-05-31 10:45:32 -04:00
end
context 'failure' do
2021-03-17 11:25:43 -04:00
fab! ( :p2 ) { Fabricate ( :post , user : moderator ) }
2018-05-31 10:45:32 -04:00
it " returns JSON with a false success " do
post " /t/ #{ topic . id } /move-posts.json " , params : {
post_ids : [ p2 . id ]
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( result [ 'success' ] ) . to eq ( false )
expect ( result [ 'url' ] ) . to be_blank
end
2022-02-02 00:22:52 -05:00
it 'returns plugin validation error' do
# stub here is to simulate validation added by plugin which would be triggered when post is moved
PostCreator . any_instance . stubs ( :skip_validations? ) . returns ( false )
p1 . update_columns ( raw : " i " , cooked : " " )
post " /t/ #{ topic . id } /move-posts.json " , params : {
post_ids : [ p1 . id ] ,
destination_topic_id : dest_topic . id
}
expect ( response . status ) . to eq ( 422 )
result = response . parsed_body
expect ( result [ 'errors' ] ) . to eq ( [ " Body is too short (minimum is 5 characters) and Body seems unclear, is it a complete sentence? " ] )
end
2018-05-31 10:45:32 -04:00
end
end
2018-12-31 06:47:22 -05:00
2020-08-05 10:33:25 -04:00
describe " moving to an existing topic as a group moderator " do
fab! ( :category ) { Fabricate ( :category , reviewable_by_group : group_user . group ) }
fab! ( :topic ) { Fabricate ( :topic , category : category ) }
fab! ( :p1 ) { Fabricate ( :post , user : group_user . user , post_number : 1 , topic : topic ) }
fab! ( :p2 ) { Fabricate ( :post , user : group_user . user , post_number : 2 , topic : topic ) }
2021-03-17 11:25:43 -04:00
let! ( :user ) { group_user . user }
2020-08-05 10:33:25 -04:00
before do
sign_in ( user )
SiteSetting . enable_category_group_moderation = true
end
it " moves the posts " do
post " /t/ #{ topic . id } /move-posts.json " , params : {
post_ids : [ p2 . id ] ,
destination_topic_id : dest_topic . id
}
expect ( response . status ) . to eq ( 200 )
result = response . parsed_body
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to be_present
end
it " does not allow posts to be moved to a private category " do
dest_topic . update! ( category : staff_category )
post " /t/ #{ topic . id } /move-posts.json " , params : {
post_ids : [ p2 . id ] ,
destination_topic_id : dest_topic . id
}
expect ( response ) . to be_forbidden
end
it " does not allow posts outside of the category to be moved " do
topic . update! ( category : nil )
post " /t/ #{ topic . id } /move-posts.json " , params : {
post_ids : [ p1 . post_number , p2 . post_number ] ,
destination_topic_id : dest_topic . id
}
expect ( response ) . to be_forbidden
end
end
2018-12-31 06:47:22 -05:00
describe 'moving to a new message' do
2021-12-13 14:44:55 -05:00
fab! ( :message ) { pm }
2021-03-17 11:25:43 -04:00
fab! ( :p1 ) { Fabricate ( :post , user : user , post_number : 1 , topic : message ) }
fab! ( :p2 ) { Fabricate ( :post , user : user , post_number : 2 , topic : message ) }
2018-12-31 06:47:22 -05:00
it " raises an error without post_ids " do
sign_in ( moderator )
post " /t/ #{ message . id } /move-posts.json " , params : { title : 'blah' , archetype : 'private_message' }
expect ( response . status ) . to eq ( 400 )
end
it " raises an error when the user doesn't have permission to move the posts " do
sign_in ( trust_level_4 )
post " /t/ #{ message . id } /move-posts.json " , params : {
title : 'blah' , post_ids : [ p1 . post_number , p2 . post_number ] , archetype : 'private_message'
}
expect ( response . status ) . to eq ( 403 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-12-31 06:47:22 -05:00
expect ( result [ 'errors' ] ) . to be_present
end
context 'success' do
2019-05-06 06:00:22 -04:00
before { sign_in ( admin ) }
2018-12-31 06:47:22 -05:00
it " returns success " do
2022-05-10 11:02:28 -04:00
SiteSetting . pm_tags_allowed_for_groups = " 1|2|3 "
2018-12-31 06:47:22 -05:00
expect do
post " /t/ #{ message . id } /move-posts.json " , params : {
title : 'Logan is a good movie' ,
post_ids : [ p2 . id ] ,
archetype : 'private_message' ,
2021-12-13 14:44:55 -05:00
tags : [ " foo " , " bar " ]
2018-12-31 06:47:22 -05:00
}
2021-12-13 14:44:55 -05:00
end . to change { Topic . count } . by ( 1 ) . and change { Tag . count } . by ( 2 )
2018-12-31 06:47:22 -05:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-12-31 06:47:22 -05:00
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to eq ( Topic . last . relative_url )
2021-12-13 14:44:55 -05:00
expect ( Tag . all . pluck ( :name ) ) . to include ( " foo " , " bar " )
2018-12-31 06:47:22 -05:00
end
describe 'when message has been deleted' do
it 'should still be able to move posts' do
2019-05-06 06:00:22 -04:00
PostDestroyer . new ( admin , message . first_post ) . destroy
2018-12-31 06:47:22 -05:00
expect ( message . reload . deleted_at ) . to_not be_nil
expect do
post " /t/ #{ message . id } /move-posts.json " , params : {
title : 'Logan is a good movie' ,
post_ids : [ p2 . id ] ,
archetype : 'private_message'
}
end . to change { Topic . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-12-31 06:47:22 -05:00
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to eq ( Topic . last . relative_url )
end
end
end
context 'failure' do
it " returns JSON with a false success " do
sign_in ( moderator )
post " /t/ #{ message . id } /move-posts.json " , params : {
post_ids : [ p2 . id ] ,
archetype : 'private_message'
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-12-31 06:47:22 -05:00
expect ( result [ 'success' ] ) . to eq ( false )
expect ( result [ 'url' ] ) . to be_blank
end
end
end
describe 'moving to an existing message' do
2021-12-21 13:28:12 -05:00
before do
sign_in ( admin )
end
2019-05-06 23:12:20 -04:00
fab! ( :evil_trout ) { Fabricate ( :evil_trout ) }
2021-12-13 14:44:55 -05:00
fab! ( :message ) { pm }
2021-03-17 11:25:43 -04:00
fab! ( :p2 ) { Fabricate ( :post , user : evil_trout , post_number : 2 , topic : message ) }
2018-12-31 06:47:22 -05:00
2021-03-17 11:25:43 -04:00
fab! ( :dest_message ) do
2018-12-31 06:47:22 -05:00
Fabricate ( :private_message_topic , user : trust_level_4 , topic_allowed_users : [
Fabricate . build ( :topic_allowed_user , user : evil_trout )
] )
end
context 'success' do
it " returns success " do
post " /t/ #{ message . id } /move-posts.json " , params : {
post_ids : [ p2 . id ] ,
destination_topic_id : dest_message . id ,
archetype : 'private_message'
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-12-31 06:47:22 -05:00
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to be_present
end
end
context 'failure' do
it " returns JSON with a false success " do
post " /t/ #{ message . id } /move-posts.json " , params : {
post_ids : [ p2 . id ] ,
archetype : 'private_message'
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-12-31 06:47:22 -05:00
expect ( result [ 'success' ] ) . to eq ( false )
expect ( result [ 'url' ] ) . to be_blank
end
end
end
2018-05-31 10:45:32 -04:00
end
describe '#merge_topic' do
it 'needs you to be logged in' do
post " /t/111/merge-topic.json " , params : {
destination_topic_id : 345
}
expect ( response . status ) . to eq ( 403 )
end
2018-12-31 06:47:22 -05:00
describe 'merging into another topic' do
2021-03-17 11:25:43 -04:00
fab! ( :p1 ) { Fabricate ( :post , user : user ) }
fab! ( :topic ) { p1 . topic }
2018-05-31 10:45:32 -04:00
it " raises an error without destination_topic_id " do
sign_in ( moderator )
post " /t/ #{ topic . id } /merge-topic.json "
expect ( response . status ) . to eq ( 400 )
end
it " raises an error when the user doesn't have permission to merge " do
sign_in ( user )
post " /t/111/merge-topic.json " , params : { destination_topic_id : 345 }
expect ( response ) . to be_forbidden
end
context 'moves all the posts to the destination topic' do
it " returns success " do
sign_in ( moderator )
post " /t/ #{ topic . id } /merge-topic.json " , params : {
destination_topic_id : dest_topic . id
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-12-31 06:47:22 -05:00
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to be_present
end
end
end
2020-08-05 10:33:25 -04:00
describe " merging into another topic as a group moderator " do
fab! ( :category ) { Fabricate ( :category , reviewable_by_group : group_user . group ) }
fab! ( :topic ) { Fabricate ( :topic , category : category ) }
2021-12-14 13:09:07 -05:00
fab! ( :p1 ) { Fabricate ( :post , user : post_author1 , post_number : 1 , topic : topic ) }
fab! ( :p2 ) { Fabricate ( :post , user : post_author2 , post_number : 2 , topic : topic ) }
2020-08-05 10:33:25 -04:00
before do
2021-12-21 13:28:12 -05:00
sign_in ( group_user . user )
2020-08-05 10:33:25 -04:00
SiteSetting . enable_category_group_moderation = true
end
it " moves the posts " do
post " /t/ #{ topic . id } /merge-topic.json " , params : {
destination_topic_id : dest_topic . id
}
expect ( response . status ) . to eq ( 200 )
result = response . parsed_body
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to be_present
end
it " does not allow posts to be moved to a private category " do
dest_topic . update! ( category : staff_category )
post " /t/ #{ topic . id } /merge-topic.json " , params : {
destination_topic_id : dest_topic . id
}
expect ( response ) . to be_forbidden
end
it " does not allow posts outside of the category to be moved " do
topic . update! ( category : nil )
post " /t/ #{ topic . id } /merge-topic.json " , params : {
destination_topic_id : dest_topic . id
}
expect ( response ) . to be_forbidden
end
end
2018-12-31 06:47:22 -05:00
describe 'merging into another message' do
2021-03-17 11:25:43 -04:00
fab! ( :message ) { Fabricate ( :private_message_topic , user : user ) }
fab! ( :p1 ) { Fabricate ( :post , topic : message , user : trust_level_4 ) }
fab! ( :p2 ) { Fabricate ( :post , topic : message , reply_to_post_number : p1 . post_number , user : user ) }
fab! ( :dest_message ) do
Fabricate ( :private_message_topic , user : trust_level_4 , topic_allowed_users : [
Fabricate . build ( :topic_allowed_user , user : moderator )
] )
end
2018-12-31 06:47:22 -05:00
it " raises an error without destination_topic_id " do
sign_in ( moderator )
post " /t/ #{ message . id } /merge-topic.json " , params : {
archetype : 'private_message'
}
expect ( response . status ) . to eq ( 400 )
end
it " raises an error when the user doesn't have permission to merge " do
sign_in ( trust_level_4 )
post " /t/ #{ message . id } /merge-topic.json " , params : {
destination_topic_id : 345 ,
archetype : 'private_message'
}
expect ( response ) . to be_forbidden
end
context 'moves all the posts to the destination message' do
it " returns success " do
sign_in ( moderator )
post " /t/ #{ message . id } /merge-topic.json " , params : {
destination_topic_id : dest_message . id ,
archetype : 'private_message'
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to be_present
end
end
end
end
describe '#change_post_owners' do
it 'needs you to be logged in' do
post " /t/111/change-owner.json " , params : {
username : 'user_a' ,
post_ids : [ 1 , 2 , 3 ]
}
expect ( response ) . to be_forbidden
end
describe 'forbidden to trust_level_4s' do
before do
2019-05-06 07:19:50 -04:00
sign_in ( trust_level_4 )
2018-05-31 10:45:32 -04:00
end
it 'correctly denies' do
post " /t/111/change-owner.json " , params : {
topic_id : 111 , username : 'user_a' , post_ids : [ 1 , 2 , 3 ]
}
expect ( response ) . to be_forbidden
end
end
describe 'changing ownership' do
2019-05-06 23:12:20 -04:00
fab! ( :user_a ) { Fabricate ( :user ) }
2021-12-14 13:09:07 -05:00
fab! ( :p1 ) { Fabricate ( :post , user : post_author1 , topic : topic ) }
fab! ( :p2 ) { Fabricate ( :post , user : post_author2 , topic : topic ) }
2018-05-31 10:45:32 -04:00
2021-07-13 10:40:11 -04:00
describe 'moderator signed in' do
let! ( :editor ) { sign_in ( moderator ) }
it " returns 200 when moderators_change_post_ownership is true " do
SiteSetting . moderators_change_post_ownership = true
post " /t/ #{ topic . id } /change-owner.json " , params : {
username : user_a . username_lower , post_ids : [ p1 . id ]
}
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
end
2021-07-13 10:40:11 -04:00
it " returns 403 when moderators_change_post_ownership is false " do
SiteSetting . moderators_change_post_ownership = false
post " /t/ #{ topic . id } /change-owner.json " , params : {
username : user_a . username_lower , post_ids : [ p1 . id ]
}
expect ( response . status ) . to eq ( 403 )
end
2018-05-31 10:45:32 -04:00
end
2021-07-13 10:40:11 -04:00
describe 'admin signed in' do
let! ( :editor ) { sign_in ( admin ) }
2018-05-31 10:45:32 -04:00
2021-07-13 10:40:11 -04:00
it " raises an error with a parameter missing " do
[
{ post_ids : [ 1 , 2 , 3 ] } ,
{ username : 'user_a' }
] . each do | params |
post " /t/111/change-owner.json " , params : params
expect ( response . status ) . to eq ( 400 )
end
end
2018-05-31 10:45:32 -04:00
2021-07-13 10:40:11 -04:00
it " changes the topic and posts ownership " do
post " /t/ #{ topic . id } /change-owner.json " , params : {
username : user_a . username_lower , post_ids : [ p1 . id ]
}
topic . reload
p1 . reload
expect ( response . status ) . to eq ( 200 )
expect ( topic . user . username ) . to eq ( user_a . username )
expect ( p1 . user . username ) . to eq ( user_a . username )
end
2018-05-31 10:45:32 -04:00
2021-07-13 10:40:11 -04:00
it " changes multiple posts " do
post " /t/ #{ topic . id } /change-owner.json " , params : {
username : user_a . username_lower , post_ids : [ p1 . id , p2 . id ]
}
2018-05-31 10:45:32 -04:00
2021-07-13 10:40:11 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
2021-07-13 10:40:11 -04:00
p1 . reload
p2 . reload
2018-05-31 10:45:32 -04:00
2021-07-13 10:40:11 -04:00
expect ( p1 . user ) . to_not eq ( nil )
expect ( p1 . reload . user ) . to eq ( p2 . reload . user )
end
2018-05-31 10:45:32 -04:00
2021-07-13 10:40:11 -04:00
it " works with deleted users " do
deleted_user = user
t2 = Fabricate ( :topic , user : deleted_user )
p3 = Fabricate ( :post , topic : t2 , user : deleted_user )
2018-05-31 10:45:32 -04:00
2021-07-13 10:40:11 -04:00
UserDestroyer . new ( editor ) . destroy ( deleted_user , delete_posts : true , context : 'test' , delete_as_spammer : true )
post " /t/ #{ t2 . id } /change-owner.json " , params : {
username : user_a . username_lower , post_ids : [ p3 . id ]
}
expect ( response . status ) . to eq ( 200 )
t2 . reload
p3 . reload
expect ( t2 . deleted_at ) . to be_nil
expect ( p3 . user ) . to eq ( user_a )
end
it " removes likes by new owner " do
now = Time . zone . now
freeze_time ( now - 1 . day )
PostActionCreator . like ( user_a , p1 )
p1 . reload
freeze_time ( now )
post " /t/ #{ topic . id } /change-owner.json " , params : {
username : user_a . username_lower , post_ids : [ p1 . id ]
}
topic . reload
p1 . reload
expect ( response . status ) . to eq ( 200 )
expect ( topic . user . username ) . to eq ( user_a . username )
expect ( p1 . user . username ) . to eq ( user_a . username )
expect ( p1 . like_count ) . to eq ( 0 )
end
2020-08-19 11:21:02 -04:00
end
2018-05-31 10:45:32 -04:00
end
end
describe '#change_timestamps' do
2021-03-17 11:25:43 -04:00
let! ( :params ) { { timestamp : Time . zone . now } }
2018-05-31 10:45:32 -04:00
it 'needs you to be logged in' do
put " /t/1/change-timestamp.json " , params : params
expect ( response . status ) . to eq ( 403 )
end
2019-02-22 04:03:52 -05:00
describe " forbidden to trust_level_4 " do
2019-05-06 07:19:50 -04:00
before do
sign_in ( trust_level_4 )
end
2018-05-31 10:45:32 -04:00
2019-02-22 04:03:52 -05:00
it 'correctly denies' do
put " /t/1/change-timestamp.json " , params : params
expect ( response ) . to be_forbidden
2018-05-31 10:45:32 -04:00
end
end
describe 'changing timestamps' do
2020-03-10 17:13:17 -04:00
before do
freeze_time
sign_in ( moderator )
end
2021-03-17 11:25:43 -04:00
let! ( :old_timestamp ) { Time . zone . now }
let! ( :new_timestamp ) { old_timestamp - 1 . day }
2018-05-31 10:45:32 -04:00
let! ( :topic ) { Fabricate ( :topic , created_at : old_timestamp ) }
2021-12-14 13:09:07 -05:00
let! ( :p1 ) { Fabricate ( :post , user : post_author1 , topic : topic , created_at : old_timestamp ) }
let! ( :p2 ) { Fabricate ( :post , user : post_author2 , topic : topic , created_at : old_timestamp + 1 . day ) }
2018-05-31 10:45:32 -04:00
2018-06-05 03:29:17 -04:00
it 'should update the timestamps of selected posts' do
# try to see if we fail with invalid first
2018-05-31 10:45:32 -04:00
put " /t/1/change-timestamp.json "
expect ( response . status ) . to eq ( 400 )
put " /t/ #{ topic . id } /change-timestamp.json " , params : {
timestamp : new_timestamp . to_f
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-03-10 17:13:17 -04:00
expect ( topic . reload . created_at ) . to eq_time ( new_timestamp )
expect ( p1 . reload . created_at ) . to eq_time ( new_timestamp )
expect ( p2 . reload . created_at ) . to eq_time ( old_timestamp )
2018-05-31 10:45:32 -04:00
end
2019-02-22 04:03:52 -05:00
it 'should create a staff log entry' do
put " /t/ #{ topic . id } /change-timestamp.json " , params : {
timestamp : new_timestamp . to_f
}
log = UserHistory . last
expect ( log . acting_user_id ) . to eq ( moderator . id )
expect ( log . topic_id ) . to eq ( topic . id )
expect ( log . new_value ) . to eq ( new_timestamp . utc . to_s )
expect ( log . previous_value ) . to eq ( old_timestamp . utc . to_s )
end
2018-05-31 10:45:32 -04:00
end
end
describe '#clear_pin' do
it 'needs you to be logged in' do
put " /t/1/clear-pin.json "
expect ( response . status ) . to eq ( 403 )
end
context 'when logged in' do
before do
sign_in ( user )
end
it " fails when the user can't see the topic " do
put " /t/ #{ pm . id } /clear-pin.json "
expect ( response ) . to be_forbidden
end
describe 'when the user can see the topic' do
it " succeeds " do
expect do
put " /t/ #{ topic . id } /clear-pin.json "
end . to change { TopicUser . where ( topic_id : topic . id , user_id : user . id ) . count } . by ( 1 )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
end
end
end
end
describe '#status' do
it 'needs you to be logged in' do
put " /t/1/status.json " , params : {
status : 'visible' , enabled : true
}
expect ( response . status ) . to eq ( 403 )
end
2020-07-14 12:36:19 -04:00
describe 'when logged in as a moderator' do
2018-05-31 10:45:32 -04:00
before do
sign_in ( moderator )
end
it " raises an exception if you can't change it " do
sign_in ( user )
put " /t/ #{ topic . id } /status.json " , params : {
status : 'visible' , enabled : 'true'
}
expect ( response ) . to be_forbidden
end
it 'requires the status parameter' do
put " /t/ #{ topic . id } /status.json " , params : { enabled : true }
expect ( response . status ) . to eq ( 400 )
end
it 'requires the enabled parameter' do
put " /t/ #{ topic . id } /status.json " , params : { status : 'visible' }
expect ( response . status ) . to eq ( 400 )
end
2020-07-26 20:23:54 -04:00
it 'raises an error with a status not in the allowlist' do
2018-05-31 10:45:32 -04:00
put " /t/ #{ topic . id } /status.json " , params : {
status : 'title' , enabled : 'true'
}
expect ( response . status ) . to eq ( 400 )
end
it 'should update the status of the topic correctly' do
2021-12-21 13:28:12 -05:00
closed_user_topic = Fabricate ( :topic , user : user , closed : true )
Fabricate ( :topic_timer , topic : closed_user_topic , status_type : TopicTimer . types [ :open ] )
2018-05-31 10:45:32 -04:00
2021-12-21 13:28:12 -05:00
put " /t/ #{ closed_user_topic . id } /status.json " , params : {
2018-05-31 10:45:32 -04:00
status : 'closed' , enabled : 'false'
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-21 13:28:12 -05:00
expect ( closed_user_topic . reload . closed ) . to eq ( false )
expect ( closed_user_topic . topic_timers ) . to eq ( [ ] )
2018-05-31 10:45:32 -04:00
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( body [ 'topic_status_update' ] ) . to eq ( nil )
end
end
2020-07-14 12:36:19 -04:00
describe 'when logged in as a group member with reviewable status' do
fab! ( :category ) { Fabricate ( :category , reviewable_by_group : group_user . group ) }
fab! ( :topic ) { Fabricate ( :topic , category : category ) }
before do
2021-12-21 13:28:12 -05:00
sign_in ( group_user . user )
2020-07-14 12:36:19 -04:00
SiteSetting . enable_category_group_moderation = true
end
it 'should allow a group moderator to close a topic' do
put " /t/ #{ topic . id } /status.json " , params : {
status : 'closed' , enabled : 'true'
}
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . closed ) . to eq ( true )
2020-08-10 15:21:01 -04:00
expect ( topic . posts . last . action_code ) . to eq ( 'closed.enabled' )
end
it 'should allow a group moderator to open a closed topic' do
topic . update! ( closed : true )
expect do
put " /t/ #{ topic . id } /status.json " , params : {
status : 'closed' , enabled : 'false'
}
end . to change { topic . reload . posts . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . closed ) . to eq ( false )
expect ( topic . posts . last . action_code ) . to eq ( 'closed.disabled' )
2020-07-14 12:36:19 -04:00
end
it 'should allow a group moderator to archive a topic' do
2020-08-10 15:21:01 -04:00
expect do
put " /t/ #{ topic . id } /status.json " , params : {
status : 'archived' , enabled : 'true'
}
end . to change { topic . reload . posts . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . archived ) . to eq ( true )
expect ( topic . posts . last . action_code ) . to eq ( 'archived.enabled' )
end
it 'should allow a group moderator to unarchive an archived topic' do
topic . update! ( archived : true )
2020-07-14 12:36:19 -04:00
put " /t/ #{ topic . id } /status.json " , params : {
2020-08-10 15:21:01 -04:00
status : 'archived' , enabled : 'false'
2020-07-14 12:36:19 -04:00
}
expect ( response . status ) . to eq ( 200 )
2020-08-10 15:21:01 -04:00
expect ( topic . reload . archived ) . to eq ( false )
expect ( topic . posts . last . action_code ) . to eq ( 'archived.disabled' )
2020-07-14 12:36:19 -04:00
end
2021-03-09 16:05:11 -05:00
it 'should allow a group moderator to pin a topic' do
2020-07-14 12:36:19 -04:00
put " /t/ #{ topic . id } /status.json " , params : {
2021-03-09 16:05:11 -05:00
status : 'pinned' , enabled : 'true' , until : 2 . weeks . from_now
2020-07-14 12:36:19 -04:00
}
2021-03-09 16:05:11 -05:00
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . pinned_at ) . to_not eq ( nil )
end
it 'should allow a group moderator to unpin a topic' do
put " /t/ #{ topic . id } /status.json " , params : {
status : 'pinned' , enabled : 'false'
}
expect ( response . status ) . to eq ( 200 )
2020-07-14 12:36:19 -04:00
expect ( topic . reload . pinned_at ) . to eq ( nil )
end
2020-12-14 11:01:22 -05:00
it 'should allow a group moderator to unlist a topic' do
put " /t/ #{ topic . id } /status.json " , params : {
status : 'visible' , enabled : 'false'
}
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . visible ) . to eq ( false )
expect ( topic . posts . last . action_code ) . to eq ( 'visible.disabled' )
end
it 'should allow a group moderator to list an unlisted topic' do
topic . update! ( visible : false )
put " /t/ #{ topic . id } /status.json " , params : {
status : 'visible' , enabled : 'true'
}
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . visible ) . to eq ( true )
expect ( topic . posts . last . action_code ) . to eq ( 'visible.enabled' )
end
2020-07-14 12:36:19 -04:00
end
2018-05-31 10:45:32 -04:00
end
describe '#destroy_timings' do
it 'needs you to be logged in' do
delete " /t/1/timings.json "
expect ( response . status ) . to eq ( 403 )
end
def topic_user_post_timings_count ( user , topic )
[ TopicUser , PostTiming ] . map do | klass |
klass . where ( user : user , topic : topic ) . count
end
end
2018-11-13 00:07:48 -05:00
context 'for last post only' do
it 'should allow you to retain topic timing but remove last post only' do
2019-04-04 21:44:36 -04:00
freeze_time
2018-11-13 00:07:48 -05:00
post1 = create_post
2019-04-08 22:42:21 -04:00
user = post1 . user
2018-11-13 00:07:48 -05:00
topic = post1 . topic
post2 = create_post ( topic_id : topic . id )
PostTiming . create! ( topic : topic , user : user , post_number : 2 , msecs : 100 )
2019-04-04 21:44:36 -04:00
user . user_stat . update! ( first_unread_at : Time . now + 1 . week )
2019-04-08 22:42:21 -04:00
topic_user = TopicUser . find_by (
topic_id : topic . id ,
user_id : user . id ,
)
topic_user . update! (
2018-11-13 00:07:48 -05:00
last_read_post_number : 2 ,
)
2019-04-08 22:42:21 -04:00
# ensure we have 2 notifications
# fake notification on topic but it is read
first_notification = Notification . create! (
user_id : user . id ,
topic_id : topic . id ,
data : " {} " ,
read : true ,
notification_type : 1
)
freeze_time 1 . minute . from_now
PostAlerter . post_created ( post2 )
second_notification = user . notifications . where ( topic_id : topic . id ) . order ( created_at : :desc ) . first
second_notification . update! ( read : true )
2018-11-13 00:07:48 -05:00
sign_in ( user )
delete " /t/ #{ topic . id } /timings.json?last=1 "
expect ( PostTiming . where ( topic : topic , user : user , post_number : 2 ) . exists? ) . to eq ( false )
expect ( PostTiming . where ( topic : topic , user : user , post_number : 1 ) . exists? ) . to eq ( true )
2021-07-05 02:17:31 -04:00
expect ( TopicUser . where ( topic : topic , user : user , last_read_post_number : 1 ) . exists? ) . to eq ( true )
2018-11-13 00:07:48 -05:00
2019-04-04 21:44:36 -04:00
user . user_stat . reload
expect ( user . user_stat . first_unread_at ) . to eq_time ( topic . updated_at )
2019-04-08 22:42:21 -04:00
first_notification . reload
second_notification . reload
expect ( first_notification . read ) . to eq ( true )
expect ( second_notification . read ) . to eq ( false )
2019-05-06 06:00:22 -04:00
PostDestroyer . new ( admin , post2 ) . destroy
2018-11-13 00:07:48 -05:00
delete " /t/ #{ topic . id } /timings.json?last=1 "
expect ( PostTiming . where ( topic : topic , user : user , post_number : 1 ) . exists? ) . to eq ( false )
2021-07-05 02:17:31 -04:00
expect ( TopicUser . where ( topic : topic , user : user , last_read_post_number : nil ) . exists? ) . to eq ( true )
2018-11-13 00:07:48 -05:00
end
end
2018-05-31 10:45:32 -04:00
context 'when logged in' do
2021-12-21 13:28:12 -05:00
fab! ( :user_topic ) { Fabricate ( :topic , user : user ) }
fab! ( :user_post ) { Fabricate ( :post , user : user , topic : user_topic , post_number : 2 ) }
2018-05-31 10:45:32 -04:00
before do
2021-12-13 14:44:55 -05:00
sign_in ( user )
2021-12-21 13:28:12 -05:00
TopicUser . create! ( topic : user_topic , user : user )
PostTiming . create! ( topic : user_topic , user : user , post_number : 2 , msecs : 1000 )
2018-05-31 10:45:32 -04:00
end
it 'deletes the forum topic user and post timings records' do
expect do
2021-12-21 13:28:12 -05:00
delete " /t/ #{ user_topic . id } /timings.json "
end . to change { topic_user_post_timings_count ( user , user_topic ) } . from ( [ 1 , 1 ] ) . to ( [ 0 , 0 ] )
2018-05-31 10:45:32 -04:00
end
end
end
describe '#mute/unmute' do
it 'needs you to be logged in' do
put " /t/99/mute.json "
expect ( response . status ) . to eq ( 403 )
end
it 'needs you to be logged in' do
put " /t/99/unmute.json "
expect ( response . status ) . to eq ( 403 )
end
end
describe '#recover' do
it " won't allow us to recover a topic when we're not logged in " do
put " /t/1/recover.json "
expect ( response . status ) . to eq ( 403 )
end
describe 'when logged in' do
2021-03-17 11:25:43 -04:00
let! ( :topic ) { Fabricate ( :topic , user : user , deleted_at : Time . now , deleted_by : moderator ) }
2018-05-31 10:45:32 -04:00
let! ( :post ) { Fabricate ( :post , user : user , topic : topic , post_number : 1 , deleted_at : Time . now , deleted_by : moderator ) }
describe 'without access' do
it " raises an exception when the user doesn't have permission to delete the topic " do
sign_in ( user )
put " /t/ #{ topic . id } /recover.json "
expect ( response ) . to be_forbidden
end
end
context 'with permission' do
before do
sign_in ( moderator )
end
it 'succeeds' do
put " /t/ #{ topic . id } /recover.json "
topic . reload
post . reload
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
expect ( topic . trashed? ) . to be_falsey
expect ( post . trashed? ) . to be_falsey
end
end
end
end
describe '#delete' do
it " won't allow us to delete a topic when we're not logged in " do
delete " /t/1.json "
expect ( response . status ) . to eq ( 403 )
end
describe 'when logged in' do
2021-03-17 11:25:43 -04:00
fab! ( :topic ) { Fabricate ( :topic , user : user , created_at : 48 . hours . ago ) }
fab! ( :post ) { Fabricate ( :post , topic : topic , user : user , post_number : 1 ) }
2018-05-31 10:45:32 -04:00
describe 'without access' do
it " raises an exception when the user doesn't have permission to delete the topic " do
sign_in ( user )
delete " /t/ #{ topic . id } .json "
2020-01-15 08:41:41 -05:00
expect ( response . status ) . to eq ( 422 )
2018-05-31 10:45:32 -04:00
end
end
describe 'with permission' do
before do
sign_in ( moderator )
end
it 'succeeds' do
delete " /t/ #{ topic . id } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
topic . reload
expect ( topic . trashed? ) . to be_truthy
end
end
end
end
describe '#id_for_slug' do
2021-12-14 13:09:07 -05:00
fab! ( :topic ) { Fabricate ( :post , user : post_author1 ) . topic }
2018-05-31 10:45:32 -04:00
it " returns JSON for the slug " do
get " /t/id_for/ #{ topic . slug } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( json [ 'topic_id' ] ) . to eq ( topic . id )
expect ( json [ 'url' ] ) . to eq ( topic . url )
expect ( json [ 'slug' ] ) . to eq ( topic . slug )
end
it " returns invalid access if the user can't see the topic " do
get " /t/id_for/ #{ pm . slug } .json "
expect ( response ) . to be_forbidden
end
end
2018-03-01 20:13:04 -05:00
describe '#update' do
2018-03-12 22:20:47 -04:00
it " won't allow us to update a topic when we're not logged in " do
put " /t/1.json " , params : { slug : 'xyz' }
expect ( response . status ) . to eq ( 403 )
end
describe 'when logged in' do
2021-03-17 11:25:43 -04:00
fab! ( :topic ) { Fabricate ( :topic , user : user ) }
2018-03-01 20:13:04 -05:00
2021-12-13 14:44:55 -05:00
before_all do
2021-12-14 13:09:07 -05:00
Fabricate ( :post , user : post_author1 , topic : topic )
2021-12-13 14:44:55 -05:00
end
before do
2018-05-31 10:45:32 -04:00
SiteSetting . editing_grace_period = 0
2018-03-12 22:20:47 -04:00
sign_in ( user )
end
2018-03-01 20:13:04 -05:00
2018-03-12 22:20:47 -04:00
it 'can not change category to a disallowed category' do
category . set_permissions ( staff : :full )
category . save!
2018-03-01 20:13:04 -05:00
2018-03-12 22:20:47 -04:00
put " /t/ #{ topic . id } .json " , params : { category_id : category . id }
2018-07-12 22:51:08 -04:00
expect ( response . status ) . to eq ( 403 )
expect ( topic . reload . category_id ) . not_to eq ( category . id )
end
it 'can not move to a category that requires topic approval' do
category . custom_fields [ Category :: REQUIRE_TOPIC_APPROVAL ] = true
category . save!
put " /t/ #{ topic . id } .json " , params : { category_id : category . id }
expect ( response . status ) . to eq ( 403 )
expect ( topic . reload . category_id ) . not_to eq ( category . id )
2018-03-12 22:20:47 -04:00
end
2021-01-14 12:20:34 -05:00
context 'updating shared drafts' do
fab! ( :topic ) { Fabricate ( :topic , category : shared_drafts_category ) }
fab! ( :shared_draft ) { Fabricate ( :shared_draft , topic : topic , category : Fabricate ( :category ) ) }
it 'changes destination category' do
put " /t/ #{ topic . id } .json " , params : { category_id : category . id }
expect ( response . status ) . to eq ( 403 )
expect ( topic . shared_draft . category_id ) . not_to eq ( category . id )
end
end
2018-03-12 22:20:47 -04:00
describe 'without permission' do
it " raises an exception when the user doesn't have permission to update the topic " do
topic . update! ( archived : true )
put " /t/ #{ topic . slug } / #{ topic . id } .json "
expect ( response . status ) . to eq ( 403 )
end
end
describe 'with permission' do
2020-03-21 09:33:10 -04:00
fab! ( :post_hook ) { Fabricate ( :post_web_hook ) }
fab! ( :topic_hook ) { Fabricate ( :topic_web_hook ) }
2018-03-12 22:20:47 -04:00
it 'succeeds' do
put " /t/ #{ topic . slug } / #{ topic . id } .json "
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ 'basic_topic' ] ) . to be_present
2018-03-12 22:20:47 -04:00
end
2020-04-22 11:53:47 -04:00
it " throws an error if it could not be saved " do
PostRevisor . any_instance . stubs ( :should_revise? ) . returns ( false )
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { title : " brand new title " }
expect ( response . status ) . to eq ( 422 )
expect ( response . parsed_body [ 'errors' ] . first ) . to eq (
I18n . t ( " activerecord.errors.models.topic.attributes.base.unable_to_update " )
)
end
2018-03-12 22:20:47 -04:00
it " can update a topic to an uncategorized topic " do
2021-03-17 11:25:43 -04:00
topic . update! ( category : category )
2018-03-12 22:20:47 -04:00
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
category_id : " "
}
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . category_id ) . to eq ( SiteSetting . uncategorized_category_id )
end
it 'allows a change of title' do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
title : 'This is a new title for the topic'
}
topic . reload
expect ( topic . title ) . to eq ( 'This is a new title for the topic' )
2020-03-21 09:33:10 -04:00
2021-05-23 19:10:22 -04:00
# emits a topic_edited event but not a post_edited web hook event
expect ( Jobs :: EmitWebHookEvent . jobs . length ) . to eq ( 1 )
job_args = Jobs :: EmitWebHookEvent . jobs [ 0 ] [ " args " ] . first
expect ( job_args [ " event_name " ] ) . to eq ( " topic_edited " )
payload = JSON . parse ( job_args [ " payload " ] )
expect ( payload [ " title " ] ) . to eq ( 'This is a new title for the topic' )
end
2022-03-11 13:01:08 -05:00
it 'allows update on short non-slug url' do
put " /t/ #{ topic . id } .json " , params : {
title : 'This is a new title for the topic'
}
topic . reload
expect ( topic . title ) . to eq ( 'This is a new title for the topic' )
end
it 'only allows update on digit ids' do
non_digit_id = " asdf "
original_title = topic . title
put " /t/ #{ non_digit_id } .json " , params : {
title : 'This is a new title for the topic'
}
topic . reload
expect ( topic . title ) . to eq ( original_title )
expect ( response . status ) . to eq ( 404 )
end
2021-05-23 19:10:22 -04:00
it 'allows a change of then updating the OP' do
topic . update ( user : user )
topic . first_post . update ( user : user )
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
title : 'This is a new title for the topic'
}
topic . reload
expect ( topic . title ) . to eq ( 'This is a new title for the topic' )
update_params = {
post : { raw : 'edited body' , edit_reason : 'typo' } ,
}
put " /posts/ #{ topic . first_post . id } .json " , params : update_params
# emits a topic_edited event and a post_edited web hook event
2020-03-21 09:33:10 -04:00
expect ( Jobs :: EmitWebHookEvent . jobs . length ) . to eq ( 2 )
job_args = Jobs :: EmitWebHookEvent . jobs [ 0 ] [ " args " ] . first
2021-05-23 19:10:22 -04:00
expect ( job_args [ " event_name " ] ) . to eq ( " topic_edited " )
payload = JSON . parse ( job_args [ " payload " ] )
expect ( payload [ " title " ] ) . to eq ( 'This is a new title for the topic' )
job_args = Jobs :: EmitWebHookEvent . jobs [ 1 ] [ " args " ] . first
2020-03-21 09:33:10 -04:00
expect ( job_args [ " event_name " ] ) . to eq ( " post_edited " )
payload = JSON . parse ( job_args [ " payload " ] )
2021-05-23 19:10:22 -04:00
expect ( payload [ " raw " ] ) . to eq ( " edited body " )
2018-03-12 22:20:47 -04:00
end
it " returns errors with invalid titles " do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
title : 'asdf'
}
expect ( response . status ) . to eq ( 422 )
2020-04-20 21:50:20 -04:00
expect ( response . parsed_body [ 'errors' ] ) . to match_array ( [ / Title is too short / , / Title seems unclear / ] )
2018-03-12 22:20:47 -04:00
end
2018-03-01 20:13:04 -05:00
2018-03-12 22:20:47 -04:00
it " returns errors when the rate limit is exceeded " do
EditRateLimiter . any_instance . expects ( :performed! ) . raises ( RateLimiter :: LimitExceeded . new ( 60 ) )
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
title : 'This is a new title for the topic'
}
expect ( response . status ) . to eq ( 429 )
end
it " returns errors with invalid categories " do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
category_id : - 1
}
expect ( response . status ) . to eq ( 422 )
end
it " doesn't call the PostRevisor when there is no changes " do
2018-05-31 10:45:32 -04:00
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
2019-05-17 04:26:00 -04:00
category_id : topic . category_id
2018-05-31 10:45:32 -04:00
}
end . not_to change ( PostRevision . all , :count )
2018-03-12 22:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
end
2021-12-20 20:21:47 -05:00
context " when using SiteSetting.disable_category_edit_notifications " do
it " doesn't bump the topic if the setting is enabled " do
SiteSetting . disable_category_edit_notifications = true
last_bumped_at = topic . bumped_at
expect ( last_bumped_at ) . not_to be_nil
2021-10-27 17:05:10 -04:00
2021-12-20 20:21:47 -05:00
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { category_id : category . id }
end . to change { topic . reload . category_id } . to ( category . id )
2021-10-27 17:05:10 -04:00
2021-12-20 20:21:47 -05:00
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . bumped_at ) . to eq_time ( last_bumped_at )
end
2021-10-27 17:05:10 -04:00
2021-12-20 20:21:47 -05:00
it " bumps the topic if the setting is disabled " do
SiteSetting . disable_category_edit_notifications = false
last_bumped_at = topic . bumped_at
expect ( last_bumped_at ) . not_to be_nil
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { category_id : category . id }
end . to change { topic . reload . category_id } . to ( category . id )
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . bumped_at ) . not_to eq_time ( last_bumped_at )
2021-11-02 13:53:21 -04:00
end
2021-12-20 20:21:47 -05:00
end
context " when using SiteSetting.disable_tags_edit_notifications " do
fab! ( :t1 ) { Fabricate ( :tag ) }
fab! ( :t2 ) { Fabricate ( :tag ) }
let ( :tags ) { [ t1 , t2 ] }
it " doesn't bump the topic if the setting is enabled " do
SiteSetting . disable_tags_edit_notifications = true
last_bumped_at = topic . bumped_at
expect ( last_bumped_at ) . not_to be_nil
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { tags : tags . map ( & :name ) }
2021-10-27 17:05:10 -04:00
2021-12-20 20:21:47 -05:00
expect ( topic . reload . tags ) . to match_array ( tags )
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . bumped_at ) . to eq_time ( last_bumped_at )
2021-11-02 13:53:21 -04:00
end
2021-10-27 17:05:10 -04:00
2021-12-20 20:21:47 -05:00
it " bumps the topic if the setting is disabled " do
SiteSetting . disable_tags_edit_notifications = false
last_bumped_at = topic . bumped_at
expect ( last_bumped_at ) . not_to be_nil
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { tags : tags . map ( & :name ) }
expect ( topic . reload . tags ) . to match_array ( tags )
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . bumped_at ) . not_to eq_time ( last_bumped_at )
2021-10-27 17:05:10 -04:00
end
end
2020-09-23 12:13:18 -04:00
describe " when first post is locked " do
it " blocks non-staff from editing even if 'trusted_users_can_edit_others' is true " do
SiteSetting . trusted_users_can_edit_others = true
2020-09-23 21:56:09 -04:00
user . update! ( trust_level : 3 )
topic . first_post . update! ( locked_by_id : admin . id )
2020-09-23 12:13:18 -04:00
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
title : topic . title + " hello "
}
2020-09-23 21:56:09 -04:00
2020-09-23 12:13:18 -04:00
expect ( response . status ) . to eq ( 403 )
end
it " allows staff to edit " do
sign_in ( Fabricate ( :admin ) )
2020-09-23 21:56:09 -04:00
topic . first_post . update! ( locked_by_id : admin . id )
2020-09-23 12:13:18 -04:00
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
title : topic . title + " hello "
}
expect ( response . status ) . to eq ( 200 )
end
end
2019-05-17 04:26:00 -04:00
context 'tags' do
before do
SiteSetting . tagging_enabled = true
end
it " can add a tag to topic " do
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
tags : [ tag . name ]
}
end . to change { topic . reload . first_post . revisions . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
expect ( topic . tags . pluck ( :id ) ) . to contain_exactly ( tag . id )
end
2020-03-30 16:42:47 -04:00
it " can create a tag " do
SiteSetting . min_trust_to_create_tag = 0
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
tags : [ " newtag " ]
}
end . to change { topic . reload . first_post . revisions . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . tags . pluck ( :name ) ) . to contain_exactly ( " newtag " )
end
it " can change the category and create a new tag " do
SiteSetting . min_trust_to_create_tag = 0
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
tags : [ " newtag " ] ,
category_id : category . id
}
end . to change { topic . reload . first_post . revisions . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . tags . pluck ( :name ) ) . to contain_exactly ( " newtag " )
end
2019-10-23 14:05:38 -04:00
it " can add a tag to wiki topic " do
SiteSetting . min_trust_to_edit_wiki_post = 2
topic . first_post . update! ( wiki : true )
2021-12-21 13:28:12 -05:00
sign_in ( user_2 )
2019-10-23 14:05:38 -04:00
expect do
put " /t/ #{ topic . id } /tags.json " , params : {
tags : [ tag . name ]
}
end . not_to change { topic . reload . first_post . revisions . count }
expect ( response . status ) . to eq ( 403 )
2021-12-21 13:28:12 -05:00
user_2 . update! ( trust_level : 2 )
2019-10-23 14:05:38 -04:00
expect do
put " /t/ #{ topic . id } /tags.json " , params : {
tags : [ tag . name ]
}
end . to change { topic . reload . first_post . revisions . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
expect ( topic . tags . pluck ( :id ) ) . to contain_exactly ( tag . id )
end
2019-05-17 04:26:00 -04:00
it 'does not remove tag if no params is given' do
topic . tags << tag
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json "
end . to_not change { topic . reload . tags . count }
expect ( response . status ) . to eq ( 200 )
end
it 'can remove a tag' do
topic . tags << tag
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
tags : [ " " ]
}
end . to change { topic . reload . first_post . revisions . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
expect ( topic . tags ) . to eq ( [ ] )
end
2021-07-29 08:14:25 -04:00
it 'does not cause a revision when tags have not changed' do
topic . tags << tag
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
tags : [ tag . name ]
}
end . to change { topic . reload . first_post . revisions . count } . by ( 0 )
expect ( response . status ) . to eq ( 200 )
end
2019-05-17 04:26:00 -04:00
end
2018-03-12 22:20:47 -04:00
context 'when topic is private' do
before do
topic . update! (
archetype : Archetype . private_message ,
category : nil ,
allowed_users : [ topic . user ]
)
end
context 'when there are no changes' do
it 'does not call the PostRevisor' do
2018-05-31 10:45:32 -04:00
expect do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
category_id : topic . category_id
}
end . not_to change ( PostRevision . all , :count )
2018-03-12 22:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
end
end
end
2019-02-26 05:21:55 -05:00
context 'updating to a category with restricted tags' do
2019-05-06 23:12:20 -04:00
fab! ( :restricted_category ) { Fabricate ( :category ) }
fab! ( :tag1 ) { Fabricate ( :tag ) }
fab! ( :tag2 ) { Fabricate ( :tag ) }
2021-03-17 11:25:43 -04:00
fab! ( :tag3 ) { Fabricate ( :tag ) }
fab! ( :tag_group_1 ) { Fabricate ( :tag_group , tag_names : [ tag1 . name ] ) }
2019-05-06 23:12:20 -04:00
fab! ( :tag_group_2 ) { Fabricate ( :tag_group ) }
2019-02-26 05:21:55 -05:00
2021-12-13 14:44:55 -05:00
before_all do
2019-02-26 05:21:55 -05:00
SiteSetting . tagging_enabled = true
topic . update! ( tags : [ tag1 ] )
end
2019-03-11 10:02:27 -04:00
it 'can’ t change to a category disallowing this topic current tags' do
2019-02-26 05:21:55 -05:00
restricted_category . allowed_tags = [ tag2 . name ]
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { category_id : restricted_category . id }
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2019-02-26 05:21:55 -05:00
expect ( response . status ) . to eq ( 422 )
expect ( result [ 'errors' ] ) . to be_present
expect ( topic . reload . category_id ) . not_to eq ( restricted_category . id )
end
2019-03-11 10:02:27 -04:00
it 'can’ t change to a category disallowing this topic current tag (through tag_group)' do
tag_group_2 . tags = [ tag2 ]
restricted_category . allowed_tag_groups = [ tag_group_2 . name ]
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { category_id : restricted_category . id }
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2019-03-11 10:02:27 -04:00
expect ( response . status ) . to eq ( 422 )
expect ( result [ 'errors' ] ) . to be_present
expect ( topic . reload . category_id ) . not_to eq ( restricted_category . id )
end
2019-02-26 05:21:55 -05:00
it 'can change to a category allowing this topic current tags' do
restricted_category . allowed_tags = [ tag1 . name ]
2019-03-11 10:02:27 -04:00
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { category_id : restricted_category . id }
expect ( response . status ) . to eq ( 200 )
end
it 'can change to a category allowing this topic current tags (through tag_group)' do
tag_group_1 . tags = [ tag1 ]
restricted_category . allowed_tag_groups = [ tag_group_1 . name ]
2019-02-26 05:21:55 -05:00
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { category_id : restricted_category . id }
expect ( response . status ) . to eq ( 200 )
end
it 'can change to a category allowing any tag' do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { category_id : category . id }
expect ( response . status ) . to eq ( 200 )
end
2019-07-23 11:06:25 -04:00
it 'can’ t add a category-only tags from another category to a category' do
restricted_category . allowed_tags = [ tag2 . name ]
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
2019-08-21 16:33:01 -04:00
tags : [ tag2 . name ] ,
2019-07-23 11:06:25 -04:00
category_id : category . id
}
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2019-07-23 11:06:25 -04:00
expect ( response . status ) . to eq ( 422 )
expect ( result [ 'errors' ] ) . to be_present
2019-08-21 16:33:01 -04:00
expect ( result [ 'errors' ] [ 0 ] ) . to include ( tag2 . name )
2019-07-23 11:06:25 -04:00
expect ( topic . reload . category_id ) . not_to eq ( restricted_category . id )
end
2019-08-21 16:33:01 -04:00
it 'allows category change when topic has a hidden tag' do
Fabricate ( :tag_group , permissions : { " staff " = > 1 } , tag_names : [ tag1 . name ] )
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
category_id : category . id
}
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2019-08-21 16:33:01 -04:00
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . tags ) . to include ( tag1 )
end
it 'allows category change when topic has a read-only tag' do
2019-11-12 14:28:44 -05:00
Fabricate ( :tag_group , permissions : { " staff " = > 1 , " everyone " = > 3 } , tag_names : [ tag3 . name ] )
topic . update! ( tags : [ tag3 ] )
2019-08-21 16:33:01 -04:00
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
category_id : category . id
}
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2019-08-21 16:33:01 -04:00
expect ( response . status ) . to eq ( 200 )
2019-11-12 14:28:44 -05:00
expect ( topic . reload . tags ) . to contain_exactly ( tag3 )
2019-08-21 16:33:01 -04:00
end
it 'does not leak tag name when trying to use a staff tag' do
2019-11-12 14:28:44 -05:00
Fabricate ( :tag_group , permissions : { " staff " = > 1 } , tag_names : [ tag3 . name ] )
2019-08-21 16:33:01 -04:00
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
2019-11-12 14:28:44 -05:00
tags : [ tag3 . name ] ,
2019-08-21 16:33:01 -04:00
category_id : category . id
}
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2019-08-21 16:33:01 -04:00
expect ( response . status ) . to eq ( 422 )
expect ( result [ 'errors' ] ) . to be_present
2019-11-12 14:28:44 -05:00
expect ( result [ 'errors' ] [ 0 ] ) . not_to include ( tag3 . name )
2019-08-21 16:33:01 -04:00
end
2019-07-23 11:06:25 -04:00
it 'will clean tag params' do
restricted_category . allowed_tags = [ tag2 . name ]
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
tags : [ " " ] ,
category_id : restricted_category . id
}
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2019-07-23 11:06:25 -04:00
expect ( response . status ) . to eq ( 200 )
end
2019-02-26 05:21:55 -05:00
end
2018-03-12 22:20:47 -04:00
context " allow_uncategorized_topics is false " do
before do
SiteSetting . allow_uncategorized_topics = false
end
it " can add a category to an uncategorized topic " do
put " /t/ #{ topic . slug } / #{ topic . id } .json " , params : {
category_id : category . id
}
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . category ) . to eq ( category )
end
end
end
end
2021-08-05 05:38:39 -04:00
describe " featured links " do
def fabricate_topic ( user , category = nil )
topic = Fabricate ( :topic , user : user , category : category )
2021-12-14 13:09:07 -05:00
Fabricate ( :post , user : post_author1 , topic : topic )
2021-08-05 05:38:39 -04:00
topic
end
it " allows to update topic featured link " do
sign_in ( trust_level_1 )
2021-12-21 13:28:12 -05:00
tl1_topic = fabricate_topic ( trust_level_1 )
put " /t/ #{ tl1_topic . slug } / #{ tl1_topic . id } .json " , params : {
2021-08-05 05:38:39 -04:00
featured_link : " https://discourse.org "
}
expect ( response . status ) . to eq ( 200 )
end
it " doesn't allow TL0 users to update topic featured link " do
sign_in ( trust_level_0 )
2021-12-21 13:28:12 -05:00
tl0_topic = fabricate_topic ( trust_level_0 )
put " /t/ #{ tl0_topic . slug } / #{ tl0_topic . id } .json " , params : {
2021-08-05 05:38:39 -04:00
featured_link : " https://discourse.org "
}
expect ( response . status ) . to eq ( 422 )
end
it " doesn't allow to update topic featured link if featured links are disabled in settings " do
sign_in ( trust_level_1 )
SiteSetting . topic_featured_link_enabled = false
2021-12-21 13:28:12 -05:00
tl1_topic = fabricate_topic ( trust_level_1 )
put " /t/ #{ tl1_topic . slug } / #{ tl1_topic . id } .json " , params : {
2021-08-05 05:38:39 -04:00
featured_link : " https://discourse.org "
}
expect ( response . status ) . to eq ( 422 )
end
it " doesn't allow to update topic featured link in the category with forbidden feature links " do
sign_in ( trust_level_1 )
category = Fabricate ( :category , topic_featured_link_allowed : false )
2021-12-21 13:28:12 -05:00
tl1_topic_in_category = fabricate_topic ( trust_level_1 , category )
put " /t/ #{ tl1_topic_in_category . slug } / #{ tl1_topic_in_category . id } .json " , params : {
2021-08-05 05:38:39 -04:00
featured_link : " https://discourse.org "
}
expect ( response . status ) . to eq ( 422 )
end
end
2018-03-01 20:13:04 -05:00
end
2022-02-08 22:55:32 -05:00
describe '#show_by_external_id' do
fab! ( :private_topic ) { Fabricate ( :private_message_topic , external_id : 'private' ) }
fab! ( :topic ) { Fabricate ( :topic , external_id : 'asdf' ) }
it 'returns 301 when found' do
get " /t/external_id/asdf.json "
expect ( response . status ) . to eq ( 301 )
2022-03-17 21:27:51 -04:00
expect ( response ) . to redirect_to ( topic . relative_url + " .json " )
2022-02-08 22:55:32 -05:00
end
it 'returns right response when not found' do
get " /t/external_id/fdsa.json "
expect ( response . status ) . to eq ( 404 )
end
2022-03-17 21:27:51 -04:00
it 'preserves only select query params' do
get " /t/external_id/asdf.json " , params : {
filter_top_level_replies : true
}
expect ( response . status ) . to eq ( 301 )
expect ( response ) . to redirect_to ( topic . relative_url + " .json?filter_top_level_replies=true " )
get " /t/external_id/asdf.json " , params : {
not_valid : true
}
expect ( response . status ) . to eq ( 301 )
expect ( response ) . to redirect_to ( topic . relative_url + " .json " )
get " /t/external_id/asdf.json " , params : {
filter_top_level_replies : true ,
post_number : 9999
}
expect ( response . status ) . to eq ( 301 )
expect ( response ) . to redirect_to ( topic . relative_url + " /9999.json?filter_top_level_replies=true " )
get " /t/external_id/asdf.json " , params : {
filter_top_level_replies : true ,
print : true
}
expect ( response . status ) . to eq ( 301 )
expect ( response ) . to redirect_to ( topic . relative_url + " .json?print=true&filter_top_level_replies=true " )
end
2022-02-08 22:55:32 -05:00
describe 'when user does not have access to the topic' do
it 'should return the right response' do
sign_in ( user )
get " /t/external_id/private.json "
expect ( response . status ) . to eq ( 403 )
expect ( response . body ) . to include ( I18n . t ( 'invalid_access' ) )
end
end
end
2017-09-27 23:04:17 -04:00
describe '#show' do
2021-12-10 15:25:26 -05:00
use_redis_snapshotting
2021-12-13 14:44:55 -05:00
fab! ( :private_topic ) { pm }
2021-12-14 13:09:07 -05:00
fab! ( :topic ) { Fabricate ( :post , user : post_author1 ) . topic }
2018-05-31 10:45:32 -04:00
2021-12-10 15:25:26 -05:00
fab! ( :p1 ) { Fabricate ( :post , user : topic . user ) }
fab! ( :p2 ) { Fabricate ( :post , user : topic . user ) }
2017-09-27 23:04:17 -04:00
describe 'when topic is not allowed' do
it 'should return the right response' do
2019-10-08 07:15:08 -04:00
SiteSetting . detailed_404 = true
2017-09-27 23:04:17 -04:00
sign_in ( user )
get " /t/ #{ private_topic . id } .json "
expect ( response . status ) . to eq ( 403 )
2019-10-08 07:15:08 -04:00
expect ( response . body ) . to include ( I18n . t ( 'invalid_access' ) )
2017-09-27 23:04:17 -04:00
end
end
2018-05-31 10:45:32 -04:00
2020-11-24 06:06:52 -05:00
describe 'when topic is allowed to a group' do
2021-03-17 11:25:43 -04:00
fab! ( :group ) { Fabricate ( :group , public_admission : true ) }
fab! ( :category ) do
2020-11-24 06:06:52 -05:00
Fabricate ( :category_with_definition ) . tap do | category |
category . set_permissions ( group = > :full )
category . save!
end
end
2021-03-17 11:25:43 -04:00
fab! ( :topic ) { Fabricate ( :topic , category : category ) }
2020-11-24 06:06:52 -05:00
before do
SiteSetting . detailed_404 = true
end
it 'shows a descriptive error message containing the group name' do
get " /t/ #{ topic . id } .json "
html = CGI . unescapeHTML ( response . parsed_body [ " extras " ] [ " html " ] )
expect ( response . status ) . to eq ( 403 )
expect ( html ) . to include ( I18n . t ( 'not_in_group.title_topic' , group : group . name ) )
expect ( html ) . to include ( I18n . t ( 'not_in_group.join_group' ) )
end
end
2021-03-04 09:07:37 -05:00
it 'correctly renders canonicals' do
2018-05-31 10:45:32 -04:00
get " /t/ #{ topic . id } " , params : { slug : topic . slug }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
expect ( css_select ( " link[rel=canonical] " ) . length ) . to eq ( 1 )
2018-06-05 03:29:17 -04:00
expect ( response . headers [ " Cache-Control " ] ) . to eq ( " no-cache, no-store " )
2018-05-31 10:45:32 -04:00
end
it 'returns 301 even if slug does not match URL' do
# in the past we had special logic for unlisted topics
# we would require slug unless you made a json call
# this was not really providing any security
#
# we no longer require a topic be visible to perform url correction
# if you need to properly hide a topic for users use a secure category
# or a PM
2021-12-21 13:28:12 -05:00
Fabricate ( :post , user : post_author1 , topic : invisible_topic )
2018-05-31 10:45:32 -04:00
2021-12-21 13:28:12 -05:00
get " /t/ #{ invisible_topic . id } .json " , params : { slug : invisible_topic . slug }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
get " /t/ #{ topic . id } .json " , params : { slug : " just-guessing " }
expect ( response . status ) . to eq ( 301 )
get " /t/ #{ topic . slug } .json "
expect ( response . status ) . to eq ( 301 )
end
it 'shows a topic correctly' do
get " /t/ #{ topic . slug } / #{ topic . id } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
end
it 'return 404 for an invalid page' do
get " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { page : 2 }
expect ( response . status ) . to eq ( 404 )
end
it 'can find a topic given a slug in the id param' do
get " /t/ #{ topic . slug } "
expect ( response ) . to redirect_to ( topic . relative_url )
end
it 'can find a topic when a slug has a number in front' do
2021-12-14 13:09:07 -05:00
another_topic = Fabricate ( :post , user : post_author1 ) . topic
2018-05-31 10:45:32 -04:00
topic . update_column ( :slug , " #{ another_topic . id } -reasons-discourse-is-awesome " )
get " /t/ #{ another_topic . id } -reasons-discourse-is-awesome "
expect ( response ) . to redirect_to ( topic . relative_url )
end
it 'keeps the post_number parameter around when redirecting' do
get " /t/ #{ topic . slug } " , params : { post_number : 42 }
expect ( response ) . to redirect_to ( topic . relative_url + " /42 " )
end
it 'keeps the page around when redirecting' do
get " /t/ #{ topic . slug } " , params : {
post_number : 42 , page : 123
}
expect ( response ) . to redirect_to ( topic . relative_url + " /42?page=123 " )
end
it 'does not accept page params as an array' do
get " /t/ #{ topic . slug } " , params : {
post_number : 42 , page : [ 2 ]
}
expect ( response ) . to redirect_to ( " #{ topic . relative_url } /42?page=1 " )
end
it 'returns 404 when an invalid slug is given and no id' do
get " /t/nope-nope.json "
expect ( response . status ) . to eq ( 404 )
end
it 'returns a 404 when slug and topic id do not match a topic' do
get " /t/made-up-topic-slug/123456.json "
expect ( response . status ) . to eq ( 404 )
end
it 'returns a 404 for an ID that is larger than postgres limits' do
get " /t/made-up-topic-slug/5014217323220164041.json "
expect ( response . status ) . to eq ( 404 )
end
2022-04-25 15:04:13 -04:00
it " doesn't use print mode when print equals false " do
SiteSetting . max_prints_per_hour_per_user = 0
get " /t/ #{ topic . slug } / #{ topic . id } .json?print=false "
expect ( response . status ) . to eq ( 200 )
end
2018-05-31 10:45:32 -04:00
context 'a topic with nil slug exists' do
before do
nil_slug_topic = Fabricate ( :topic )
Topic . connection . execute ( " update topics set slug=null where id = #{ nil_slug_topic . id } " ) # can't find a way to set slug column to null using the model
end
it 'returns a 404 when slug and topic id do not match a topic' do
get " /t/made-up-topic-slug/123123.json "
expect ( response . status ) . to eq ( 404 )
end
end
context 'permission errors' do
2019-05-06 23:12:20 -04:00
fab! ( :allowed_user ) { Fabricate ( :user ) }
2021-03-17 11:25:43 -04:00
fab! ( :allowed_group ) { Fabricate ( :group ) }
fab! ( :accessible_group ) { Fabricate ( :group , public_admission : true ) }
fab! ( :secure_category ) do
2018-05-31 10:45:32 -04:00
c = Fabricate ( :category )
c . permissions = [ [ allowed_group , :full ] ]
c . save
allowed_user . groups = [ allowed_group ]
allowed_user . save
c
end
2021-03-17 11:25:43 -04:00
fab! ( :accessible_category ) do
2019-07-04 04:12:39 -04:00
Fabricate ( :category ) . tap do | c |
c . set_permissions ( accessible_group = > :full )
c . save!
end
end
2021-03-17 11:25:43 -04:00
fab! ( :normal_topic ) { Fabricate ( :topic ) }
fab! ( :secure_topic ) { Fabricate ( :topic , category : secure_category ) }
fab! ( :private_topic ) { Fabricate ( :private_message_topic , user : allowed_user ) }
2021-12-13 14:44:55 -05:00
# Can't use fab!, because deleted_topics can't be re-found
before_all do
@deleted_topic = Fabricate ( :deleted_topic )
@deleted_secure_topic = Fabricate ( :topic , category : secure_category , deleted_at : 1 . day . ago )
@deleted_private_topic = Fabricate ( :private_message_topic , user : allowed_user , deleted_at : 1 . day . ago )
end
let ( :deleted_topic ) { @deleted_topic }
let ( :deleted_secure_topic ) { @deleted_secure_topic }
let ( :deleted_private_topic ) { @deleted_private_topic }
2021-05-20 21:43:47 -04:00
let! ( :nonexistent_topic_id ) { Topic . last . id + 10000 }
2021-03-17 11:25:43 -04:00
fab! ( :secure_accessible_topic ) { Fabricate ( :topic , category : accessible_category ) }
2018-05-31 10:45:32 -04:00
2022-01-05 13:12:50 -05:00
shared_examples " various scenarios " do | expected , request_json : |
2018-05-31 10:45:32 -04:00
expected . each do | key , value |
it " returns #{ value } for #{ key } " do
2021-05-20 21:43:47 -04:00
slug = key == :nonexistent ? " garbage-slug " : send ( key . to_s ) . slug
topic_id = key == :nonexistent ? nonexistent_topic_id : send ( key . to_s ) . id
2021-12-02 10:12:25 -05:00
format = request_json ? " .json " : " "
get " /t/ #{ slug } / #{ topic_id } #{ format } "
2018-05-31 10:45:32 -04:00
expect ( response . status ) . to eq ( value )
end
end
2020-05-27 14:28:38 -04:00
expected_slug_response = expected [ :secure_topic ] == 200 ? 301 : expected [ :secure_topic ]
it " will return a #{ expected_slug_response } when requesting a secure topic by slug " do
2021-12-02 10:12:25 -05:00
format = request_json ? " .json " : " "
get " /t/ #{ secure_topic . slug } #{ format } "
2020-05-27 14:28:38 -04:00
expect ( response . status ) . to eq ( expected_slug_response )
end
2018-05-31 10:45:32 -04:00
end
2019-10-08 07:15:08 -04:00
context 'without detailed error pages' do
2018-05-31 10:45:32 -04:00
before do
2019-10-08 07:15:08 -04:00
SiteSetting . detailed_404 = false
2018-05-31 10:45:32 -04:00
end
2019-10-08 07:15:08 -04:00
context 'anonymous' do
expected = {
normal_topic : 200 ,
secure_topic : 404 ,
private_topic : 404 ,
deleted_topic : 404 ,
deleted_secure_topic : 404 ,
deleted_private_topic : 404 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 404
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2018-05-31 10:45:32 -04:00
end
2019-10-08 07:15:08 -04:00
context 'anonymous with login required' do
before do
SiteSetting . login_required = true
end
expected = {
normal_topic : 302 ,
secure_topic : 302 ,
private_topic : 302 ,
deleted_topic : 302 ,
deleted_secure_topic : 302 ,
deleted_private_topic : 302 ,
2021-05-20 21:43:47 -04:00
nonexistent : 302 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 302
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2019-10-08 07:15:08 -04:00
end
2018-05-31 10:45:32 -04:00
2021-12-02 10:12:25 -05:00
context 'anonymous with login required, requesting json' do
before do
SiteSetting . login_required = true
end
expected = {
normal_topic : 403 ,
secure_topic : 403 ,
private_topic : 403 ,
deleted_topic : 403 ,
deleted_secure_topic : 403 ,
deleted_private_topic : 403 ,
nonexistent : 403 ,
secure_accessible_topic : 403
}
include_examples " various scenarios " , expected , request_json : true
end
2019-10-08 07:15:08 -04:00
context 'normal user' do
before do
sign_in ( user )
end
expected = {
normal_topic : 200 ,
secure_topic : 404 ,
private_topic : 404 ,
deleted_topic : 404 ,
deleted_secure_topic : 404 ,
deleted_private_topic : 404 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 404
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2018-05-31 10:45:32 -04:00
end
2019-10-08 07:15:08 -04:00
context 'allowed user' do
before do
sign_in ( allowed_user )
end
2018-05-31 10:45:32 -04:00
2019-10-08 07:15:08 -04:00
expected = {
normal_topic : 200 ,
secure_topic : 200 ,
private_topic : 200 ,
deleted_topic : 404 ,
deleted_secure_topic : 404 ,
deleted_private_topic : 404 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 404
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2018-05-31 10:45:32 -04:00
end
2019-10-08 07:15:08 -04:00
context 'moderator' do
before do
sign_in ( moderator )
end
expected = {
normal_topic : 200 ,
secure_topic : 404 ,
private_topic : 404 ,
deleted_topic : 200 ,
deleted_secure_topic : 404 ,
deleted_private_topic : 404 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 404
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2019-10-08 07:15:08 -04:00
end
context 'admin' do
before do
sign_in ( admin )
end
expected = {
normal_topic : 200 ,
secure_topic : 200 ,
private_topic : 200 ,
deleted_topic : 200 ,
deleted_secure_topic : 200 ,
deleted_private_topic : 200 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 200
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2019-10-08 07:15:08 -04:00
end
2018-05-31 10:45:32 -04:00
end
2019-10-08 07:15:08 -04:00
context 'with detailed error pages' do
2018-05-31 10:45:32 -04:00
before do
2019-10-08 07:15:08 -04:00
SiteSetting . detailed_404 = true
2018-05-31 10:45:32 -04:00
end
2019-10-08 07:15:08 -04:00
context 'anonymous' do
expected = {
normal_topic : 200 ,
secure_topic : 403 ,
private_topic : 403 ,
deleted_topic : 410 ,
deleted_secure_topic : 403 ,
deleted_private_topic : 403 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 403
}
2021-12-02 10:12:25 -05:00
include_examples " various scenarios " , expected , request_json : true
2019-10-08 07:15:08 -04:00
end
context 'anonymous with login required' do
before do
SiteSetting . login_required = true
end
expected = {
normal_topic : 302 ,
secure_topic : 302 ,
private_topic : 302 ,
deleted_topic : 302 ,
deleted_secure_topic : 302 ,
deleted_private_topic : 302 ,
2021-05-20 21:43:47 -04:00
nonexistent : 302 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 302
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2019-10-08 07:15:08 -04:00
end
context 'normal user' do
before do
sign_in ( user )
end
expected = {
normal_topic : 200 ,
secure_topic : 403 ,
private_topic : 403 ,
deleted_topic : 410 ,
deleted_secure_topic : 403 ,
deleted_private_topic : 403 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 403
}
2021-12-02 10:12:25 -05:00
include_examples " various scenarios " , expected , request_json : true
2019-10-08 07:15:08 -04:00
end
context 'allowed user' do
before do
sign_in ( allowed_user )
end
expected = {
normal_topic : 200 ,
secure_topic : 200 ,
private_topic : 200 ,
deleted_topic : 410 ,
deleted_secure_topic : 410 ,
deleted_private_topic : 410 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 403
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2019-10-08 07:15:08 -04:00
end
context 'moderator' do
before do
sign_in ( moderator )
end
expected = {
normal_topic : 200 ,
secure_topic : 403 ,
private_topic : 403 ,
deleted_topic : 200 ,
deleted_secure_topic : 403 ,
deleted_private_topic : 403 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 403
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2019-10-08 07:15:08 -04:00
end
context 'admin' do
before do
sign_in ( admin )
end
expected = {
normal_topic : 200 ,
secure_topic : 200 ,
private_topic : 200 ,
deleted_topic : 200 ,
deleted_secure_topic : 200 ,
deleted_private_topic : 200 ,
2021-05-20 21:43:47 -04:00
nonexistent : 404 ,
2019-10-08 07:15:08 -04:00
secure_accessible_topic : 200
}
2022-01-05 13:12:50 -05:00
include_examples " various scenarios " , expected , request_json : false
2019-10-08 07:15:08 -04:00
end
2018-05-31 10:45:32 -04:00
end
2019-10-08 07:15:08 -04:00
2018-05-31 10:45:32 -04:00
end
it 'records a view' do
expect do
get " /t/ #{ topic . slug } / #{ topic . id } .json "
end . to change ( TopicViewItem , :count ) . by ( 1 )
end
2018-11-20 19:58:47 -05:00
it 'records a view to invalid post_number' do
expect do
get " /t/ #{ topic . slug } / #{ topic . id } / #{ 256 ** 4 } " , params : {
u : user . username
}
expect ( response . status ) . to eq ( 200 )
end . to change { IncomingLink . count } . by ( 1 )
end
2018-05-31 10:45:32 -04:00
it 'records incoming links' do
expect do
get " /t/ #{ topic . slug } / #{ topic . id } " , params : {
u : user . username
}
end . to change { IncomingLink . count } . by ( 1 )
end
context 'print' do
it " doesn't renders the print view when disabled " do
SiteSetting . max_prints_per_hour_per_user = 0
get " /t/ #{ topic . slug } / #{ topic . id } /print "
expect ( response ) . to be_forbidden
end
it 'renders the print view when enabled' do
SiteSetting . max_prints_per_hour_per_user = 10
2018-06-05 00:03:49 -04:00
get " /t/ #{ topic . slug } / #{ topic . id } /print " , headers : { HTTP_USER_AGENT : " Rails Testing " }
2018-05-31 10:45:32 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-06-05 00:03:49 -04:00
body = response . body
expect ( body ) . to have_tag ( :body , class : 'crawler' )
expect ( body ) . to_not have_tag ( :meta , with : { name : 'fragment' } )
end
it " uses the application layout when there's no param " do
SiteSetting . max_prints_per_hour_per_user = 10
get " /t/ #{ topic . slug } / #{ topic . id } " , headers : { HTTP_USER_AGENT : " Rails Testing " }
body = response . body
2022-06-20 10:33:05 -04:00
expect ( body ) . to have_tag ( :script , src : " /assets/discourse.js " )
2018-06-05 00:03:49 -04:00
expect ( body ) . to have_tag ( :meta , with : { name : 'fragment' } )
2018-05-31 10:45:32 -04:00
end
end
it 'records redirects' do
get " /t/ #{ topic . id } " , headers : { HTTP_REFERER : " http://twitter.com " }
get " /t/ #{ topic . slug } / #{ topic . id } " , headers : { HTTP_REFERER : nil }
link = IncomingLink . first
expect ( link . referer ) . to eq ( 'http://twitter.com' )
end
it 'tracks a visit for all html requests' do
sign_in ( user )
get " /t/ #{ topic . slug } / #{ topic . id } "
topic_user = TopicUser . where ( user : user , topic : topic ) . first
2020-03-10 17:13:17 -04:00
expect ( topic_user . last_visited_at ) . to eq_time ( topic_user . first_visited_at )
2018-05-31 10:45:32 -04:00
end
context 'consider for a promotion' do
before do
SiteSetting . tl1_requires_topics_entered = 0
SiteSetting . tl1_requires_read_posts = 0
SiteSetting . tl1_requires_time_spent_mins = 0
SiteSetting . tl1_requires_time_spent_mins = 0
end
it " reviews the user for a promotion if they're new " do
sign_in ( user )
user . update_column ( :trust_level , TrustLevel [ 0 ] )
get " /t/ #{ topic . slug } / #{ topic . id } .json "
user . reload
expect ( user . trust_level ) . to eq ( 1 )
end
end
context 'filters' do
def extract_post_stream
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-31 10:45:32 -04:00
json [ " post_stream " ] [ " posts " ] . map { | post | post [ " id " ] }
end
before do
TopicView . stubs ( :chunk_size ) . returns ( 2 )
@post_ids = topic . posts . pluck ( :id )
3 . times do
2021-12-14 13:09:07 -05:00
@post_ids << Fabricate ( :post , user : post_author1 , topic : topic ) . id
2018-05-31 10:45:32 -04:00
end
end
it 'grabs the correct set of posts' do
get " /t/ #{ topic . slug } / #{ topic . id } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
expect ( extract_post_stream ) . to eq ( @post_ids [ 0 .. 1 ] )
get " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { page : 1 }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
expect ( extract_post_stream ) . to eq ( @post_ids [ 0 .. 1 ] )
get " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { page : 2 }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
expect ( extract_post_stream ) . to eq ( @post_ids [ 2 .. 3 ] )
post_number = topic . posts . pluck ( :post_number ) . sort [ 3 ]
get " /t/ #{ topic . slug } / #{ topic . id } / #{ post_number } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
expect ( extract_post_stream ) . to eq ( @post_ids [ - 2 .. - 1 ] )
2021-05-28 04:36:45 -04:00
TopicView . stubs ( :chunk_size ) . returns ( 3 )
get " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { page : 1 }
expect ( response . status ) . to eq ( 200 )
expect ( extract_post_stream ) . to eq ( @post_ids [ 0 .. 2 ] )
get " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { page : 2 }
expect ( response . status ) . to eq ( 200 )
expect ( extract_post_stream ) . to eq ( @post_ids [ 3 .. 3 ] )
get " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { page : 3 }
expect ( response . status ) . to eq ( 404 )
TopicView . stubs ( :chunk_size ) . returns ( 4 )
get " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { page : 1 }
expect ( response . status ) . to eq ( 200 )
expect ( extract_post_stream ) . to eq ( @post_ids [ 0 .. 3 ] )
get " /t/ #{ topic . slug } / #{ topic . id } .json " , params : { page : 2 }
expect ( response . status ) . to eq ( 404 )
2018-05-31 10:45:32 -04:00
end
end
2020-12-10 12:02:07 -05:00
describe '#show filters' do
2021-12-14 13:09:07 -05:00
fab! ( :post ) { Fabricate ( :post , user : post_author1 ) }
2021-03-17 11:25:43 -04:00
fab! ( :topic ) { post . topic }
2021-12-14 13:09:07 -05:00
fab! ( :post2 ) { Fabricate ( :post , user : post_author2 , topic : topic ) }
2020-12-10 12:02:07 -05:00
describe 'filter by replies to a post' do
2021-12-14 13:09:07 -05:00
fab! ( :post3 ) { Fabricate ( :post , user : post_author3 , topic : topic , reply_to_post_number : post2 . post_number ) }
fab! ( :post4 ) { Fabricate ( :post , user : post_author4 , topic : topic , reply_to_post_number : post2 . post_number ) }
fab! ( :post5 ) { Fabricate ( :post , user : post_author5 , topic : topic ) }
2021-03-17 11:25:43 -04:00
fab! ( :quote_reply ) { Fabricate ( :basic_reply , user : user , topic : topic ) }
fab! ( :post_reply ) { PostReply . create ( post_id : post2 . id , reply_post_id : quote_reply . id ) }
2020-12-10 12:02:07 -05:00
it 'should return the right posts' do
get " /t/ #{ topic . id } .json " , params : {
replies_to_post_number : post2 . post_number
}
expect ( response . status ) . to eq ( 200 )
body = response . parsed_body
expect ( body . has_key? ( " suggested_topics " ) ) . to eq ( false )
expect ( body . has_key? ( " related_messages " ) ) . to eq ( false )
ids = body [ " post_stream " ] [ " posts " ] . map { | p | p [ " id " ] }
2020-12-14 15:24:36 -05:00
expect ( ids ) . to eq ( [ post . id , post2 . id , post3 . id , post4 . id , quote_reply . id ] )
2020-12-10 12:02:07 -05:00
end
end
2022-03-02 15:25:36 -05:00
describe 'filter by top level replies' do
fab! ( :post3 ) { Fabricate ( :post , user : post_author3 , topic : topic , reply_to_post_number : post2 . post_number ) }
fab! ( :post4 ) { Fabricate ( :post , user : post_author4 , topic : topic , reply_to_post_number : post2 . post_number ) }
fab! ( :post5 ) { Fabricate ( :post , user : post_author5 , topic : topic ) }
fab! ( :post6 ) { Fabricate ( :post , user : post_author4 , topic : topic , reply_to_post_number : post5 . post_number ) }
it 'should return the right posts' do
get " /t/ #{ topic . id } .json " , params : {
filter_top_level_replies : true
}
expect ( response . status ) . to eq ( 200 )
body = response . parsed_body
expect ( body . has_key? ( " suggested_topics " ) ) . to eq ( false )
expect ( body . has_key? ( " related_messages " ) ) . to eq ( false )
ids = body [ " post_stream " ] [ " posts " ] . map { | p | p [ " id " ] }
expect ( ids ) . to eq ( [ post2 . id , post5 . id ] )
end
end
2020-12-10 12:02:07 -05:00
describe 'filter upwards by post id' do
2021-12-14 13:09:07 -05:00
fab! ( :post3 ) { Fabricate ( :post , user : post_author3 , topic : topic ) }
fab! ( :post4 ) { Fabricate ( :post , user : post_author4 , topic : topic , reply_to_post_number : post3 . post_number ) }
fab! ( :post5 ) { Fabricate ( :post , user : post_author5 , topic : topic , reply_to_post_number : post4 . post_number ) }
fab! ( :post6 ) { Fabricate ( :post , user : post_author6 , topic : topic ) }
2020-12-10 12:02:07 -05:00
it 'should return the right posts' do
get " /t/ #{ topic . id } .json " , params : {
filter_upwards_post_id : post5 . id
}
expect ( response . status ) . to eq ( 200 )
body = response . parsed_body
expect ( body . has_key? ( " suggested_topics " ) ) . to eq ( false )
expect ( body . has_key? ( " related_messages " ) ) . to eq ( false )
ids = body [ " post_stream " ] [ " posts " ] . map { | p | p [ " id " ] }
# includes topic OP, current post and subsequent posts
# but only one level of parents, respecting default max_reply_history = 1
expect ( ids ) . to eq ( [ post . id , post4 . id , post5 . id , post6 . id ] )
end
it 'should respect max_reply_history site setting' do
SiteSetting . max_reply_history = 2
get " /t/ #{ topic . id } .json " , params : {
filter_upwards_post_id : post5 . id
}
expect ( response . status ) . to eq ( 200 )
body = response . parsed_body
ids = body [ " post_stream " ] [ " posts " ] . map { | p | p [ " id " ] }
# includes 2 levels of replies (post3 and post4)
expect ( ids ) . to eq ( [ post . id , post3 . id , post4 . id , post5 . id , post6 . id ] )
end
end
end
2018-05-31 10:45:32 -04:00
context " when 'login required' site setting has been enabled " do
before { SiteSetting . login_required = true }
context 'and the user is logged in' do
2021-12-13 14:44:55 -05:00
before { sign_in ( user ) }
2018-05-31 10:45:32 -04:00
it 'shows the topic' do
get " /t/ #{ topic . slug } / #{ topic . id } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
end
end
context 'and the user is not logged in' do
2019-11-05 09:10:23 -05:00
let ( :api_key ) { Fabricate ( :api_key , user : topic . user ) }
2018-05-31 10:45:32 -04:00
2021-12-02 10:12:25 -05:00
it 'redirects browsers to the login page' do
get " /t/ #{ topic . slug } / #{ topic . id } "
2018-05-31 10:45:32 -04:00
expect ( response ) . to redirect_to login_path
end
2021-12-02 10:12:25 -05:00
it 'raises a 403 for json requests' do
get " /t/ #{ topic . slug } / #{ topic . id } .json "
expect ( response . status ) . to eq ( 403 )
end
2018-05-31 10:45:32 -04:00
it 'shows the topic if valid api key is provided' do
2020-05-12 08:35:36 -04:00
get " /t/ #{ topic . slug } / #{ topic . id } .json " , headers : { " HTTP_API_KEY " = > api_key . key }
2018-05-31 10:45:32 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
topic . reload
expect ( topic . views ) . to eq ( 1 )
end
it 'returns 403 for an invalid key' do
[ :json , :html ] . each do | format |
2020-05-12 08:35:36 -04:00
get " /t/ #{ topic . slug } / #{ topic . id } . #{ format } " , headers : { " HTTP_API_KEY " = > " bad " }
2018-05-31 10:45:32 -04:00
2019-10-08 07:15:08 -04:00
expect ( response . code . to_i ) . to eq ( 403 )
2018-05-31 10:45:32 -04:00
expect ( response . body ) . to include ( I18n . t ( " invalid_access " ) )
end
end
end
end
it " is included for unlisted topics " do
2021-12-21 13:28:12 -05:00
get " /t/ #{ invisible_topic . slug } / #{ invisible_topic . id } .json "
2018-05-31 10:45:32 -04:00
expect ( response . headers [ 'X-Robots-Tag' ] ) . to eq ( 'noindex' )
end
it " is not included for normal topics " do
get " /t/ #{ topic . slug } / #{ topic . id } .json "
expect ( response . headers [ 'X-Robots-Tag' ] ) . to eq ( nil )
end
2018-06-05 00:03:49 -04:00
2020-05-10 21:06:55 -04:00
it " is included when allow_index_in_robots_txt is set to false " do
SiteSetting . allow_index_in_robots_txt = false
get " /t/ #{ topic . slug } / #{ topic . id } .json "
2020-05-10 22:14:21 -04:00
expect ( response . headers [ 'X-Robots-Tag' ] ) . to eq ( 'noindex, nofollow' )
2020-05-10 21:06:55 -04:00
end
2018-06-05 00:03:49 -04:00
it " doesn't store an incoming link when there's no referer " do
expect {
get " /t/ #{ topic . id } .json "
} . not_to change ( IncomingLink , :count )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-06-05 00:03:49 -04:00
end
it " doesn't raise an error on a very long link " do
get " /t/ #{ topic . id } .json " , headers : { HTTP_REFERER : " http:// #{ 'a' * 2000 } .com " }
expect ( response . status ) . to eq ( 200 )
end
describe " has_escaped_fragment? " do
context " when the SiteSetting is disabled " do
it " uses the application layout even with an escaped fragment param " do
SiteSetting . enable_escaped_fragments = false
get " /t/ #{ topic . slug } / #{ topic . id } " , params : {
_escaped_fragment_ : 'true'
}
body = response . body
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2022-06-20 10:33:05 -04:00
expect ( body ) . to have_tag ( :script , with : { src : " /assets/discourse.js " } )
2018-06-05 00:03:49 -04:00
expect ( body ) . to_not have_tag ( :meta , with : { name : 'fragment' } )
end
end
context " when the SiteSetting is enabled " do
before do
SiteSetting . enable_escaped_fragments = true
end
it " uses the application layout when there's no param " do
get " /t/ #{ topic . slug } / #{ topic . id } "
body = response . body
2022-06-20 10:33:05 -04:00
expect ( body ) . to have_tag ( :script , with : { src : " /assets/discourse.js " } )
2018-06-05 00:03:49 -04:00
expect ( body ) . to have_tag ( :meta , with : { name : 'fragment' } )
end
it " uses the crawler layout when there's an _escaped_fragment_ param " do
get " /t/ #{ topic . slug } / #{ topic . id } " , params : {
_escaped_fragment_ : true
} , headers : { HTTP_USER_AGENT : " Rails Testing " }
body = response . body
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-06-05 00:03:49 -04:00
expect ( body ) . to have_tag ( :body , with : { class : 'crawler' } )
expect ( body ) . to_not have_tag ( :meta , with : { name : 'fragment' } )
end
end
end
describe 'clear_notifications' do
it 'correctly clears notifications if specified via cookie' do
2019-11-15 00:48:24 -05:00
set_subfolder " /eviltrout "
2018-06-05 00:03:49 -04:00
notification = Fabricate ( :notification )
sign_in ( notification . user )
cookies [ 'cn' ] = " 2828,100, #{ notification . id } "
get " /t/ #{ topic . id } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-06-05 00:03:49 -04:00
expect ( response . cookies [ 'cn' ] ) . to eq ( nil )
2018-06-28 11:03:36 -04:00
expect ( response . headers [ 'Set-Cookie' ] ) . to match ( / ^cn=;.*path= \/ eviltrout / )
2018-06-05 00:03:49 -04:00
notification . reload
expect ( notification . read ) . to eq ( true )
end
it 'correctly clears notifications if specified via header' do
notification = Fabricate ( :notification )
sign_in ( notification . user )
get " /t/ #{ topic . id } .json " , headers : { " Discourse-Clear-Notifications " = > " 2828,100, #{ notification . id } " }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-06-05 00:03:49 -04:00
notification . reload
expect ( notification . read ) . to eq ( true )
end
end
describe " read only header " do
it " returns no read only header by default " do
get " /t/ #{ topic . id } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-06-05 00:03:49 -04:00
expect ( response . headers [ 'Discourse-Readonly' ] ) . to eq ( nil )
end
it " returns a readonly header if the site is read only " do
2019-06-21 10:08:57 -04:00
Discourse . received_postgres_readonly!
2018-06-05 00:03:49 -04:00
get " /t/ #{ topic . id } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-06-05 00:03:49 -04:00
expect ( response . headers [ 'Discourse-Readonly' ] ) . to eq ( 'true' )
end
end
2018-10-17 04:19:32 -04:00
describe " image only topic " do
it " uses image alt tag for meta description " do
2021-12-14 13:09:07 -05:00
post = Fabricate ( :post , user : post_author1 , raw : " ![image_description|690x405](upload://sdtr5O5xaxf0iEOxICxL36YRj86.png) " )
2018-10-17 04:19:32 -04:00
get post . topic . url
body = response . body
expect ( body ) . to have_tag ( :meta , with : { name : 'description' , content : '[image_description]' } )
end
2021-07-26 12:09:51 -04:00
it " uses image cdn url for schema markup " do
set_cdn_url ( " http://cdn.localhost " )
2021-12-14 13:09:07 -05:00
post = Fabricate ( :post_with_uploaded_image , user : post_author1 )
2021-07-26 12:09:51 -04:00
cpp = CookedPostProcessor . new ( post ) . update_post_image
get post . topic . url
body = response . body
expect ( body ) . to have_tag ( :link , with : { itemprop : 'image' , href : post . image_url } )
end
2018-10-17 04:19:32 -04:00
end
2018-05-31 10:45:32 -04:00
end
2018-06-28 02:54:54 -04:00
describe '#post_ids' do
2021-12-14 13:09:07 -05:00
fab! ( :post ) { Fabricate ( :post , user : post_author1 ) }
2021-03-17 11:25:43 -04:00
fab! ( :topic ) { post . topic }
2018-06-28 02:54:54 -04:00
before do
TopicView . stubs ( :chunk_size ) . returns ( 1 )
end
it 'returns the right post ids' do
2021-12-14 13:09:07 -05:00
post2 = Fabricate ( :post , user : post_author2 , topic : topic )
post3 = Fabricate ( :post , user : post_author3 , topic : topic )
2018-06-28 02:54:54 -04:00
get " /t/ #{ topic . id } /post_ids.json " , params : {
post_number : post . post_number
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2018-06-28 02:54:54 -04:00
expect ( body [ " post_ids " ] ) . to eq ( [ post2 . id , post3 . id ] )
end
describe 'filtering by post number with filters' do
describe 'username filters' do
2021-03-17 11:25:43 -04:00
fab! ( :post ) { Fabricate ( :post , user : user ) }
fab! ( :post2 ) { Fabricate ( :post , topic : topic , user : user ) }
2021-12-14 13:09:07 -05:00
fab! ( :post3 ) { Fabricate ( :post , user : post_author3 , topic : topic ) }
2018-06-28 02:54:54 -04:00
it 'should return the right posts' do
get " /t/ #{ topic . id } /post_ids.json " , params : {
post_number : post . post_number ,
username_filters : post2 . user . username
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2018-06-28 02:54:54 -04:00
expect ( body [ " post_ids " ] ) . to eq ( [ post2 . id ] )
end
end
describe 'summary filter' do
2021-12-14 13:09:07 -05:00
fab! ( :post2 ) { Fabricate ( :post , user : post_author2 , topic : topic , percent_rank : 0 . 2 ) }
fab! ( :post3 ) { Fabricate ( :post , user : post_author3 , topic : topic ) }
2018-06-28 02:54:54 -04:00
it 'should return the right posts' do
get " /t/ #{ topic . id } /post_ids.json " , params : {
post_number : post . post_number ,
filter : 'summary'
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2018-06-28 02:54:54 -04:00
expect ( body [ " post_ids " ] ) . to eq ( [ post2 . id ] )
end
end
2021-05-09 18:57:58 -04:00
describe 'custom filters' do
2021-12-14 13:09:07 -05:00
fab! ( :post2 ) { Fabricate ( :post , user : post_author2 , topic : topic , percent_rank : 0 . 2 ) }
fab! ( :post3 ) { Fabricate ( :post , user : post_author3 , topic : topic , percent_rank : 0 . 5 ) }
2021-05-09 18:57:58 -04:00
it 'should return the right posts' do
TopicView . add_custom_filter ( " percent " ) do | posts , topic_view |
posts . where ( percent_rank : 0 . 5 )
end
get " /t/ #{ topic . id } .json " , params : {
post_number : post . post_number ,
filter : 'percent'
}
expect ( response . status ) . to eq ( 200 )
body = response . parsed_body
expect ( body [ " post_stream " ] [ " posts " ] . map { | p | p [ " id " ] } ) . to eq ( [ post3 . id ] )
ensure
2021-05-10 21:24:14 -04:00
TopicView . instance_variable_set ( :@custom_filters , { } )
2021-05-09 18:57:58 -04:00
end
end
2018-06-28 02:54:54 -04:00
end
end
2018-05-31 10:45:32 -04:00
describe '#posts' do
2021-12-14 13:09:07 -05:00
fab! ( :post ) { Fabricate ( :post , user : post_author1 ) }
2021-03-17 11:25:43 -04:00
fab! ( :topic ) { post . topic }
2018-05-31 10:45:32 -04:00
2020-03-10 17:13:17 -04:00
after do
2020-05-23 00:56:13 -04:00
Discourse . redis . flushdb
2020-03-10 17:13:17 -04:00
end
2018-07-11 03:41:26 -04:00
it 'returns first post of the topic' do
2019-02-21 18:37:18 -05:00
# we need one for suggested
create_post
2018-05-31 10:45:32 -04:00
get " /t/ #{ topic . id } /posts.json "
2018-07-11 03:41:26 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-07-11 03:41:26 -04:00
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2018-07-11 03:41:26 -04:00
expect ( body [ " post_stream " ] [ " posts " ] . first [ " id " ] ) . to eq ( post . id )
2019-02-21 18:37:18 -05:00
expect ( body [ " suggested_topics " ] ) . to eq ( nil )
get " /t/ #{ topic . id } /posts.json?include_suggested=true "
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2019-02-21 18:37:18 -05:00
expect ( body [ " suggested_topics " ] ) . not_to eq ( nil )
2018-07-11 03:41:26 -04:00
end
describe 'filtering by post number with filters' do
describe 'username filters' do
2021-12-14 13:09:07 -05:00
fab! ( :post2 ) { Fabricate ( :post , user : post_author2 , topic : topic ) }
fab! ( :post3 ) { Fabricate ( :post , user : post_author3 , topic : topic ) }
2018-07-11 03:41:26 -04:00
it 'should return the right posts' do
TopicView . stubs ( :chunk_size ) . returns ( 2 )
get " /t/ #{ topic . id } /posts.json " , params : {
post_number : post . post_number ,
username_filters : post2 . user . username ,
asc : true
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2018-07-11 03:41:26 -04:00
expect ( body [ " post_stream " ] [ " posts " ] . first [ " id " ] ) . to eq ( post2 . id )
end
end
describe 'summary filter' do
2021-12-14 13:09:07 -05:00
fab! ( :post2 ) { Fabricate ( :post , user : post_author2 , topic : topic , percent_rank : 0 . 2 ) }
fab! ( :post3 ) { Fabricate ( :post , user : post_author3 , topic : topic ) }
2018-07-11 03:41:26 -04:00
it 'should return the right posts' do
TopicView . stubs ( :chunk_size ) . returns ( 2 )
get " /t/ #{ topic . id } /posts.json " , params : {
post_number : post . post_number ,
filter : 'summary' ,
asc : true
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2018-07-11 03:41:26 -04:00
expect ( body [ " post_stream " ] [ " posts " ] . first [ " id " ] ) . to eq ( post2 . id )
end
end
2018-05-31 10:45:32 -04:00
end
end
describe '#feed' do
2021-12-14 13:09:07 -05:00
fab! ( :topic ) { Fabricate ( :post , user : post_author1 ) . topic }
2018-05-31 10:45:32 -04:00
it 'renders rss of the topic' do
get " /t/foo/ #{ topic . id } .rss "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2019-09-11 20:41:50 -04:00
expect ( response . media_type ) . to eq ( 'application/rss+xml' )
2022-03-09 02:25:20 -05:00
# our RSS feed is full of post 1/2/3/4/5 links, we do not want it included
# in the index, and do not want links followed
# this allows us to remove it while allowing via robots.txt
expect ( response . headers [ 'X-Robots-Tag' ] ) . to eq ( 'noindex, nofollow' )
2018-05-31 10:45:32 -04:00
end
2018-08-27 18:05:08 -04:00
it 'renders rss of the topic correctly with subfolder' do
2019-11-15 00:48:24 -05:00
set_subfolder " /forum "
2018-08-27 18:05:08 -04:00
get " /t/foo/ #{ topic . id } .rss "
expect ( response . status ) . to eq ( 200 )
expect ( response . body ) . to_not include ( " /forum/forum " )
expect ( response . body ) . to include ( " http://test.localhost/forum/t/ #{ topic . slug } " )
end
2021-01-07 19:16:15 -05:00
it 'returns 404 when posts are deleted' do
topic . posts . each ( & :trash! )
get " /t/foo/ #{ topic . id } .rss "
expect ( response . status ) . to eq ( 404 )
end
2021-02-09 00:47:06 -05:00
it 'returns 404 when the topic is deleted' do
topic . trash!
get " /t/foo/ #{ topic . id } .rss "
expect ( response . status ) . to eq ( 404 )
end
2018-05-31 10:45:32 -04:00
end
describe '#invite_group' do
2021-03-17 11:25:43 -04:00
let! ( :admins ) { Group [ :admins ] }
2018-05-31 10:45:32 -04:00
before do
2019-05-06 06:00:22 -04:00
sign_in ( admin )
2018-05-31 10:45:32 -04:00
admins . messageable_level = Group :: ALIAS_LEVELS [ :everyone ]
admins . save!
end
it " disallows inviting a group to a topic " do
post " /t/ #{ topic . id } /invite-group.json " , params : {
group : 'admins'
}
expect ( response . status ) . to eq ( 422 )
end
it " allows inviting a group to a PM " do
2021-12-21 13:28:12 -05:00
post " /t/ #{ pm . id } /invite-group.json " , params : {
2018-05-31 10:45:32 -04:00
group : 'admins'
}
expect ( response . status ) . to eq ( 200 )
2021-12-21 13:28:12 -05:00
expect ( pm . allowed_groups . first . id ) . to eq ( admins . id )
2018-05-31 10:45:32 -04:00
end
end
describe '#make_banner' do
it 'needs you to be a staff member' do
2021-12-21 13:28:12 -05:00
tl4_topic = Fabricate ( :topic , user : sign_in ( trust_level_4 ) )
put " /t/ #{ tl4_topic . id } /make-banner.json "
2018-05-31 10:45:32 -04:00
expect ( response ) . to be_forbidden
end
describe 'when logged in' do
it " changes the topic archetype to 'banner' " do
2021-12-21 13:28:12 -05:00
admin_topic = Fabricate ( :topic , user : sign_in ( admin ) )
2018-05-31 10:45:32 -04:00
2021-12-21 13:28:12 -05:00
put " /t/ #{ admin_topic . id } /make-banner.json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-21 13:28:12 -05:00
admin_topic . reload
expect ( admin_topic . archetype ) . to eq ( Archetype . banner )
2018-05-31 10:45:32 -04:00
end
end
end
describe '#remove_banner' do
it 'needs you to be a staff member' do
2021-12-21 13:28:12 -05:00
tl4_topic = Fabricate ( :topic , user : sign_in ( trust_level_4 ) , archetype : Archetype . banner )
put " /t/ #{ tl4_topic . id } /remove-banner.json "
2018-05-31 10:45:32 -04:00
expect ( response ) . to be_forbidden
end
describe 'when logged in' do
it " resets the topic archetype " do
2021-12-21 13:28:12 -05:00
admin_topic = Fabricate ( :topic , user : sign_in ( admin ) , archetype : Archetype . banner )
2018-05-31 10:45:32 -04:00
2021-12-21 13:28:12 -05:00
put " /t/ #{ admin_topic . id } /remove-banner.json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-21 13:28:12 -05:00
admin_topic . reload
expect ( admin_topic . archetype ) . to eq ( Archetype . default )
2018-05-31 10:45:32 -04:00
end
end
end
describe '#remove_allowed_user' do
it 'admin can be removed from a pm' do
2019-05-06 06:00:22 -04:00
sign_in ( admin )
2018-05-31 10:45:32 -04:00
pm = create_post ( user : user , archetype : 'private_message' , target_usernames : [ user . username , admin . username ] )
put " /t/ #{ pm . topic_id } /remove-allowed-user.json " , params : {
username : admin . username
}
expect ( response . status ) . to eq ( 200 )
expect ( TopicAllowedUser . where ( topic_id : pm . topic_id , user_id : admin . id ) . first ) . to eq ( nil )
end
end
describe '#bulk' do
it 'needs you to be logged in' do
put " /topics/bulk.json "
expect ( response . status ) . to eq ( 403 )
end
describe " when logged in " do
2019-05-06 05:44:15 -04:00
before { sign_in ( user ) }
2021-03-17 11:25:43 -04:00
let! ( :operation ) { { type : 'change_category' , category_id : '1' } }
let! ( :topic_ids ) { [ 1 , 2 , 3 ] }
2018-05-31 10:45:32 -04:00
it " requires a list of topic_ids or filter " do
put " /topics/bulk.json " , params : { operation : operation }
expect ( response . status ) . to eq ( 400 )
end
it " requires an operation param " do
put " /topics/bulk.json " , params : { topic_ids : topic_ids }
expect ( response . status ) . to eq ( 400 )
end
it " requires a type field for the operation param " do
put " /topics/bulk.json " , params : { topic_ids : topic_ids , operation : { } }
expect ( response . status ) . to eq ( 400 )
end
2019-06-26 23:26:07 -04:00
it " can mark sub-categories unread " do
2019-08-06 06:26:54 -04:00
sub = Fabricate ( :category , parent_category_id : category . id )
2019-06-26 23:26:07 -04:00
topic . update! ( category_id : sub . id )
post1 = create_post ( user : user , topic_id : topic . id )
create_post ( topic_id : topic . id )
put " /topics/bulk.json " , params : {
category_id : category . id ,
include_subcategories : true ,
filter : 'unread' ,
operation : { type : 'dismiss_posts' }
}
expect ( response . status ) . to eq ( 200 )
expect ( TopicUser . get ( post1 . topic , post1 . user ) . last_read_post_number ) . to eq ( 2 )
end
2020-08-27 13:34:45 -04:00
it " can mark tag topics unread " do
TopicTag . create! (
topic_id : topic . id ,
tag_id : tag . id
)
post1 = create_post ( user : user , topic_id : topic . id )
create_post ( topic_id : topic . id )
put " /topics/bulk.json " , params : {
tag_name : tag . name ,
filter : 'unread' ,
operation : { type : 'dismiss_posts' }
}
expect ( response . status ) . to eq ( 200 )
expect ( TopicUser . get ( post1 . topic , post1 . user ) . last_read_post_number ) . to eq ( 2 )
end
2021-07-30 05:00:48 -04:00
context " private message " do
fab! ( :group ) do
Fabricate ( :group , messageable_level : Group :: ALIAS_LEVELS [ :everyone ] ) . tap do | g |
g . add ( user_2 )
end
end
fab! ( :group_message ) do
create_post (
user : user ,
target_group_names : [ group . name ] ,
archetype : Archetype . private_message
) . topic
end
fab! ( :private_message ) do
create_post (
user : user ,
target_usernames : [ user_2 . username ] ,
archetype : Archetype . private_message
) . topic
end
2021-08-05 02:44:58 -04:00
fab! ( :private_message_2 ) do
create_post (
user : user ,
target_usernames : [ user_2 . username ] ,
archetype : Archetype . private_message
) . topic
end
2021-07-30 05:00:48 -04:00
fab! ( :group_pm_topic_user ) do
TopicUser . find_by ( user : user_2 , topic : group_message ) . tap do | tu |
tu . update! ( last_read_post_number : 1 )
end
end
fab! ( :regular_pm_topic_user ) do
TopicUser . find_by ( user : user_2 , topic : private_message ) . tap do | tu |
tu . update! ( last_read_post_number : 1 )
end
end
2021-08-05 02:44:58 -04:00
fab! ( :regular_pm_topic_user_2 ) do
TopicUser . find_by ( user : user_2 , topic : private_message_2 ) . tap do | tu |
tu . update! ( last_read_post_number : 1 )
end
end
2021-12-13 14:44:55 -05:00
before_all do
2021-07-30 05:00:48 -04:00
create_post ( user : user , topic : group_message )
create_post ( user : user , topic : private_message )
2021-08-05 02:44:58 -04:00
create_post ( user : user , topic : private_message_2 )
2021-12-13 14:44:55 -05:00
end
before do
2021-07-30 05:00:48 -04:00
sign_in ( user_2 )
end
it " can dismiss all user and group private message topics " do
expect do
put " /topics/bulk.json " , params : {
filter : " unread " ,
operation : { type : 'dismiss_posts' } ,
private_message_inbox : " all "
}
expect ( response . status ) . to eq ( 200 )
end . to change { group_pm_topic_user . reload . last_read_post_number } . from ( 1 ) . to ( 2 )
. and change { regular_pm_topic_user . reload . last_read_post_number } . from ( 1 ) . to ( 2 )
end
it " can dismiss all user unread private message topics " do
2021-08-05 02:44:58 -04:00
stub_const ( TopicQuery , " DEFAULT_PER_PAGE_COUNT " , 1 ) do
expect do
put " /topics/bulk.json " , params : {
filter : " unread " ,
operation : { type : 'dismiss_posts' } ,
private_message_inbox : " user "
}
2021-07-30 05:00:48 -04:00
2021-08-05 02:44:58 -04:00
expect ( response . status ) . to eq ( 200 )
end . to change { regular_pm_topic_user . reload . last_read_post_number } . from ( 1 ) . to ( 2 )
. and change { regular_pm_topic_user_2 . reload . last_read_post_number } . from ( 1 ) . to ( 2 )
2021-07-30 05:00:48 -04:00
2021-08-05 02:44:58 -04:00
expect ( group_pm_topic_user . reload . last_read_post_number ) . to eq ( 1 )
end
2021-07-30 05:00:48 -04:00
end
it " returns the right response when trying to dismiss private messages of an invalid group " do
put " /topics/bulk.json " , params : {
filter : " unread " ,
operation : { type : 'dismiss_posts' } ,
private_message_inbox : " group " ,
group_name : 'randomgroup'
}
expect ( response . status ) . to eq ( 404 )
end
it " returns the right response when trying to dismiss private messages of a restricted group " do
sign_in ( user )
put " /topics/bulk.json " , params : {
filter : " unread " ,
operation : { type : 'dismiss_posts' } ,
private_message_inbox : " group " ,
group_name : group . name
}
expect ( response . status ) . to eq ( 404 )
end
it " can dismiss all group unread private message topics " do
expect do
put " /topics/bulk.json " , params : {
filter : " unread " ,
operation : { type : 'dismiss_posts' } ,
private_message_inbox : " group " ,
group_name : group . name
}
expect ( response . status ) . to eq ( 200 )
end . to change { group_pm_topic_user . reload . last_read_post_number } . from ( 1 ) . to ( 2 )
expect ( regular_pm_topic_user . reload . last_read_post_number ) . to eq ( 1 )
end
end
2018-05-31 10:45:32 -04:00
it " can find unread " do
# mark all unread muted
put " /topics/bulk.json " , params : {
filter : 'unread' , operation : { type : :change_notification_level , notification_level_id : 0 }
}
expect ( response . status ) . to eq ( 200 )
end
it " delegates work to `TopicsBulkAction` " do
topics_bulk_action = mock
TopicsBulkAction . expects ( :new ) . with ( user , topic_ids , operation , group : nil ) . returns ( topics_bulk_action )
topics_bulk_action . expects ( :perform! )
put " /topics/bulk.json " , params : {
topic_ids : topic_ids , operation : operation
}
end
2020-09-25 15:39:37 -04:00
2021-05-25 19:38:46 -04:00
it " raises an error if topic_ids is provided and it is not an array " do
put " /topics/bulk.json " , params : {
topic_ids : " 1 " , operation : operation
}
expect ( response . parsed_body [ " errors " ] . first ) . to match ( / Expecting topic_ids to contain a list / )
put " /topics/bulk.json " , params : {
topic_ids : [ 1 ] , operation : operation
}
expect ( response . parsed_body [ " errors " ] ) . to eq ( nil )
end
2020-09-25 15:39:37 -04:00
it " respects the tracked parameter " do
# untracked topic
CategoryUser . set_notification_level_for_category ( user ,
NotificationLevels . all [ :regular ] ,
category . id )
create_post ( user : user , topic_id : topic . id )
topic . update! ( category_id : category . id )
create_post ( topic_id : topic . id )
# tracked topic
CategoryUser . set_notification_level_for_category ( user ,
NotificationLevels . all [ :tracking ] ,
tracked_category . id )
tracked_topic = create_post ( user : user ) . topic
tracked_topic . update! ( category_id : tracked_category . id )
create_post ( topic_id : tracked_topic . id )
put " /topics/bulk.json " , params : {
filter : 'unread' ,
operation : { type : 'dismiss_posts' } ,
tracked : true
}
expect ( response . status ) . to eq ( 200 )
expect ( TopicUser . get ( topic , user ) . last_read_post_number ) . to eq ( topic . posts . count - 1 )
expect ( TopicUser . get ( tracked_topic , user ) . last_read_post_number ) . to eq ( tracked_topic . posts . count )
end
2018-05-31 10:45:32 -04:00
end
end
describe '#remove_bookmarks' do
it " should remove bookmarks properly from non first post " do
2019-05-06 05:44:15 -04:00
sign_in ( user )
2018-05-31 10:45:32 -04:00
post = create_post
post2 = create_post ( topic_id : post . topic_id )
2022-05-22 20:07:15 -04:00
Fabricate ( :bookmark , user : user , bookmarkable : post )
Fabricate ( :bookmark , user : user , bookmarkable : post2 )
2018-05-31 10:45:32 -04:00
put " /t/ #{ post . topic_id } /remove_bookmarks.json "
2020-04-21 23:44:19 -04:00
expect ( Bookmark . where ( user : user ) . count ) . to eq ( 0 )
2018-05-31 10:45:32 -04:00
end
it " should disallow bookmarks on posts you have no access to " do
sign_in ( Fabricate ( :user ) )
pm = create_post ( user : user , archetype : 'private_message' , target_usernames : [ user . username ] )
put " /t/ #{ pm . topic_id } /bookmark.json "
expect ( response ) . to be_forbidden
end
2020-02-13 01:26:02 -05:00
2020-04-21 23:44:19 -04:00
context " bookmarks with reminders " do
2020-02-13 01:26:02 -05:00
it " deletes all the bookmarks for the user in the topic " do
sign_in ( user )
post = create_post
2022-05-22 20:07:15 -04:00
Fabricate ( :bookmark , bookmarkable : post , user : user )
2020-02-13 01:26:02 -05:00
put " /t/ #{ post . topic_id } /remove_bookmarks.json "
2021-09-14 20:16:54 -04:00
expect ( Bookmark . for_user_in_topic ( user . id , post . topic_id ) . count ) . to eq ( 0 )
2020-02-13 01:26:02 -05:00
end
end
end
describe " # bookmark " do
before do
sign_in ( user )
end
2022-05-22 20:07:15 -04:00
it " should create a new bookmark for the topic " do
2020-02-13 01:26:02 -05:00
post = create_post
post2 = create_post ( topic_id : post . topic_id )
put " /t/ #{ post . topic_id } /bookmark.json "
2022-05-22 20:07:15 -04:00
expect ( Bookmark . find_by ( user_id : user . id ) . bookmarkable_id ) . to eq ( post . topic_id )
2020-02-13 01:26:02 -05:00
end
it " errors if the topic is already bookmarked for the user " do
post = create_post
2022-05-22 20:07:15 -04:00
Bookmark . create ( bookmarkable : post . topic , user : user )
2020-02-13 01:26:02 -05:00
put " /t/ #{ post . topic_id } /bookmark.json "
2020-04-21 23:44:19 -04:00
expect ( response . status ) . to eq ( 400 )
2020-02-13 01:26:02 -05:00
end
2018-05-31 10:45:32 -04:00
end
describe '#reset_new' do
2021-12-23 13:29:51 -05:00
context " when a user is not signed in " do
it 'fails' do
put " /topics/reset-new.json "
expect ( response . status ) . to eq ( 403 )
end
2018-05-31 10:45:32 -04:00
end
2021-12-23 13:29:51 -05:00
context " when a user is signed in " do
before_all do
@old_date = 2 . years . ago
user . user_stat . update_column ( :new_since , @old_date )
2018-05-31 10:45:32 -04:00
2021-12-23 13:29:51 -05:00
CategoryUser . set_notification_level_for_category (
user ,
NotificationLevels . all [ :tracking ] ,
tracked_category . id ,
)
end
2019-11-24 14:17:31 -05:00
2021-12-23 13:29:51 -05:00
let! ( :old_date ) { @old_date }
2019-11-13 19:16:13 -05:00
2021-12-23 13:29:51 -05:00
before do
2020-09-25 15:39:37 -04:00
sign_in ( user )
end
2021-12-23 13:29:51 -05:00
context " when tracked is unset " do
it " updates the `new_since` date " do
TopicTrackingState . expects ( :publish_dismiss_new )
2020-09-25 15:39:37 -04:00
2021-12-23 13:29:51 -05:00
put " /topics/reset-new.json "
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_stat . new_since . to_date ) . not_to eq ( old_date . to_date )
end
end
2020-09-25 15:39:37 -04:00
2021-12-23 13:29:51 -05:00
describe " when tracked param is true " do
it " does not update user_stat.new_since " do
2021-06-16 18:20:09 -04:00
put " /topics/reset-new.json?tracked=true "
2021-12-23 13:29:51 -05:00
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_stat . new_since . to_date ) . to eq ( old_date . to_date )
end
2021-06-16 18:20:09 -04:00
2021-12-23 13:29:51 -05:00
it " creates dismissed topic user records for each new topic " do
tracked_topic = create_post ( category : tracked_category ) . topic
2021-06-16 18:20:09 -04:00
2021-12-23 13:29:51 -05:00
create_post # This is a new post, but is not tracked so a record will not be created for it
expect do
put " /topics/reset-new.json?tracked=true "
end . to change {
DismissedTopicUser . where ( user_id : user . id , topic_id : tracked_topic . id ) . count
} . by ( 1 )
2021-06-16 18:20:09 -04:00
end
2022-01-03 12:00:03 -05:00
end
2021-06-16 18:20:09 -04:00
2022-01-03 12:00:03 -05:00
context " when 5 tracked topics exist " do
before_all do
@tracked_topic_ids = 5 . times . map { create_post ( category : tracked_category ) . topic . id }
@tracked_topic_ids . freeze
2021-06-16 18:20:09 -04:00
end
2022-01-03 12:00:03 -05:00
describe " when tracked param is true " do
it " creates dismissed topic user records if there are > 30 (default pagination) topics " do
expect do
stub_const ( TopicQuery , " DEFAULT_PER_PAGE_COUNT " , 2 ) do
put " /topics/reset-new.json?tracked=true "
end
end . to change {
DismissedTopicUser . where ( user_id : user . id , topic_id : @tracked_topic_ids ) . count
} . by ( 5 )
2021-06-16 18:20:09 -04:00
end
2021-12-23 13:29:51 -05:00
2022-01-03 12:00:03 -05:00
it " creates dismissed topic user records if there are > 30 (default pagination) topics and topic_ids are provided " do
dismissing_topic_ids = @tracked_topic_ids . sample ( 4 )
2021-08-25 21:25:20 -04:00
2022-01-03 12:00:03 -05:00
expect do
stub_const ( TopicQuery , " DEFAULT_PER_PAGE_COUNT " , 2 ) do
put " /topics/reset-new.json?tracked=true " , params : { topic_ids : dismissing_topic_ids }
end
end . to change {
DismissedTopicUser . where ( user_id : user . id , topic_id : @tracked_topic_ids ) . count
} . by ( 4 )
2021-08-25 21:25:20 -04:00
end
end
2022-01-03 12:00:03 -05:00
context " when two extra topics exist " do
before_all do
@topic_ids = @tracked_topic_ids + [ Fabricate ( :topic ) . id , Fabricate ( :topic ) . id ]
@topic_ids . freeze
2021-08-25 21:25:20 -04:00
end
2022-01-03 12:00:03 -05:00
context " when tracked=false " do
it " updates the user_stat new_since column and dismisses all the new topics " do
old_new_since = user . user_stat . new_since
2021-08-25 21:25:20 -04:00
2022-01-03 12:00:03 -05:00
put " /topics/reset-new.json?tracked=false "
expect ( DismissedTopicUser . where ( user_id : user . id , topic_id : @topic_ids ) . count ) . to eq ( 7 )
expect ( user . reload . user_stat . new_since > old_new_since ) . to eq ( true )
end
it " does not pass topic ids that are not new for the user to the bulk action, limit the scope to new topics " do
dismiss_ids = @topic_ids [ 0 .. 1 ]
other_ids = @topic_ids [ 2 .. - 1 ] . sort . reverse
DismissedTopicUser . create ( user_id : user . id , topic_id : dismiss_ids . first )
DismissedTopicUser . create ( user_id : user . id , topic_id : dismiss_ids . second )
2021-08-25 21:25:20 -04:00
2022-01-03 12:00:03 -05:00
expect { put " /topics/reset-new.json?tracked=false " } . to change {
DismissedTopicUser . where ( user_id : user . id ) . count
} . by ( 5 )
end
end
2021-08-25 21:25:20 -04:00
end
end
2019-11-24 14:17:31 -05:00
2021-12-23 13:29:51 -05:00
context 'category' do
fab! ( :subcategory ) { Fabricate ( :category , parent_category_id : category . id ) }
fab! ( :category_topic ) { Fabricate ( :topic , category : category ) }
fab! ( :subcategory_topic ) { Fabricate ( :topic , category : subcategory ) }
2019-11-13 19:16:13 -05:00
2021-12-23 13:29:51 -05:00
it 'dismisses topics for main category' do
TopicTrackingState . expects ( :publish_dismiss_new ) . with ( user . id , topic_ids : [ category_topic . id ] )
2019-11-13 19:16:13 -05:00
2021-12-23 13:29:51 -05:00
put " /topics/reset-new.json?category_id= #{ category . id } "
2021-02-14 16:50:33 -05:00
2021-12-23 13:29:51 -05:00
expect ( DismissedTopicUser . where ( user_id : user . id ) . pluck ( :topic_id ) ) . to eq ( [ category_topic . id ] )
end
2021-02-14 16:50:33 -05:00
2021-12-23 13:29:51 -05:00
it 'dismisses topics for main category and subcategories' do
TopicTrackingState . expects ( :publish_dismiss_new ) . with ( user . id , topic_ids : [ category_topic . id , subcategory_topic . id ] )
2019-11-13 19:16:13 -05:00
2021-12-23 13:29:51 -05:00
put " /topics/reset-new.json?category_id= #{ category . id } &include_subcategories=true "
2021-02-08 18:39:30 -05:00
2021-12-23 13:29:51 -05:00
expect ( DismissedTopicUser . where ( user_id : user . id ) . pluck ( :topic_id ) . sort ) . to eq ( [ category_topic . id , subcategory_topic . id ] . sort )
end
2021-02-08 18:39:30 -05:00
end
2021-12-23 13:29:51 -05:00
context 'tag' do
fab! ( :tag_topic ) { Fabricate ( :topic ) }
fab! ( :topic_tag ) { Fabricate ( :topic_tag , topic : tag_topic , tag : tag ) }
2021-02-08 18:39:30 -05:00
2021-12-23 13:29:51 -05:00
it 'dismisses topics for tag' do
TopicTrackingState . expects ( :publish_dismiss_new ) . with ( user . id , topic_ids : [ tag_topic . id ] )
put " /topics/reset-new.json?tag_id= #{ tag . name } "
expect ( DismissedTopicUser . where ( user_id : user . id ) . pluck ( :topic_id ) ) . to eq ( [ tag_topic . id ] )
end
2021-02-08 18:39:30 -05:00
end
2021-05-25 19:38:46 -04:00
2021-12-23 13:29:51 -05:00
context 'tag and category' do
fab! ( :tag_topic ) { Fabricate ( :topic ) }
fab! ( :topic_tag ) { Fabricate ( :topic_tag , topic : tag_topic , tag : tag ) }
fab! ( :tag_and_category_topic ) { Fabricate ( :topic , category : category ) }
fab! ( :topic_tag2 ) { Fabricate ( :topic_tag , topic : tag_and_category_topic , tag : tag ) }
2021-05-25 19:38:46 -04:00
2021-12-23 13:29:51 -05:00
it 'dismisses topics for tag' do
TopicTrackingState . expects ( :publish_dismiss_new ) . with ( user . id , topic_ids : [ tag_and_category_topic . id ] )
put " /topics/reset-new.json?tag_id= #{ tag . name } &category_id= #{ category . id } "
expect ( DismissedTopicUser . where ( user_id : user . id ) . pluck ( :topic_id ) ) . to eq ( [ tag_and_category_topic . id ] )
end
2021-05-25 19:38:46 -04:00
end
2021-12-23 13:29:51 -05:00
context " specific topics " do
fab! ( :topic2 ) { Fabricate ( :topic ) }
fab! ( :topic3 ) { Fabricate ( :topic ) }
2021-05-25 19:38:46 -04:00
2021-12-23 13:29:51 -05:00
it " updates the `new_since` date " do
TopicTrackingState . expects ( :publish_dismiss_new ) . with ( user . id , topic_ids : [ topic2 . id , topic3 . id ] ) . at_least_once
2021-05-25 19:38:46 -04:00
2021-12-23 13:29:51 -05:00
put " /topics/reset-new.json " , ** { params : { topic_ids : [ topic2 . id , topic3 . id ] } }
2021-05-25 19:38:46 -04:00
expect ( response . status ) . to eq ( 200 )
user . reload
2021-12-23 13:29:51 -05:00
expect ( user . user_stat . new_since . to_date ) . not_to eq ( old_date . to_date )
expect ( DismissedTopicUser . where ( user_id : user . id ) . pluck ( :topic_id ) ) . to match_array ( [ topic2 . id , topic3 . id ] )
2021-05-25 19:38:46 -04:00
end
2021-12-23 13:29:51 -05:00
it " raises an error if topic_ids is provided and it is not an array " do
put " /topics/reset-new.json " , params : { topic_ids : topic2 . id }
expect ( response . parsed_body [ " errors " ] . first ) . to match ( / Expecting topic_ids to contain a list / )
put " /topics/reset-new.json " , params : { topic_ids : [ topic2 . id ] }
expect ( response . parsed_body [ " errors " ] ) . to eq ( nil )
end
2021-05-25 19:38:46 -04:00
2021-12-23 13:29:51 -05:00
describe " when tracked param is true " do
it " does not update user_stat.new_since and does not dismiss untracked topics " do
put " /topics/reset-new.json?tracked=true " , ** { params : { topic_ids : [ topic2 . id , topic3 . id ] } }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_stat . new_since . to_date ) . to eq ( old_date . to_date )
expect ( DismissedTopicUser . where ( user_id : user . id ) . pluck ( :topic_id ) ) . to be_empty
end
2021-05-25 19:38:46 -04:00
2021-12-23 13:29:51 -05:00
it " creates topic user records for each unread topic " do
tracked_topic = create_post . topic
tracked_topic . update! ( category_id : tracked_category . id )
topic2 . update! ( category_id : tracked_category . id )
create_post # This is a new post, but is not tracked so a record will not be created for it
expect do
put " /topics/reset-new.json?tracked=true " , ** { params : { topic_ids : [ tracked_topic . id , topic2 . id , topic3 . id ] } }
end . to change { DismissedTopicUser . where ( user_id : user . id ) . count } . by ( 2 )
expect ( DismissedTopicUser . where ( user_id : user . id ) . pluck ( :topic_id ) ) . to match_array ( [ tracked_topic . id , topic2 . id ] )
end
2021-05-25 19:38:46 -04:00
end
end
end
2018-05-31 10:45:32 -04:00
end
describe '#feature_stats' do
it " works " do
get " /topics/feature_stats.json " , params : { category_id : 1 }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( json [ " pinned_in_category_count " ] ) . to eq ( 0 )
expect ( json [ " pinned_globally_count " ] ) . to eq ( 0 )
expect ( json [ " banner_count " ] ) . to eq ( 0 )
end
it " allows unlisted banner topic " do
Fabricate ( :topic , category_id : 1 , archetype : Archetype . banner , visible : false )
get " /topics/feature_stats.json " , params : { category_id : 1 }
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( json [ " banner_count " ] ) . to eq ( 1 )
end
end
describe '#excerpts' do
it " can correctly get excerpts " do
first_post = create_post ( raw : 'This is the first post :)' , title : 'This is a test title I am making yay' )
second_post = create_post ( raw : 'This is second post' , topic : first_post . topic )
2021-10-11 21:20:35 -04:00
third_post = first_post . topic . add_small_action ( first_post . user , " autobumped " )
2018-05-31 10:45:32 -04:00
2021-12-14 13:09:07 -05:00
random_post = Fabricate ( :post , user : post_author1 )
2018-05-31 10:45:32 -04:00
get " /t/ #{ first_post . topic_id } /excerpts.json " , params : {
2021-10-11 21:20:35 -04:00
post_ids : [ first_post . id , second_post . id , third_post . id , random_post . id ]
2018-05-31 10:45:32 -04:00
}
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-31 10:45:32 -04:00
json . sort! { | a , b | a [ " post_id " ] < = > b [ " post_id " ] }
# no random post
2021-10-11 21:20:35 -04:00
expect ( json . map { | p | p [ " post_id " ] } ) . to contain_exactly ( first_post . id , second_post . id , third_post . id )
2018-05-31 10:45:32 -04:00
# keep emoji images
expect ( json [ 0 ] [ " excerpt " ] ) . to match ( / emoji / )
expect ( json [ 0 ] [ " excerpt " ] ) . to match ( / first post / )
expect ( json [ 0 ] [ " username " ] ) . to eq ( first_post . user . username )
2021-10-11 21:20:35 -04:00
expect ( json [ 0 ] [ " created_at " ] . present? ) . to eq ( false )
2018-05-31 10:45:32 -04:00
expect ( json [ 1 ] [ " excerpt " ] ) . to match ( / second post / )
2021-10-11 21:20:35 -04:00
expect ( json [ 2 ] [ " action_code " ] ) . to eq ( " autobumped " )
expect ( json [ 2 ] [ " created_at " ] . present? ) . to eq ( true )
2018-05-31 10:45:32 -04:00
end
end
describe '#convert_topic' do
it 'needs you to be logged in' do
put " /t/111/convert-topic/private.json "
expect ( response . status ) . to eq ( 403 )
end
describe 'converting public topic to private message' do
2021-03-17 11:25:43 -04:00
fab! ( :topic ) { Fabricate ( :topic , user : user ) }
2022-02-10 20:00:58 -05:00
fab! ( :post ) { Fabricate ( :post , user : user , topic : topic ) }
2018-05-31 10:45:32 -04:00
it " raises an error when the user doesn't have permission to convert topic " do
2019-05-06 05:44:15 -04:00
sign_in ( user )
2018-05-31 10:45:32 -04:00
put " /t/ #{ topic . id } /convert-topic/private.json "
expect ( response ) . to be_forbidden
end
context " success " do
it " returns success " do
2019-05-06 06:00:22 -04:00
sign_in ( admin )
2018-05-31 10:45:32 -04:00
put " /t/ #{ topic . id } /convert-topic/private.json "
topic . reload
expect ( topic . archetype ) . to eq ( Archetype . private_message )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to be_present
end
end
end
describe 'converting private message to public topic' do
2021-03-17 11:25:43 -04:00
fab! ( :topic ) { Fabricate ( :private_message_topic , user : user ) }
2021-12-14 13:09:07 -05:00
fab! ( :post ) { Fabricate ( :post , user : post_author1 , topic : topic ) }
2018-05-31 10:45:32 -04:00
it " raises an error when the user doesn't have permission to convert topic " do
2019-05-06 05:44:15 -04:00
sign_in ( user )
2018-05-31 10:45:32 -04:00
put " /t/ #{ topic . id } /convert-topic/public.json "
expect ( response ) . to be_forbidden
end
context " success " do
it " returns success " do
2019-05-06 06:00:22 -04:00
sign_in ( admin )
2019-07-19 11:52:50 -04:00
put " /t/ #{ topic . id } /convert-topic/public.json?category_id= #{ category . id } "
2018-05-31 10:45:32 -04:00
topic . reload
expect ( topic . archetype ) . to eq ( Archetype . default )
2019-07-19 11:52:50 -04:00
expect ( topic . category_id ) . to eq ( category . id )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-31 10:45:32 -04:00
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-31 10:45:32 -04:00
expect ( result [ 'success' ] ) . to eq ( true )
expect ( result [ 'url' ] ) . to be_present
end
end
end
2017-09-27 23:04:17 -04:00
end
2017-09-04 04:36:02 -04:00
describe '#timings' do
2021-12-14 13:09:07 -05:00
fab! ( :post_1 ) { Fabricate ( :post , user : post_author1 , topic : topic ) }
2017-09-04 04:36:02 -04:00
it 'should record the timing' do
sign_in ( user )
2017-08-31 00:06:56 -04:00
post " /topics/timings.json " , params : {
2017-09-04 04:36:02 -04:00
topic_id : topic . id ,
topic_time : 5 ,
timings : { post_1 . post_number = > 2 }
2017-08-31 00:06:56 -04:00
}
2017-09-04 04:36:02 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2017-09-04 04:36:02 -04:00
post_timing = PostTiming . first
expect ( post_timing . topic ) . to eq ( topic )
expect ( post_timing . user ) . to eq ( user )
expect ( post_timing . msecs ) . to eq ( 2 )
end
2021-02-18 09:48:15 -05:00
it 'caps post read time at the max integer value (2^31 - 1)' do
PostTiming . create! (
topic_id : post_1 . topic . id ,
post_number : post_1 . post_number ,
user_id : user . id ,
msecs : 2 ** 31 - 10
)
sign_in ( user )
post " /topics/timings.json " , params : {
topic_id : topic . id ,
topic_time : 5 ,
timings : { post_1 . post_number = > 100 }
}
expect ( response . status ) . to eq ( 200 )
post_timing = PostTiming . first
expect ( post_timing . topic ) . to eq ( topic )
expect ( post_timing . user ) . to eq ( user )
expect ( post_timing . msecs ) . to eq ( 2 ** 31 - 1 )
end
2017-09-04 04:36:02 -04:00
end
2017-08-23 23:01:11 -04:00
describe '#timer' do
context 'when a user is not logged in' do
it 'should return the right response' do
2018-01-11 22:15:10 -05:00
post " /t/ #{ topic . id } /timer.json " , params : {
time : '24' ,
status_type : TopicTimer . types [ 1 ]
}
expect ( response . status ) . to eq ( 403 )
2017-08-23 23:01:11 -04:00
end
end
context 'when does not have permission' do
it 'should return the right response' do
sign_in ( user )
2017-08-31 00:06:56 -04:00
post " /t/ #{ topic . id } /timer.json " , params : {
2017-08-23 23:01:11 -04:00
time : '24' ,
status_type : TopicTimer . types [ 1 ]
2017-08-31 00:06:56 -04:00
}
2017-08-23 23:01:11 -04:00
expect ( response . status ) . to eq ( 403 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " error_type " ] ) . to eq ( 'invalid_access' )
2017-08-23 23:01:11 -04:00
end
end
2020-12-08 12:13:45 -05:00
context 'when time is in the past' do
it 'returns an error' do
freeze_time
sign_in ( admin )
post " /t/ #{ topic . id } /timer.json " , params : {
time : Time . current - 1 . day ,
status_type : TopicTimer . types [ 1 ]
}
expect ( response . status ) . to eq ( 400 )
end
end
2017-08-23 23:01:11 -04:00
context 'when logged in as an admin' do
before do
2020-03-10 17:13:17 -04:00
freeze_time
2017-08-23 23:01:11 -04:00
sign_in ( admin )
end
it 'should be able to create a topic status update' do
2017-08-31 00:06:56 -04:00
post " /t/ #{ topic . id } /timer.json " , params : {
2017-08-23 23:01:11 -04:00
time : 24 ,
status_type : TopicTimer . types [ 1 ]
2017-08-31 00:06:56 -04:00
}
2017-08-23 23:01:11 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2017-08-23 23:01:11 -04:00
topic_status_update = TopicTimer . last
expect ( topic_status_update . topic ) . to eq ( topic )
2020-03-10 17:13:17 -04:00
expect ( topic_status_update . execute_at ) . to eq_time ( 24 . hours . from_now )
2017-08-23 23:01:11 -04:00
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2017-08-23 23:01:11 -04:00
expect ( DateTime . parse ( json [ 'execute_at' ] ) )
2020-03-10 17:13:17 -04:00
. to eq_time ( DateTime . parse ( topic_status_update . execute_at . to_s ) )
2017-08-23 23:01:11 -04:00
2021-02-04 19:12:56 -05:00
expect ( json [ 'duration_minutes' ] ) . to eq ( topic_status_update . duration_minutes )
2017-08-23 23:01:11 -04:00
expect ( json [ 'closed' ] ) . to eq ( topic . reload . closed )
end
it 'should be able to delete a topic status update' do
Fabricate ( :topic_timer , topic : topic )
2017-08-31 00:06:56 -04:00
post " /t/ #{ topic . id } /timer.json " , params : {
2017-08-23 23:01:11 -04:00
time : nil ,
status_type : TopicTimer . types [ 1 ]
2017-08-31 00:06:56 -04:00
}
2017-08-23 23:01:11 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2017-08-23 23:01:11 -04:00
expect ( topic . reload . public_topic_timer ) . to eq ( nil )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2017-08-23 23:01:11 -04:00
expect ( json [ 'execute_at' ] ) . to eq ( nil )
2021-02-04 19:12:56 -05:00
expect ( json [ 'duration_minutes' ] ) . to eq ( nil )
2017-08-23 23:01:11 -04:00
expect ( json [ 'closed' ] ) . to eq ( topic . closed )
end
2020-03-19 11:36:31 -04:00
it 'should be able to create a topic status update with duration' do
post " /t/ #{ topic . id } /timer.json " , params : {
2021-02-04 19:12:56 -05:00
duration_minutes : 7200 ,
2020-03-19 11:36:31 -04:00
status_type : TopicTimer . types [ 7 ]
}
expect ( response . status ) . to eq ( 200 )
topic_status_update = TopicTimer . last
expect ( topic_status_update . topic ) . to eq ( topic )
expect ( topic_status_update . execute_at ) . to eq_time ( 5 . days . from_now )
2021-02-04 19:12:56 -05:00
expect ( topic_status_update . duration_minutes ) . to eq ( 7200 )
2020-03-19 11:36:31 -04:00
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2020-03-19 11:36:31 -04:00
expect ( DateTime . parse ( json [ 'execute_at' ] ) )
. to eq_time ( DateTime . parse ( topic_status_update . execute_at . to_s ) )
2021-02-04 19:12:56 -05:00
expect ( json [ 'duration_minutes' ] ) . to eq ( topic_status_update . duration_minutes )
2020-03-19 11:36:31 -04:00
end
2020-05-18 05:47:08 -04:00
it 'should be able to delete a topic status update for delete_replies type' do
Fabricate ( :topic_timer , topic : topic , status_type : TopicTimer . types [ :delete_replies ] )
post " /t/ #{ topic . id } /timer.json " , params : {
time : nil ,
status_type : TopicTimer . types [ 7 ]
}
expect ( response . status ) . to eq ( 200 )
expect ( topic . reload . public_topic_timer ) . to eq ( nil )
json = response . parsed_body
expect ( json [ 'execute_at' ] ) . to eq ( nil )
expect ( json [ 'duration' ] ) . to eq ( nil )
expect ( json [ 'closed' ] ) . to eq ( topic . closed )
end
2017-08-23 23:01:11 -04:00
describe 'publishing topic to category in the future' do
it 'should be able to create the topic status update' do
2017-08-31 00:06:56 -04:00
post " /t/ #{ topic . id } /timer.json " , params : {
2017-08-23 23:01:11 -04:00
time : 24 ,
status_type : TopicTimer . types [ 3 ] ,
category_id : topic . category_id
2017-08-31 00:06:56 -04:00
}
2017-08-23 23:01:11 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2017-08-23 23:01:11 -04:00
topic_status_update = TopicTimer . last
expect ( topic_status_update . topic ) . to eq ( topic )
2020-03-10 17:13:17 -04:00
expect ( topic_status_update . execute_at ) . to eq_time ( 24 . hours . from_now )
2017-08-23 23:01:11 -04:00
expect ( topic_status_update . status_type )
. to eq ( TopicTimer . types [ :publish_to_category ] )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2017-08-23 23:01:11 -04:00
expect ( json [ 'category_id' ] ) . to eq ( topic . category_id )
end
end
describe 'invalid status type' do
it 'should raise the right error' do
2018-01-11 22:15:10 -05:00
post " /t/ #{ topic . id } /timer.json " , params : {
time : 10 ,
status_type : 'something'
}
expect ( response . status ) . to eq ( 400 )
expect ( response . body ) . to include ( 'status_type' )
2017-08-23 23:01:11 -04:00
end
end
end
2020-10-06 15:49:06 -04:00
context 'when logged in as a TL4 user' do
it " raises an error if the user can't see the topic " do
user . update! ( trust_level : TrustLevel [ 4 ] )
sign_in ( user )
pm_topic = Fabricate ( :private_message_topic )
post " /t/ #{ pm_topic . id } /timer.json " , params : {
time : '24' ,
status_type : TopicTimer . types [ 1 ]
}
expect ( response . status ) . to eq ( 403 )
expect ( response . parsed_body [ " error_type " ] ) . to eq ( 'invalid_access' )
end
end
2017-08-23 23:01:11 -04:00
end
2017-12-13 21:53:21 -05:00
2020-10-16 15:24:38 -04:00
describe '#set_slow_mode' do
context 'when not logged in' do
it 'returns a forbidden response' do
put " /t/ #{ topic . id } /slow_mode.json " , params : {
seconds : '3600'
}
expect ( response . status ) . to eq ( 403 )
end
end
context 'logged in as an admin' do
it 'allows admins to set the slow mode interval' do
sign_in ( admin )
put " /t/ #{ topic . id } /slow_mode.json " , params : {
seconds : '3600'
}
topic . reload
expect ( response . status ) . to eq ( 200 )
expect ( topic . slow_mode_seconds ) . to eq ( 3600 )
end
end
context 'logged in as a regular user' do
it 'does nothing if the user is not TL4' do
user . update! ( trust_level : TrustLevel [ 3 ] )
sign_in ( user )
put " /t/ #{ topic . id } /slow_mode.json " , params : {
seconds : '3600'
}
expect ( response . status ) . to eq ( 403 )
end
it 'allows TL4 users to set the slow mode interval' do
user . update! ( trust_level : TrustLevel [ 4 ] )
sign_in ( user )
put " /t/ #{ topic . id } /slow_mode.json " , params : {
seconds : '3600'
}
topic . reload
expect ( response . status ) . to eq ( 200 )
expect ( topic . slow_mode_seconds ) . to eq ( 3600 )
end
end
2020-12-14 12:06:50 -05:00
context 'auto-disable slow mode' do
before { sign_in ( admin ) }
2021-03-17 11:25:43 -04:00
let! ( :timestamp ) { 1 . week . from_now . to_formatted_s ( :iso8601 ) }
2020-12-14 12:06:50 -05:00
it 'sets a topic timer to clear the slow mode automatically' do
put " /t/ #{ topic . id } /slow_mode.json " , params : {
seconds : '3600' , enabled_until : timestamp
}
created_timer = TopicTimer . find_by ( topic : topic )
execute_at = created_timer . execute_at . to_formatted_s ( :iso8601 )
expect ( execute_at ) . to eq ( timestamp )
end
it 'deletes the topic timer' do
put " /t/ #{ topic . id } /slow_mode.json " , params : {
seconds : '3600' , enabled_until : timestamp
}
put " /t/ #{ topic . id } /slow_mode.json " , params : {
seconds : '0' , enabled_until : timestamp
}
created_timer = TopicTimer . find_by ( topic : topic )
expect ( created_timer ) . to be_nil
end
it 'updates the existing timer' do
put " /t/ #{ topic . id } /slow_mode.json " , params : {
seconds : '3600' , enabled_until : timestamp
}
updated_timestamp = 1 . hour . from_now . to_formatted_s ( :iso8601 )
put " /t/ #{ topic . id } /slow_mode.json " , params : {
seconds : '3600' , enabled_until : updated_timestamp
}
created_timer = TopicTimer . find_by ( topic : topic )
execute_at = created_timer . execute_at . to_formatted_s ( :iso8601 )
expect ( execute_at ) . to eq ( updated_timestamp )
end
end
2020-10-16 15:24:38 -04:00
end
2018-02-25 21:42:06 -05:00
describe '#invite' do
describe 'when not logged in' do
it " should return the right response " do
post " /t/ #{ topic . id } /invite.json " , params : {
email : 'jake@adventuretime.ooo'
}
expect ( response . status ) . to eq ( 403 )
end
end
describe 'when logged in' do
before do
sign_in ( user )
end
describe 'as a valid user' do
2021-12-21 13:28:12 -05:00
fab! ( :user_topic ) { Fabricate ( :topic , user : user ) }
2018-02-25 21:42:06 -05:00
it 'should return the right response' do
2021-09-29 10:40:16 -04:00
user . update! ( trust_level : SiteSetting . min_trust_level_to_allow_invite )
2018-02-25 21:42:06 -05:00
expect do
2021-12-21 13:28:12 -05:00
post " /t/ #{ user_topic . id } /invite.json " , params : {
2018-02-25 21:42:06 -05:00
email : 'someguy@email.com'
}
end . to change { Invite . where ( invited_by_id : user . id ) . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
2021-03-25 12:26:22 -04:00
expect ( Jobs :: InviteEmail . jobs . first [ 'args' ] . first [ 'invite_to_topic' ] ) . to be_truthy
2018-02-25 21:42:06 -05:00
end
end
describe 'when user is a group manager' do
2021-03-17 11:25:43 -04:00
fab! ( :group ) { Fabricate ( :group ) . tap { | g | g . add_owner ( user ) } }
fab! ( :private_category ) { Fabricate ( :private_category , group : group ) }
2018-02-25 21:42:06 -05:00
2021-03-17 11:25:43 -04:00
fab! ( :group_private_topic ) do
2018-02-25 21:42:06 -05:00
Fabricate ( :topic , category : private_category , user : user )
end
2021-03-17 11:25:43 -04:00
let! ( :recipient ) { 'jake@adventuretime.ooo' }
2018-02-25 21:42:06 -05:00
2021-12-13 14:44:55 -05:00
before_all do
2021-09-29 10:40:16 -04:00
user . update! ( trust_level : SiteSetting . min_trust_level_to_allow_invite )
end
2018-02-25 21:42:06 -05:00
it " should attach group to the invite " do
post " /t/ #{ group_private_topic . id } /invite.json " , params : {
2018-12-05 10:43:07 -05:00
user : recipient ,
2021-07-27 01:51:10 -04:00
group_ids : " #{ group . id } ,9999999 "
2018-02-25 21:42:06 -05:00
}
expect ( response . status ) . to eq ( 200 )
2021-07-27 01:51:10 -04:00
expect ( Invite . find_by ( email : recipient ) . groups ) . to contain_exactly ( group )
2018-02-25 21:42:06 -05:00
end
2018-12-05 10:43:07 -05:00
describe 'when group is available to automatic groups only' do
before do
group . update! ( automatic : true )
end
it 'should return the right response' do
post " /t/ #{ group_private_topic . id } /invite.json " , params : {
2019-05-06 05:44:15 -04:00
user : user
2018-12-05 10:43:07 -05:00
}
expect ( response . status ) . to eq ( 403 )
end
end
describe 'when user is not part of the required group' do
it 'should return the right response' do
post " /t/ #{ group_private_topic . id } /invite.json " , params : {
2019-05-06 05:44:15 -04:00
user : user
2018-12-05 10:43:07 -05:00
}
expect ( response . status ) . to eq ( 422 )
2020-05-07 11:04:12 -04:00
response_body = response . parsed_body
2018-12-05 10:43:07 -05:00
expect ( response_body [ " errors " ] ) . to eq ( [
I18n . t ( " topic_invite.failed_to_invite " ,
group_names : group . name
)
] )
end
end
2018-02-25 21:42:06 -05:00
end
describe 'when topic id is invalid' do
it 'should return the right response' do
2022-01-10 19:51:57 -05:00
id = topic . id
topic . destroy!
post " /t/ #{ id } /invite.json " , params : {
2019-05-06 05:44:15 -04:00
email : user . email
2018-02-25 21:42:06 -05:00
}
expect ( response . status ) . to eq ( 400 )
end
end
it 'requires an email parameter' do
post " /t/ #{ topic . id } /invite.json "
expect ( response . status ) . to eq ( 400 )
end
2018-08-23 00:36:49 -04:00
describe " when PM has reached maximum allowed numbers of recipients " do
2021-03-17 11:25:43 -04:00
fab! ( :pm ) { Fabricate ( :private_message_topic , user : user ) }
2018-08-23 00:36:49 -04:00
2021-03-17 11:25:43 -04:00
fab! ( :moderator_pm ) { Fabricate ( :private_message_topic , user : moderator ) }
2018-08-23 00:36:49 -04:00
before do
SiteSetting . max_allowed_message_recipients = 2
end
it " doesn't allow normal users to invite " do
post " /t/ #{ pm . id } /invite.json " , params : {
2021-12-13 14:44:55 -05:00
user : user_2 . username
2018-08-23 00:36:49 -04:00
}
expect ( response . status ) . to eq ( 422 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " errors " ] ) . to contain_exactly (
2018-08-23 00:36:49 -04:00
I18n . t ( " pm_reached_recipients_limit " , recipients_limit : SiteSetting . max_allowed_message_recipients )
)
end
it " allows staff to bypass limits " do
sign_in ( moderator )
post " /t/ #{ moderator_pm . id } /invite.json " , params : {
2021-12-13 14:44:55 -05:00
user : user_2 . username
2018-08-23 00:36:49 -04:00
}
expect ( response . status ) . to eq ( 200 )
expect ( moderator_pm . reload . topic_allowed_users . count ) . to eq ( 3 )
end
end
2018-02-25 21:42:06 -05:00
describe 'when user does not have permission to invite to the topic' do
2021-12-21 13:28:12 -05:00
fab! ( :topic ) { pm }
2018-02-25 21:42:06 -05:00
it " should return the right response " do
post " /t/ #{ topic . id } /invite.json " , params : {
user : user . username
}
expect ( response . status ) . to eq ( 403 )
end
end
end
describe " when inviting a group to a topic " do
2021-03-17 11:25:43 -04:00
fab! ( :group ) { Fabricate ( :group ) }
2018-02-25 21:42:06 -05:00
before do
2019-05-06 06:00:22 -04:00
sign_in ( admin )
2018-02-25 21:42:06 -05:00
end
it " should work correctly " do
email = 'hiro@from.heros'
post " /t/ #{ topic . id } /invite.json " , params : {
email : email , group_ids : group . id
}
expect ( response . status ) . to eq ( 200 )
groups = Invite . find_by ( email : email ) . groups
expect ( groups . count ) . to eq ( 1 )
expect ( groups . first . id ) . to eq ( group . id )
end
end
end
2017-12-13 21:53:21 -05:00
describe 'invite_group' do
2021-03-17 11:25:43 -04:00
let! ( :admins ) { Group [ :admins ] }
2017-12-13 21:53:21 -05:00
def invite_group ( topic , expected_status )
post " /t/ #{ topic . id } /invite-group.json " , params : { group : admins . name }
expect ( response . status ) . to eq ( expected_status )
end
before do
admins . update! ( messageable_level : Group :: ALIAS_LEVELS [ :everyone ] )
end
describe 'as an anon user' do
it 'should be forbidden' do
invite_group ( pm , 403 )
end
end
describe 'as a normal user' do
2021-12-13 14:44:55 -05:00
before { sign_in ( user ) }
2017-12-13 21:53:21 -05:00
describe 'when user does not have permission to view the topic' do
it 'should be forbidden' do
invite_group ( pm , 403 )
end
end
describe 'when user has permission to view the topic' do
before do
pm . allowed_users << user
end
it 'should allow user to invite group to topic' do
invite_group ( pm , 200 )
expect ( pm . allowed_groups . first . id ) . to eq ( admins . id )
end
end
end
describe 'as an admin user' do
2019-05-06 06:00:22 -04:00
before do
sign_in ( admin )
end
2017-12-13 21:53:21 -05:00
it " disallows inviting a group to a topic " do
invite_group ( topic , 422 )
end
it " allows inviting a group to a PM " do
invite_group ( pm , 200 )
expect ( pm . allowed_groups . first . id ) . to eq ( admins . id )
end
end
2018-08-23 00:36:49 -04:00
context " when PM has reached maximum allowed numbers of recipients " do
2021-03-17 11:25:43 -04:00
fab! ( :group ) { Fabricate ( :group , messageable_level : 99 ) }
fab! ( :pm ) { Fabricate ( :private_message_topic , user : user ) }
2018-08-23 00:36:49 -04:00
2021-03-17 11:25:43 -04:00
fab! ( :moderator_pm ) { Fabricate ( :private_message_topic , user : moderator ) }
2018-08-23 00:36:49 -04:00
before do
SiteSetting . max_allowed_message_recipients = 2
end
it " doesn't allow normal users to invite " do
post " /t/ #{ pm . id } /invite-group.json " , params : {
group : group . name
}
expect ( response . status ) . to eq ( 422 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " errors " ] ) . to contain_exactly (
2018-08-23 00:36:49 -04:00
I18n . t ( " pm_reached_recipients_limit " , recipients_limit : SiteSetting . max_allowed_message_recipients )
)
end
it " allows staff to bypass limits " do
sign_in ( moderator )
post " /t/ #{ moderator_pm . id } /invite-group.json " , params : {
group : group . name
}
expect ( response . status ) . to eq ( 200 )
expect ( moderator_pm . reload . topic_allowed_users . count + moderator_pm . topic_allowed_groups . count ) . to eq ( 3 )
end
end
2017-12-13 21:53:21 -05:00
end
2018-03-13 15:59:12 -04:00
describe 'shared drafts' do
before do
SiteSetting . shared_drafts_category = shared_drafts_category . id
end
2018-03-23 11:12:22 -04:00
describe " # update_shared_draft " do
2021-03-17 11:25:43 -04:00
fab! ( :other_cat ) { Fabricate ( :category ) }
fab! ( :topic ) { Fabricate ( :topic , category : shared_drafts_category , visible : false ) }
2018-03-23 11:12:22 -04:00
context " anonymous " do
it " doesn't allow staff to update the shared draft " do
put " /t/ #{ topic . id } /shared-draft.json " , params : { category_id : other_cat . id }
expect ( response . code . to_i ) . to eq ( 403 )
end
end
context " as a moderator " do
before do
sign_in ( moderator )
end
2018-03-23 11:33:02 -04:00
context " with a shared draft " do
2021-03-17 11:25:43 -04:00
fab! ( :shared_draft ) { Fabricate ( :shared_draft , topic : topic , category : category ) }
2018-03-23 11:33:02 -04:00
it " allows staff to update the category id " do
put " /t/ #{ topic . id } /shared-draft.json " , params : { category_id : other_cat . id }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-03-23 11:33:02 -04:00
topic . reload
expect ( topic . shared_draft . category_id ) . to eq ( other_cat . id )
end
end
context " without a shared draft " do
it " allows staff to update the category id " do
put " /t/ #{ topic . id } /shared-draft.json " , params : { category_id : other_cat . id }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-03-23 11:33:02 -04:00
topic . reload
expect ( topic . shared_draft . category_id ) . to eq ( other_cat . id )
end
2018-03-23 11:12:22 -04:00
end
end
end
2018-03-13 15:59:12 -04:00
describe " # publish " do
2021-03-17 11:25:43 -04:00
fab! ( :topic ) { Fabricate ( :topic , category : shared_drafts_category , visible : false ) }
2021-12-14 13:09:07 -05:00
fab! ( :post ) { Fabricate ( :post , user : post_author1 , topic : topic ) }
2018-03-13 15:59:12 -04:00
it " fails for anonymous users " do
2018-03-20 20:33:06 -04:00
put " /t/ #{ topic . id } /publish.json " , params : { destination_category_id : category . id }
expect ( response . status ) . to eq ( 403 )
2018-03-13 15:59:12 -04:00
end
it " fails as a regular user " do
2019-05-06 05:44:15 -04:00
sign_in ( user )
2018-03-20 20:33:06 -04:00
put " /t/ #{ topic . id } /publish.json " , params : { destination_category_id : category . id }
expect ( response . status ) . to eq ( 403 )
2018-03-13 15:59:12 -04:00
end
context " as staff " do
before do
sign_in ( moderator )
end
it " will publish the topic " do
put " /t/ #{ topic . id } /publish.json " , params : { destination_category_id : category . id }
2018-03-20 20:33:06 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body [ 'basic_topic' ]
2018-03-13 15:59:12 -04:00
result = Topic . find ( json [ 'id' ] )
expect ( result . category_id ) . to eq ( category . id )
expect ( result . visible ) . to eq ( true )
end
2020-12-14 14:08:20 -05:00
it 'fails if the destination category is the shared drafts category' do
put " /t/ #{ topic . id } /publish.json " , params : { destination_category_id : shared_drafts_category . id }
expect ( response . status ) . to eq ( 400 )
end
2018-03-13 15:59:12 -04:00
end
end
end
2018-04-09 01:01:16 -04:00
describe " crawler " do
context " when not a crawler " do
it " renders with the application layout " do
get topic . url
body = response . body
2022-06-20 10:33:05 -04:00
expect ( body ) . to have_tag ( :script , with : { src : " /assets/discourse.js " } )
2018-04-09 01:01:16 -04:00
expect ( body ) . to have_tag ( :meta , with : { name : 'fragment' } )
end
end
context " when a crawler " do
2019-06-04 21:24:52 -04:00
it " renders with the crawler layout, and handles proper pagination " do
page1_time = 3 . months . ago
page2_time = 2 . months . ago
page3_time = 1 . month . ago
2018-04-13 00:58:33 -04:00
freeze_time page1_time
2021-12-14 13:09:07 -05:00
Fabricate ( :post , user : post_author2 , topic : topic )
Fabricate ( :post , user : post_author3 , topic : topic )
2018-04-13 00:58:33 -04:00
freeze_time page2_time
2021-12-14 13:09:07 -05:00
Fabricate ( :post , user : post_author4 , topic : topic )
Fabricate ( :post , user : post_author5 , topic : topic )
2018-04-13 00:58:33 -04:00
freeze_time page3_time
2021-12-14 13:09:07 -05:00
Fabricate ( :post , user : post_author6 , topic : topic )
2018-04-09 01:01:16 -04:00
2021-05-20 21:43:47 -04:00
# ugly, but no interface to set this and we don't want to create
2018-04-09 01:01:16 -04:00
# 100 posts to test this thing
TopicView . stubs ( :chunk_size ) . returns ( 2 )
2019-06-04 21:24:52 -04:00
user_agent = " Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) "
2018-04-09 01:01:16 -04:00
2019-06-04 21:24:52 -04:00
get topic . url , env : { " HTTP_USER_AGENT " = > user_agent }
2018-04-09 01:01:16 -04:00
2019-06-04 21:24:52 -04:00
body = response . body
2018-04-09 01:01:16 -04:00
2019-06-04 21:24:52 -04:00
expect ( body ) . to have_tag ( :body , with : { class : 'crawler' } )
expect ( body ) . to_not have_tag ( :meta , with : { name : 'fragment' } )
expect ( body ) . to include ( '<link rel="next" href="' + topic . relative_url + " ?page=2 " )
2018-04-13 00:58:33 -04:00
2022-03-15 05:17:06 -04:00
expect ( body ) . to include ( " id='post_1' " )
expect ( body ) . to include ( " id='post_2' " )
2019-06-04 21:24:52 -04:00
expect ( response . headers [ 'Last-Modified' ] ) . to eq ( page1_time . httpdate )
2018-04-09 01:01:16 -04:00
2019-06-04 21:32:47 -04:00
get topic . url + " ?page=2 " , env : { " HTTP_USER_AGENT " = > user_agent }
2019-06-04 21:24:52 -04:00
body = response . body
expect ( response . headers [ 'Last-Modified' ] ) . to eq ( page2_time . httpdate )
2022-03-15 05:17:06 -04:00
expect ( body ) . to include ( " id='post_3' " )
expect ( body ) . to include ( " id='post_4' " )
2019-06-04 21:24:52 -04:00
expect ( body ) . to include ( '<link rel="prev" href="' + topic . relative_url )
expect ( body ) . to include ( '<link rel="next" href="' + topic . relative_url + " ?page=3 " )
2019-06-04 21:32:47 -04:00
get topic . url + " ?page=3 " , env : { " HTTP_USER_AGENT " = > user_agent }
2019-06-04 21:24:52 -04:00
body = response . body
2018-04-13 00:58:33 -04:00
2019-06-04 21:24:52 -04:00
expect ( response . headers [ 'Last-Modified' ] ) . to eq ( page3_time . httpdate )
expect ( body ) . to include ( '<link rel="prev" href="' + topic . relative_url + " ?page=2 " )
end
2018-04-09 01:01:16 -04:00
2020-03-09 10:31:24 -04:00
context " canonical_url " do
fab! ( :topic_embed ) { Fabricate ( :topic_embed , embed_url : " https://markvanlan.com " ) }
2021-03-17 11:25:43 -04:00
let! ( :user_agent ) { " Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) " }
2020-03-09 10:31:24 -04:00
it " set to topic.url when embed_set_canonical_url is false " do
get topic_embed . topic . url , env : { " HTTP_USER_AGENT " = > user_agent }
expect ( response . body ) . to include ( '<link rel="canonical" href="' + topic_embed . topic . url )
end
it " set to topic_embed.embed_url when embed_set_canonical_url is true " do
SiteSetting . embed_set_canonical_url = true
get topic_embed . topic . url , env : { " HTTP_USER_AGENT " = > user_agent }
expect ( response . body ) . to include ( '<link rel="canonical" href="' + topic_embed . embed_url )
end
end
2019-06-04 21:24:52 -04:00
context " wayback machine " do
it " renders crawler layout " do
get topic . url , env : { " HTTP_USER_AGENT " = > " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36 " , " HTTP_VIA " = > " HTTP/1.0 web.archive.org (Wayback Save Page) " }
2019-06-02 22:13:32 -04:00
body = response . body
2018-04-09 01:01:16 -04:00
2019-06-04 21:24:52 -04:00
expect ( body ) . to have_tag ( :body , with : { class : 'crawler' } )
expect ( body ) . to_not have_tag ( :meta , with : { name : 'fragment' } )
2019-06-02 22:13:32 -04:00
end
2018-04-09 01:01:16 -04:00
end
end
end
2018-08-09 20:51:03 -04:00
describe " # reset_bump_date " do
context " errors " do
it " needs you to be logged in " do
put " /t/ #{ topic . id } /reset-bump-date.json "
expect ( response . status ) . to eq ( 403 )
end
2019-01-02 10:57:05 -05:00
[ :user ] . each do | user |
2018-08-09 20:51:03 -04:00
it " denies access for #{ user } " do
sign_in ( Fabricate ( user ) )
put " /t/ #{ topic . id } /reset-bump-date.json "
expect ( response . status ) . to eq ( 403 )
end
end
2021-05-20 21:43:47 -04:00
it " should fail for non-existent topic " do
2019-05-07 19:31:47 -04:00
max_id = Topic . maximum ( :id )
2019-05-06 06:00:22 -04:00
sign_in ( admin )
2019-05-07 19:31:47 -04:00
put " /t/ #{ max_id + 1 } /reset-bump-date.json "
2018-08-09 20:51:03 -04:00
expect ( response . status ) . to eq ( 404 )
end
end
2019-01-02 10:57:05 -05:00
[ :admin , :moderator , :trust_level_4 ] . each do | user |
2018-08-09 20:51:03 -04:00
it " should reset bumped_at as #{ user } " do
2021-12-21 13:28:12 -05:00
sign_in ( public_send ( user ) )
topic . update! ( bumped_at : 1 . hour . ago )
2018-08-09 20:51:03 -04:00
timestamp = 1 . day . ago
2021-12-14 13:09:07 -05:00
Fabricate ( :post , user : post_author1 , topic : topic , created_at : timestamp )
2018-08-09 20:51:03 -04:00
put " /t/ #{ topic . id } /reset-bump-date.json "
expect ( response . status ) . to eq ( 200 )
2020-03-10 17:13:17 -04:00
expect ( topic . reload . bumped_at ) . to eq_time ( timestamp )
2018-08-09 20:51:03 -04:00
end
end
end
2021-07-30 05:00:48 -04:00
describe '#private_message_reset_new' do
fab! ( :group ) do
Fabricate ( :group , messageable_level : Group :: ALIAS_LEVELS [ :everyone ] ) . tap do | g |
g . add ( user_2 )
end
end
fab! ( :group_message ) do
create_post (
user : user ,
target_group_names : [ group . name ] ,
archetype : Archetype . private_message
) . topic
end
fab! ( :private_message ) do
create_post (
user : user ,
target_usernames : [ user_2 . username ] ,
archetype : Archetype . private_message
) . topic
end
2021-08-05 02:44:58 -04:00
fab! ( :private_message_2 ) do
create_post (
user : user ,
target_usernames : [ user_2 . username ] ,
archetype : Archetype . private_message
) . topic
end
2021-07-30 05:00:48 -04:00
before do
sign_in ( user_2 )
end
it 'returns the right response when inbox param is missing' do
put " /topics/pm-reset-new.json "
expect ( response . status ) . to eq ( 400 )
end
it " returns the right response when trying to reset new private messages of an invalid group " do
put " /topics/pm-reset-new.json " , params : {
inbox : " group " ,
group_name : " randomgroup "
}
expect ( response . status ) . to eq ( 404 )
end
it " returns the right response when trying to reset new private messages of a restricted group " do
sign_in ( user )
put " /topics/pm-reset-new.json " , params : {
inbox : " group " ,
group_name : group . name
}
expect ( response . status ) . to eq ( 404 )
end
it " can reset all new group private messages " do
put " /topics/pm-reset-new.json " , params : {
inbox : " group " ,
group_name : group . name
}
expect ( response . status ) . to eq ( 200 )
2021-09-09 00:39:27 -04:00
expect ( response . parsed_body [ " topic_ids " ] ) . to contain_exactly ( group_message . id )
2021-07-30 05:00:48 -04:00
expect ( DismissedTopicUser . count ) . to eq ( 1 )
expect ( DismissedTopicUser . exists? ( topic : group_message , user : user_2 ) )
. to eq ( true )
end
it " can reset new personal private messages " do
put " /topics/pm-reset-new.json " , params : {
inbox : " user " ,
}
expect ( response . status ) . to eq ( 200 )
2021-09-09 00:39:27 -04:00
expect ( response . parsed_body [ " topic_ids " ] ) . to contain_exactly (
private_message . id ,
private_message_2 . id
)
2021-07-30 05:00:48 -04:00
2021-08-05 02:44:58 -04:00
expect ( DismissedTopicUser . count ) . to eq ( 2 )
2021-07-30 05:00:48 -04:00
2021-08-05 02:44:58 -04:00
expect ( DismissedTopicUser . exists? ( user : user_2 , topic : [
private_message ,
private_message_2
] ) ) . to eq ( true )
2021-07-30 05:00:48 -04:00
end
it 'can reset new personal and group private messages' do
2021-08-05 02:44:58 -04:00
stub_const ( TopicQuery , " DEFAULT_PER_PAGE_COUNT " , 1 ) do
put " /topics/pm-reset-new.json " , params : {
inbox : " all " ,
}
2021-07-30 05:00:48 -04:00
2021-08-05 02:44:58 -04:00
expect ( response . status ) . to eq ( 200 )
2021-07-30 05:00:48 -04:00
2021-08-05 02:44:58 -04:00
expect ( DismissedTopicUser . count ) . to eq ( 3 )
2021-07-30 05:00:48 -04:00
2021-08-05 02:44:58 -04:00
expect ( DismissedTopicUser . exists? ( user : user_2 , topic : [
private_message ,
private_message_2 ,
group_message
] ) ) . to eq ( true )
end
2021-07-30 05:00:48 -04:00
end
it 'returns the right response is topic_ids params is not valid' do
put " /topics/pm-reset-new.json " , params : {
topic_ids : '1'
}
expect ( response . status ) . to eq ( 400 )
end
it 'can reset new private messages from given topic ids' do
put " /topics/pm-reset-new.json " , params : {
topic_ids : [ group_message . id , '12345' ]
}
expect ( response . status ) . to eq ( 200 )
expect ( DismissedTopicUser . count ) . to eq ( 1 )
expect ( DismissedTopicUser . exists? ( topic : group_message , user : user_2 ) )
. to eq ( true )
put " /topics/pm-reset-new.json " , params : {
topic_ids : [ private_message . id , '12345' ]
}
expect ( response . status ) . to eq ( 200 )
expect ( DismissedTopicUser . exists? ( topic : private_message , user : user_2 ) )
. to eq ( true )
end
end
2021-09-09 21:20:50 -04:00
describe '#archive_message' do
fab! ( :group ) do
Fabricate ( :group , messageable_level : Group :: ALIAS_LEVELS [ :everyone ] ) . tap do | g |
g . add ( user )
end
end
fab! ( :group_message ) do
create_post (
user : user ,
target_group_names : [ group . name ] ,
archetype : Archetype . private_message
) . topic
end
it 'should be able to archive a private message' do
sign_in ( user )
message = MessageBus . track_publish (
PrivateMessageTopicTrackingState . group_channel ( group . id )
) do
put " /t/ #{ group_message . id } /archive-message.json "
expect ( response . status ) . to eq ( 200 )
end . first
expect ( message . data [ " message_type " ] ) . to eq (
PrivateMessageTopicTrackingState :: GROUP_ARCHIVE_MESSAGE_TYPE
)
expect ( message . data [ " payload " ] [ " acting_user_id " ] ) . to eq ( user . id )
body = response . parsed_body
expect ( body [ " group_name " ] ) . to eq ( group . name )
end
end
2017-08-23 23:01:11 -04:00
end