2013-02-05 14:16:51 -05:00
require 'spec_helper'
2014-02-19 17:41:17 +01:00
shared_examples 'finding and showing post' do
let ( :user ) { log_in }
let ( :post ) { Fabricate ( :post , user : user ) }
2013-02-05 14:16:51 -05:00
2014-02-19 17:41:17 +01:00
it 'ensures the user can see the post' do
Guardian . any_instance . expects ( :can_see? ) . with ( post ) . returns ( false )
xhr :get , action , params
response . should be_forbidden
2013-04-24 18:05:35 +10:00
end
2014-02-19 17:41:17 +01:00
it 'succeeds' do
xhr :get , action , params
response . should be_success
end
2013-02-05 14:16:51 -05:00
2014-02-19 17:41:17 +01:00
context " deleted post " do
before do
post . trash! ( user )
end
it " can't find deleted posts as an anonymous user " do
xhr :get , action , params
2013-02-05 14:16:51 -05:00
response . should be_forbidden
end
2014-02-19 17:41:17 +01:00
it " can't find deleted posts as a regular user " do
log_in ( :user )
xhr :get , action , params
response . should be_forbidden
2013-02-05 14:16:51 -05:00
end
2014-02-19 17:41:17 +01:00
it " can find posts as a moderator " do
log_in ( :moderator )
xhr :get , action , params
response . should be_success
end
end
end
2013-02-08 17:49:15 -05:00
2014-02-19 17:41:17 +01:00
describe PostsController do
2013-02-08 17:49:15 -05:00
2014-02-19 17:41:17 +01:00
describe 'short_link' do
it 'logs the incoming link once' do
IncomingLink . expects ( :add ) . once . returns ( true )
p = Fabricate ( :post )
get :short_link , post_id : p . id , user_id : 999
response . should be_redirect
end
end
2013-02-08 17:49:15 -05:00
2014-02-19 17:41:17 +01:00
describe 'show' do
include_examples 'finding and showing post' do
let ( :action ) { :show }
let ( :params ) { { id : post . id } }
end
end
2013-02-08 17:49:15 -05:00
2014-02-19 17:41:17 +01:00
describe 'by_number' do
include_examples 'finding and showing post' do
let ( :action ) { :by_number }
let ( :params ) { { topic_id : post . topic_id , post_number : post . post_number } }
2013-02-08 17:49:15 -05:00
end
2013-08-06 17:42:36 -04:00
end
describe 'reply_history' do
2014-02-20 17:38:13 +01:00
include_examples 'finding and showing post' do
let ( :action ) { :reply_history }
let ( :params ) { { id : post . id } }
2013-08-06 17:42:36 -04:00
end
2013-02-08 17:49:15 -05:00
2014-02-20 17:38:13 +01:00
it 'asks post for reply history' do
2013-08-06 17:42:36 -04:00
Post . any_instance . expects ( :reply_history )
xhr :get , :reply_history , id : post . id
2014-02-20 17:38:13 +01:00
end
end
describe 'replies' do
include_examples 'finding and showing post' do
let ( :action ) { :replies }
let ( :params ) { { post_id : post . id } }
end
it 'asks post for replies' do
Post . any_instance . expects ( :replies )
xhr :get , :replies , post_id : post . id
2013-08-06 17:42:36 -04:00
end
2013-02-05 14:16:51 -05:00
end
describe 'delete a post' do
it 'raises an exception when not logged in' do
lambda { xhr :delete , :destroy , id : 123 } . should raise_error ( Discourse :: NotLoggedIn )
end
describe 'when logged in' do
2013-02-07 15:12:55 -05:00
let ( :user ) { log_in ( :moderator ) }
let ( :post ) { Fabricate ( :post , user : user , post_number : 2 ) }
2013-02-05 14:16:51 -05:00
2014-02-18 17:19:38 +01:00
it 'does not allow to destroy when edit time limit expired' do
Guardian . any_instance . stubs ( :can_delete_post? ) . with ( post ) . returns ( false )
Post . any_instance . stubs ( :edit_time_limit_expired? ) . returns ( true )
xhr :delete , :destroy , id : post . id
response . status . should == 422
JSON . parse ( response . body ) [ 'errors' ] . should include ( I18n . t ( 'too_late_to_edit' ) )
end
2013-02-05 14:16:51 -05:00
it " raises an error when the user doesn't have permission to see the post " do
Guardian . any_instance . expects ( :can_delete? ) . with ( post ) . returns ( false )
xhr :delete , :destroy , id : post . id
response . should be_forbidden
end
2013-03-18 17:52:29 -04:00
it " uses a PostDestroyer " do
destroyer = mock
PostDestroyer . expects ( :new ) . with ( user , post ) . returns ( destroyer )
destroyer . expects ( :destroy )
2013-02-05 14:16:51 -05:00
xhr :delete , :destroy , id : post . id
end
2013-02-07 15:12:55 -05:00
end
end
describe 'recover a post' do
it 'raises an exception when not logged in' do
lambda { xhr :put , :recover , post_id : 123 } . should raise_error ( Discourse :: NotLoggedIn )
end
describe 'when logged in' do
let ( :user ) { log_in ( :moderator ) }
let ( :post ) { Fabricate ( :post , user : user , post_number : 2 ) }
it " raises an error when the user doesn't have permission to see the post " do
Guardian . any_instance . expects ( :can_recover_post? ) . with ( post ) . returns ( false )
xhr :put , :recover , post_id : post . id
response . should be_forbidden
end
2013-07-22 17:48:24 +10:00
it " recovers a post correctly " do
topic_id = create_post . topic_id
post = create_post ( topic_id : topic_id )
PostDestroyer . new ( user , post ) . destroy
2013-02-07 15:12:55 -05:00
xhr :put , :recover , post_id : post . id
2013-07-22 17:48:24 +10:00
post . reload
post . deleted_at . should == nil
2013-02-05 14:16:51 -05:00
end
end
end
describe 'destroy_many' do
it 'raises an exception when not logged in' do
lambda { xhr :delete , :destroy_many , post_ids : [ 123 , 345 ] } . should raise_error ( Discourse :: NotLoggedIn )
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
describe 'when logged in' do
let! ( :poster ) { log_in ( :moderator ) }
let! ( :post1 ) { Fabricate ( :post , user : poster , post_number : 2 ) }
2013-09-04 11:53:00 -04:00
let! ( :post2 ) { Fabricate ( :post , topic_id : post1 . topic_id , user : poster , post_number : 3 , reply_to_post_number : post1 . post_number ) }
2013-02-05 14:16:51 -05:00
it " raises invalid parameters no post_ids " do
2013-09-04 11:53:00 -04:00
lambda { xhr :delete , :destroy_many } . should raise_error ( ActionController :: ParameterMissing )
2013-02-05 14:16:51 -05:00
end
it " raises invalid parameters with missing ids " do
lambda { xhr :delete , :destroy_many , post_ids : [ 12345 ] } . should raise_error ( Discourse :: InvalidParameters )
end
it " raises an error when the user doesn't have permission to delete the posts " do
Guardian . any_instance . expects ( :can_delete? ) . with ( instance_of ( Post ) ) . returns ( false )
xhr :delete , :destroy_many , post_ids : [ post1 . id , post2 . id ]
response . should be_forbidden
end
it " deletes the post " do
2013-09-04 20:50:58 -04:00
PostDestroyer . any_instance . expects ( :destroy ) . twice
2013-02-05 14:16:51 -05:00
xhr :delete , :destroy_many , post_ids : [ post1 . id , post2 . id ]
end
it " updates the highest read data for the forum " do
2013-09-04 20:50:58 -04:00
Topic . expects ( :reset_highest ) . twice
2013-02-05 14:16:51 -05:00
xhr :delete , :destroy_many , post_ids : [ post1 . id , post2 . id ]
end
2013-09-04 11:53:00 -04:00
describe " can delete replies " do
before do
PostReply . create ( post_id : post1 . id , reply_id : post2 . id )
end
it " deletes the post and the reply to it " do
2013-09-04 20:50:58 -04:00
PostDestroyer . any_instance . expects ( :destroy ) . twice
2013-09-04 11:53:00 -04:00
xhr :delete , :destroy_many , post_ids : [ post1 . id ] , reply_post_ids : [ post1 . id ]
end
end
2013-02-05 14:16:51 -05:00
end
end
describe 'edit a post' do
it 'raises an exception when not logged in' do
lambda { xhr :put , :update , id : 2 } . should raise_error ( Discourse :: NotLoggedIn )
end
describe 'when logged in' do
let ( :post ) { Fabricate ( :post , user : log_in ) }
let ( :update_params ) do
2013-11-15 23:28:16 +01:00
{
id : post . id ,
post : { raw : 'edited body' , edit_reason : 'typo' } ,
image_sizes : { 'http://image.com/image.jpg' = > { 'width' = > 123 , 'height' = > 456 } } ,
}
2013-02-05 14:16:51 -05:00
end
2014-02-18 17:19:38 +01:00
it 'does not allow to update when edit time limit expired' do
Guardian . any_instance . stubs ( :can_edit? ) . with ( post ) . returns ( false )
Post . any_instance . stubs ( :edit_time_limit_expired? ) . returns ( true )
xhr :put , :update , update_params
response . status . should == 422
JSON . parse ( response . body ) [ 'errors' ] . should include ( I18n . t ( 'too_late_to_edit' ) )
end
2013-02-05 14:16:51 -05:00
it 'passes the image sizes through' do
Post . any_instance . expects ( :image_sizes = )
xhr :put , :update , update_params
end
2013-11-15 23:28:16 +01:00
it 'passes the edit reason through' do
Post . any_instance . expects ( :edit_reason = )
xhr :put , :update , update_params
end
2013-02-05 14:16:51 -05:00
it " raises an error when the post parameter is missing " do
update_params . delete ( :post )
2013-02-25 19:42:20 +03:00
lambda {
2013-02-05 14:16:51 -05:00
xhr :put , :update , update_params
2013-10-02 16:59:57 +02:00
} . should raise_error ( ActionController :: ParameterMissing )
2013-02-05 14:16:51 -05:00
end
it " raises an error when the user doesn't have permission to see the post " do
2014-01-07 10:32:09 -05:00
Guardian . any_instance . expects ( :can_edit? ) . with ( post ) . at_least_once . returns ( false )
2013-02-05 14:16:51 -05:00
xhr :put , :update , update_params
response . should be_forbidden
end
it " calls revise with valid parameters " do
2013-11-15 23:28:16 +01:00
PostRevisor . any_instance . expects ( :revise! ) . with ( post . user , 'edited body' , edit_reason : 'typo' )
2013-02-05 14:16:51 -05:00
xhr :put , :update , update_params
end
it " extracts links from the new body " do
TopicLink . expects ( :extract_from ) . with ( post )
xhr :put , :update , update_params
end
end
end
describe 'bookmark a post' do
it 'raises an exception when not logged in' do
lambda { xhr :put , :bookmark , post_id : 2 } . should raise_error ( Discourse :: NotLoggedIn )
end
describe 'when logged in' do
let ( :post ) { Fabricate ( :post , user : log_in ) }
it " raises an error if the user doesn't have permission to see the post " do
Guardian . any_instance . expects ( :can_see? ) . with ( post ) . returns ( false )
2013-02-25 19:42:20 +03:00
xhr :put , :bookmark , post_id : post . id , bookmarked : 'true'
2013-02-05 14:16:51 -05:00
response . should be_forbidden
end
it 'creates a bookmark' do
2013-03-01 15:07:44 +03:00
PostAction . expects ( :act ) . with ( post . user , post , PostActionType . types [ :bookmark ] )
2013-02-05 14:16:51 -05:00
xhr :put , :bookmark , post_id : post . id , bookmarked : 'true'
end
it 'removes a bookmark' do
2013-03-01 15:07:44 +03:00
PostAction . expects ( :remove_act ) . with ( post . user , post , PostActionType . types [ :bookmark ] )
2013-02-05 14:16:51 -05:00
xhr :put , :bookmark , post_id : post . id
end
end
end
describe 'creating a post' do
it 'raises an exception when not logged in' do
lambda { xhr :post , :create } . should raise_error ( Discourse :: NotLoggedIn )
end
describe 'when logged in' do
let! ( :user ) { log_in }
let ( :new_post ) { Fabricate . build ( :post , user : user ) }
2013-06-07 00:52:03 -07:00
it " raises an exception without a raw parameter " do
lambda { xhr :post , :create } . should raise_error ( ActionController :: ParameterMissing )
2013-02-05 14:16:51 -05:00
end
it 'calls the post creator' do
PostCreator . any_instance . expects ( :create ) . returns ( new_post )
2013-06-07 00:52:03 -07:00
xhr :post , :create , { raw : 'test' }
2013-02-05 14:16:51 -05:00
response . should be_success
end
it 'returns JSON of the post' do
PostCreator . any_instance . expects ( :create ) . returns ( new_post )
2013-06-07 00:52:03 -07:00
xhr :post , :create , { raw : 'test' }
2013-02-05 14:16:51 -05:00
:: JSON . parse ( response . body ) . should be_present
end
2013-07-29 12:25:19 +10:00
it 'protects against dupes' do
# TODO we really should be using a mock redis here
xhr :post , :create , { raw : 'this is a test post 123' , title : 'this is a test title 123' , wpid : 1 }
response . should be_success
original = response . body
xhr :post , :create , { raw : 'this is a test post 123' , title : 'this is a test title 123' , wpid : 2 }
response . should be_success
response . body . should == original
end
2013-05-10 16:58:23 -04:00
context " errors " do
let ( :post_with_errors ) { Fabricate . build ( :post , user : user ) }
before do
post_with_errors . errors . add ( :base , I18n . t ( :spamming_host ) )
PostCreator . any_instance . stubs ( :errors ) . returns ( post_with_errors . errors )
PostCreator . any_instance . expects ( :create ) . returns ( post_with_errors )
end
it " does not succeed " do
2013-06-07 00:52:03 -07:00
xhr :post , :create , { raw : 'test' }
2013-05-10 16:58:23 -04:00
User . any_instance . expects ( :flag_linked_posts_as_spam ) . never
response . should_not be_success
end
it " it triggers flag_linked_posts_as_spam when the post creator returns spam " do
PostCreator . any_instance . expects ( :spam? ) . returns ( true )
User . any_instance . expects ( :flag_linked_posts_as_spam )
2013-06-07 00:52:03 -07:00
xhr :post , :create , { raw : 'test' }
2013-05-10 16:58:23 -04:00
end
end
2013-02-05 14:16:51 -05:00
context " parameters " do
let ( :post_creator ) { mock }
before do
post_creator . expects ( :create ) . returns ( new_post )
post_creator . stubs ( :errors ) . returns ( nil )
end
it " passes raw through " do
2013-06-07 00:52:03 -07:00
PostCreator . expects ( :new ) . with ( user , has_entries ( 'raw' = > 'hello' ) ) . returns ( post_creator )
xhr :post , :create , { raw : 'hello' }
2013-02-05 14:16:51 -05:00
end
it " passes title through " do
2013-06-07 00:52:03 -07:00
PostCreator . expects ( :new ) . with ( user , has_entries ( 'title' = > 'new topic title' ) ) . returns ( post_creator )
xhr :post , :create , { raw : 'hello' , title : 'new topic title' }
2013-02-05 14:16:51 -05:00
end
it " passes topic_id through " do
2013-06-07 00:52:03 -07:00
PostCreator . expects ( :new ) . with ( user , has_entries ( 'topic_id' = > '1234' ) ) . returns ( post_creator )
xhr :post , :create , { raw : 'hello' , topic_id : 1234 }
2013-02-05 14:16:51 -05:00
end
it " passes archetype through " do
2013-06-07 00:52:03 -07:00
PostCreator . expects ( :new ) . with ( user , has_entries ( 'archetype' = > 'private_message' ) ) . returns ( post_creator )
xhr :post , :create , { raw : 'hello' , archetype : 'private_message' }
2013-02-05 14:16:51 -05:00
end
it " passes category through " do
2013-06-07 00:52:03 -07:00
PostCreator . expects ( :new ) . with ( user , has_entries ( 'category' = > 'cool' ) ) . returns ( post_creator )
xhr :post , :create , { raw : 'hello' , category : 'cool' }
2013-02-05 14:16:51 -05:00
end
it " passes target_usernames through " do
2013-06-07 00:52:03 -07:00
PostCreator . expects ( :new ) . with ( user , has_entries ( 'target_usernames' = > 'evil,trout' ) ) . returns ( post_creator )
xhr :post , :create , { raw : 'hello' , target_usernames : 'evil,trout' }
2013-02-05 14:16:51 -05:00
end
it " passes reply_to_post_number through " do
2013-06-07 00:52:03 -07:00
PostCreator . expects ( :new ) . with ( user , has_entries ( 'reply_to_post_number' = > '6789' ) ) . returns ( post_creator )
xhr :post , :create , { raw : 'hello' , reply_to_post_number : 6789 }
2013-02-05 14:16:51 -05:00
end
it " passes image_sizes through " do
2013-09-27 10:55:50 +02:00
PostCreator . expects ( :new ) . with ( user , has_entries ( 'image_sizes' = > { 'width' = > '100' , 'height' = > '200' } ) ) . returns ( post_creator )
xhr :post , :create , { raw : 'hello' , image_sizes : { width : '100' , height : '200' } }
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
it " passes meta_data through " do
2013-06-07 00:52:03 -07:00
PostCreator . expects ( :new ) . with ( user , has_entries ( 'meta_data' = > { 'xyz' = > 'abc' } ) ) . returns ( post_creator )
xhr :post , :create , { raw : 'hello' , meta_data : { xyz : 'abc' } }
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
end
end
end
2014-02-04 20:05:50 +01:00
describe " revisions " do
let ( :post_revision ) { Fabricate ( :post_revision ) }
it " throws an exception when revision is < 2 " do
expect {
xhr :get , :revisions , post_id : post_revision . post_id , revision : 1
} . to raise_error ( Discourse :: InvalidParameters )
end
context " when edit history is not visible to the public " do
before { SiteSetting . stubs ( :edit_history_visible_to_public ) . returns ( false ) }
it " ensures anonymous can not see the revisions " do
xhr :get , :revisions , post_id : post_revision . post_id , revision : post_revision . number
response . should be_forbidden
end
it " ensures staff can see the revisions " do
log_in ( :admin )
xhr :get , :revisions , post_id : post_revision . post_id , revision : post_revision . number
response . should be_success
end
it " ensures poster can see the revisions " do
user = log_in ( :active_user )
pr = Fabricate ( :post_revision , user : user )
xhr :get , :revisions , post_id : pr . post_id , revision : pr . number
response . should be_success
end
end
context " when edit history is visible to everyone " do
before { SiteSetting . stubs ( :edit_history_visible_to_public ) . returns ( true ) }
it " ensures anyone can see the revisions " do
xhr :get , :revisions , post_id : post_revision . post_id , revision : post_revision . number
response . should be_success
end
end
context " deleted post " do
let ( :admin ) { log_in ( :admin ) }
let ( :deleted_post ) { Fabricate ( :post , user : admin ) }
let ( :deleted_post_revision ) { Fabricate ( :post_revision , user : admin , post : deleted_post ) }
before { deleted_post . trash! ( admin ) }
it " also work on deleted post " do
xhr :get , :revisions , post_id : deleted_post_revision . post_id , revision : deleted_post_revision . number
response . should be_success
end
end
end
2013-02-05 14:16:51 -05:00
end