Initial release of Discourse

This commit is contained in:
Robin Ward
2013-02-05 14:16:51 -05:00
commit 21b5628528
2932 changed files with 143949 additions and 0 deletions

View File

@ -0,0 +1,20 @@
require 'spec_helper'
describe Admin::AdminController do
context 'index' do
it 'needs you to be logged in' do
lambda { xhr :get, :index }.should raise_error(Discourse::NotLoggedIn)
end
it "raises an error if you aren't an admin" do
user = log_in
xhr :get, :index
response.should be_forbidden
end
end
end

View File

@ -0,0 +1,37 @@
require 'spec_helper'
describe Admin::EmailLogsController do
it "is a subclass of AdminController" do
(Admin::EmailLogsController < Admin::AdminController).should be_true
end
let!(:user) { log_in(:admin) }
context '.index' do
before do
xhr :get, :index
end
subject { response }
it { should be_success }
end
context '.test' do
it 'raises an error without the email parameter' do
lambda { xhr :post, :test }.should raise_error(Discourse::InvalidParameters)
end
context 'with an email address' do
it 'enqueues a test email job' do
Jobs.expects(:enqueue).with(:test_email, to_address: 'eviltrout@test.domain')
xhr :post, :test, email_address: 'eviltrout@test.domain'
end
end
end
end

View File

@ -0,0 +1,57 @@
require 'spec_helper'
describe Admin::ExportController do
it "is a subclass of AdminController" do
(Admin::ExportController < Admin::AdminController).should be_true
end
context 'while logged in as an admin' do
before do
@user = log_in(:admin)
end
describe "create" do
it "should start an export job" do
Jobs::Exporter.any_instance.expects(:execute).returns(true)
xhr :post, :create
end
it "should return a job id" do
job_id = 'abc123'
Jobs.stubs(:enqueue).returns( job_id )
xhr :post, :create
json = JSON.parse(response.body)
json.should have_key('job_id')
json['job_id'].should == job_id
end
shared_examples_for "when export should not be started" do
it "should return an error" do
xhr :post, :create
json = JSON.parse(response.body)
json['failed'].should_not be_nil
json['message'].should_not be_nil
end
it "should not start an export job" do
Jobs::Exporter.any_instance.expects(:start_export).never
xhr :post, :create
end
end
context "when an export is already running" do
before do
Export.stubs(:is_export_running?).returns( true )
end
it_should_behave_like "when export should not be started"
end
context "when an import is currently running" do
before do
Import.stubs(:is_import_running?).returns( true )
end
it_should_behave_like "when export should not be started"
end
end
end
end

View File

@ -0,0 +1,37 @@
require 'spec_helper'
describe Admin::FlagsController do
it "is a subclass of AdminController" do
(Admin::FlagsController < Admin::AdminController).should be_true
end
context 'while logged in as an admin' do
before do
@user = log_in(:admin)
end
context 'index' do
it 'returns empty json when nothing is flagged' do
xhr :get, :index
data = ::JSON.parse(response.body)
data["users"].should == []
data["posts"].should == []
end
it 'returns a valid json payload when some thing is flagged' do
p = Fabricate(:post)
u = Fabricate(:user)
PostAction.act(u, p, PostActionType.Types[:spam])
xhr :get, :index
data = ::JSON.parse(response.body)
data["users"].length == 2
data["posts"].length == 1
end
end
end
end

View File

@ -0,0 +1,68 @@
require 'spec_helper'
describe Admin::ImpersonateController do
it "is a subclass of AdminController" do
(Admin::ImpersonateController < Admin::AdminController).should be_true
end
context 'while logged in as an admin' do
let!(:admin) { log_in(:admin) }
let(:user) { Fabricate(:user) }
context 'index' do
it 'returns success' do
xhr :get, :index
response.should be_success
end
end
context 'create' do
it 'requires a username_or_email parameter' do
lambda { xhr :put, :create }.should raise_error(Discourse::InvalidParameters)
end
it 'returns 404 when that user does not exist' do
xhr :post, :create, username_or_email: 'hedonismbot'
response.status.should == 404
end
it "raises an invalid access error if the user can't be impersonated" do
Guardian.any_instance.expects(:can_impersonate?).with(user).returns(false)
xhr :post, :create, username_or_email: user.email
response.should be_forbidden
end
context 'success' do
it "changes the current user session id" do
xhr :post, :create, username_or_email: user.username
session[:current_user_id].should == user.id
end
it "returns success" do
xhr :post, :create, username_or_email: user.email
response.should be_success
end
it "also works with an email address" do
xhr :post, :create, username_or_email: user.email
session[:current_user_id].should == user.id
end
it "also works with a name" do
xhr :post, :create, username_or_email: user.name
session[:current_user_id].should == user.id
end
end
end
end
end

View File

@ -0,0 +1,42 @@
require 'spec_helper'
describe Admin::SiteCustomizationsController do
it "is a subclass of AdminController" do
(Admin::UsersController < Admin::AdminController).should be_true
end
context 'while logged in as an admin' do
before do
@user = log_in(:admin)
end
context ' .index' do
it 'returns success' do
xhr :get, :index
response.should be_success
end
it 'returns JSON' do
xhr :get, :index
::JSON.parse(response.body).should be_present
end
end
context ' .create' do
it 'returns success' do
xhr :post, :create, site_customization: {name: 'my test name'}
response.should be_success
end
it 'returns json' do
xhr :post, :create, site_customization: {name: 'my test name'}
::JSON.parse(response.body).should be_present
end
end
end
end

View File

@ -0,0 +1,43 @@
require 'spec_helper'
describe Admin::SiteSettingsController do
it "is a subclass of AdminController" do
(Admin::SiteSettingsController < Admin::AdminController).should be_true
end
context 'while logged in as an admin' do
before do
@user = log_in(:admin)
end
context 'index' do
it 'returns success' do
xhr :get, :index
response.should be_success
end
it 'returns JSON' do
xhr :get, :index
::JSON.parse(response.body).should be_present
end
end
context 'update' do
it 'requires a value parameter' do
lambda { xhr :put, :update, id: 'test_setting' }.should raise_error(Discourse::InvalidParameters)
end
it 'sets the value when the param is present' do
SiteSetting.expects(:'test_setting=').with('hello').once
xhr :put, :update, id: 'test_setting', value: 'hello'
end
end
end
end

View File

@ -0,0 +1,118 @@
require 'spec_helper'
describe Admin::UsersController do
it "is a subclass of AdminController" do
(Admin::UsersController < Admin::AdminController).should be_true
end
context 'while logged in as an admin' do
before do
@user = log_in(:admin)
end
context '.index' do
it 'returns success' do
xhr :get, :index
response.should be_success
end
it 'returns JSON' do
xhr :get, :index
::JSON.parse(response.body).should be_present
end
end
context '.show' do
it 'returns success' do
xhr :get, :show, id: @user.username
response.should be_success
end
end
context '.approve_bulk' do
let(:evil_trout) { Fabricate(:evil_trout) }
it "does nothing without uesrs" do
User.any_instance.expects(:approve).never
xhr :put, :approve_bulk
end
it "won't approve the user when not allowed" do
Guardian.any_instance.expects(:can_approve?).with(evil_trout).returns(false)
User.any_instance.expects(:approve).never
xhr :put, :approve_bulk, users: [evil_trout.id]
end
it "approves the user when permitted" do
Guardian.any_instance.expects(:can_approve?).with(evil_trout).returns(true)
User.any_instance.expects(:approve).once
xhr :put, :approve_bulk, users: [evil_trout.id]
end
end
context '.approve' do
let(:evil_trout) { Fabricate(:evil_trout) }
it "raises an error when the user doesn't have permission" do
Guardian.any_instance.expects(:can_approve?).with(evil_trout).returns(false)
xhr :put, :approve, user_id: evil_trout.id
response.should be_forbidden
end
it 'calls approve' do
User.any_instance.expects(:approve).with(@user)
xhr :put, :approve, user_id: evil_trout.id
end
end
context '.revoke_admin' do
before do
@another_admin = Fabricate(:another_admin)
end
it 'raises an error unless the user can revoke access' do
Guardian.any_instance.expects(:can_revoke_admin?).with(@another_admin).returns(false)
xhr :put, :revoke_admin, user_id: @another_admin.id
response.should be_forbidden
end
it 'updates the admin flag' do
xhr :put, :revoke_admin, user_id: @another_admin.id
@another_admin.reload
@another_admin.should_not be_admin
end
end
context '.grant_admin' do
before do
@another_user = Fabricate(:coding_horror)
end
it "raises an error when the user doesn't have permission" do
Guardian.any_instance.expects(:can_grant_admin?).with(@another_user).returns(false)
xhr :put, :grant_admin, user_id: @another_user.id
response.should be_forbidden
end
it "returns a 404 if the username doesn't exist" do
xhr :put, :grant_admin, user_id: 123123
response.should be_forbidden
end
it 'updates the admin flag' do
xhr :put, :grant_admin, user_id: @another_user.id
@another_user.reload
@another_user.should be_admin
end
end
end
end

View File

@ -0,0 +1,55 @@
require 'spec_helper'
require_dependency 'version'
describe Admin::VersionsController do
before do
RestClient.stubs(:get).returns( {success: 'OK', version: '1.2.33'}.to_json )
end
it "is a subclass of AdminController" do
(Admin::VersionsController < Admin::AdminController).should be_true
end
context 'while logged in as an admin' do
before do
@user = log_in(:admin)
end
describe 'show' do
context 'when discourse_org_access_key is set' do
before do
SiteSetting.stubs(:discourse_org_access_key).returns('asdf')
end
subject { xhr :get, :show }
it { should be_success }
it 'should return the currently available version' do
json = JSON.parse(subject.body)
json['latest_version'].should == '1.2.33'
end
it "should return the installed version" do
json = JSON.parse(subject.body)
json['installed_version'].should == Discourse::VERSION::STRING
end
end
context 'when discourse_org_access_key is blank' do
subject { xhr :get, :show }
it { should be_success }
it 'should return the installed version as the currently available version' do
json = JSON.parse(subject.body)
json['latest_version'].should == Discourse::VERSION::STRING
end
it "should return the installed version" do
json = JSON.parse(subject.body)
json['installed_version'].should == Discourse::VERSION::STRING
end
end
end
end
end

View File

@ -0,0 +1,147 @@
require 'spec_helper'
describe CategoriesController do
describe 'create' do
it 'requires the user to be logged in' do
lambda { xhr :post, :create }.should raise_error(Discourse::NotLoggedIn)
end
describe 'logged in' do
before do
@user = log_in(:moderator)
end
it "raises an exception when they don't have permission to create it" do
Guardian.any_instance.expects(:can_create?).with(Category, nil).returns(false)
xhr :post, :create, name: 'hello', color: '#ff0'
response.should be_forbidden
end
it 'raises an exception when the name is missing' do
lambda { xhr :post, :create, color: '#ff0' }.should raise_error(Discourse::InvalidParameters)
end
it 'raises an exception when the color is missing' do
lambda { xhr :post, :create, name: 'hello' }.should raise_error(Discourse::InvalidParameters)
end
describe 'failure' do
before do
@category = Fabricate(:category, user: @user)
xhr :post, :create, name: @category.name, color: '#ff0'
end
it { should_not respond_with(:success) }
it 'returns errors on a duplicate category name' do
response.code.to_i.should == 422
end
end
describe 'success' do
before do
xhr :post, :create, name: 'hello', color: '#ff0'
end
it 'creates a category' do
Category.count.should == 1
end
it { should respond_with(:success) }
end
end
end
describe 'destroy' do
it 'requires the user to be logged in' do
lambda { xhr :delete, :destroy, id: 'category'}.should raise_error(Discourse::NotLoggedIn)
end
describe 'logged in' do
before do
@user = log_in
@category = Fabricate(:category, user: @user)
end
it "raises an exception if they don't have permission to delete it" do
Guardian.any_instance.expects(:can_delete_category?).returns(false)
xhr :delete, :destroy, id: @category.slug
response.should be_forbidden
end
it "deletes the record" do
Guardian.any_instance.expects(:can_delete_category?).returns(true)
lambda { xhr :delete, :destroy, id: @category.slug}.should change(Category, :count).by(-1)
end
end
end
describe 'update' do
it 'requires the user to be logged in' do
lambda { xhr :put, :update, id: 'category'}.should raise_error(Discourse::NotLoggedIn)
end
describe 'logged in' do
before do
@user = log_in(:moderator)
@category = Fabricate(:category, user: @user)
end
it "raises an exception if they don't have permission to edit it" do
Guardian.any_instance.expects(:can_edit?).returns(false)
xhr :put, :update, id: @category.slug, name: 'hello', color: '#ff0'
response.should be_forbidden
end
it "requires a name" do
lambda { xhr :put, :update, id: @category.slug, color: '#fff' }.should raise_error(Discourse::InvalidParameters)
end
it "requires a color" do
lambda { xhr :put, :update, id: @category.slug, name: 'asdf'}.should raise_error(Discourse::InvalidParameters)
end
describe 'failure' do
before do
@other_category = Fabricate(:category, name: 'Other', user: @user )
xhr :put, :update, id: @category.id, name: @other_category.name, color: '#ff0'
end
it 'returns errors on a duplicate category name' do
response.should_not be_success
end
it 'returns errors on a duplicate category name' do
response.code.to_i.should == 422
end
end
describe 'success' do
before do
xhr :put, :update, id: @category.id, name: 'science', color: '#000'
@category.reload
end
it 'updates the name' do
@category.name.should == 'science'
end
it 'updates the color' do
@category.color.should == '#000'
end
end
end
end
end

View File

@ -0,0 +1,64 @@
require 'spec_helper'
describe ClicksController do
context 'create' do
context 'missing params' do
it 'raises an error without the url param' do
lambda { xhr :get, :track, post_id: 123 }.should raise_error(Discourse::InvalidParameters)
end
it "redirects to the url even without the topic_id or post_id params" do
xhr :get, :track, url: 'http://google.com'
response.should redirect_to("http://google.com")
end
end
context 'correct params' do
before do
request.stubs(:remote_ip).returns('192.168.0.1')
end
context 'with a post_id' do
it 'calls create_from' do
TopicLinkClick.expects(:create_from).with(url: 'http://discourse.org', post_id: 123, ip: '192.168.0.1')
xhr :get, :track, url: 'http://discourse.org', post_id: 123
response.should redirect_to("http://discourse.org")
end
it 'redirects to the url' do
TopicLinkClick.stubs(:create_from)
xhr :get, :track, url: 'http://discourse.org', post_id: 123
response.should redirect_to("http://discourse.org")
end
it 'will pass the user_id to create_from' do
TopicLinkClick.expects(:create_from).with(url: 'http://discourse.org', post_id: 123, ip: '192.168.0.1')
xhr :get, :track, url: 'http://discourse.org', post_id: 123
response.should redirect_to("http://discourse.org")
end
it "doesn't redirect with the redirect=false param" do
TopicLinkClick.expects(:create_from).with(url: 'http://discourse.org', post_id: 123, ip: '192.168.0.1')
xhr :get, :track, url: 'http://discourse.org', post_id: 123, redirect: 'false'
response.should_not be_redirect
end
end
context 'with a topic_id' do
it 'calls create_from' do
TopicLinkClick.expects(:create_from).with(url: 'http://discourse.org', topic_id: 789, ip: '192.168.0.1')
xhr :get, :track, url: 'http://discourse.org', topic_id: 789
response.should redirect_to("http://discourse.org")
end
end
end
end
end

View File

@ -0,0 +1,22 @@
require 'spec_helper'
describe DraftController do
it 'requires you to be logged in' do
lambda { post :update }.should raise_error(Discourse::NotLoggedIn)
end
it 'saves a draft on update' do
user = log_in
post :update, draft_key: 'xyz', data: 'my data', sequence: 0
Draft.get(user, 'xyz', 0).should == 'my data'
end
it 'destroys drafts when required' do
user = log_in
Draft.set(user, 'xxx', 0, 'hi')
delete :destroy, draft_key: 'xxx', sequence: 0
Draft.get(user, 'xxx', 0).should be_nil
end
end

View File

@ -0,0 +1,99 @@
require 'spec_helper'
describe EmailController do
context '.preferences_redirect' do
it 'requires you to be logged in' do
lambda { get :preferences_redirect }.should raise_error(Discourse::NotLoggedIn)
end
context 'when logged in' do
let!(:user) { log_in }
it 'redirects to your user preferences' do
get :preferences_redirect
response.should redirect_to("/users/#{user.username}/preferences")
end
end
end
context '.resubscribe' do
let(:user) { Fabricate(:user, email_digests: false) }
context 'with a valid key' do
before do
get :resubscribe, key: user.temporary_key
user.reload
end
it 'subscribes the user' do
user.email_digests.should be_true
end
end
end
context '.unsubscribe' do
let(:user) { Fabricate(:user) }
context 'with a valid key' do
before do
get :unsubscribe, key: user.temporary_key
user.reload
end
it 'unsubscribes the user' do
user.email_digests.should be_false
end
it "does not set the not_found instance variable" do
assigns(:not_found).should be_blank
end
end
context 'when logged in as a different user' do
let!(:logged_in_user) { log_in(:coding_horror) }
before do
get :unsubscribe, key: user.temporary_key
user.reload
end
it 'does not unsubscribe the user' do
user.email_digests.should be_true
end
it 'sets not found' do
assigns(:not_found).should be_true
end
end
context 'when logged in as the keyed user' do
before do
log_in_user(user)
get :unsubscribe, key: user.temporary_key
user.reload
end
it 'unsubscribes the user' do
user.email_digests.should be_false
end
it "doesn't set not found" do
assigns(:not_found).should be_blank
end
end
it "sets not_found when the key didn't match anything" do
get :unsubscribe, key: 'asdfasdf'
assigns(:not_found).should be_true
end
end
end

View File

@ -0,0 +1,82 @@
require 'spec_helper'
describe ExcerptController do
describe 'show' do
it 'raises an error without the url param' do
lambda { xhr :get, :show }.should raise_error(Discourse::InvalidParameters)
end
it 'returns 404 with a non-existant url' do
xhr :get, :show, url: 'http://madeup.com/url'
response.status.should == 404
end
it 'returns 404 from an invalid url' do
xhr :get, :show, url: 'asdfasdf'
response.status.should == 404
end
describe 'user excerpt' do
before do
@user = Fabricate(:user)
@url = "http://test.host/users/#{@user.username}"
xhr :get, :show, url: @url
end
it 'returns a valid status' do
response.should be_success
end
it 'returns an excerpt type for the forum topic' do
parsed = JSON.parse(response.body)
parsed['type'].should == 'User'
end
end
describe 'forum topic excerpt' do
before do
@post = Fabricate(:post)
@url = "http://test.host#{@post.topic.relative_url}"
xhr :get, :show, url: @url
end
it 'returns a valid status' do
response.should be_success
end
it 'returns an excerpt type for the forum topic' do
parsed = JSON.parse(response.body)
parsed['type'].should == 'Post'
end
end
describe 'post excerpt' do
before do
@post = Fabricate(:post)
@url = "http://test.host#{@post.topic.relative_url}/1"
xhr :get, :show, url: @url
end
it 'returns a valid status' do
response.should be_success
end
it 'returns an excerpt type for the forum topic' do
parsed = JSON.parse(response.body)
parsed['type'].should == 'Post'
end
end
end
end

View File

@ -0,0 +1,151 @@
require 'spec_helper'
describe InvitesController do
context '.destroy' do
it 'requires you to be logged in' do
lambda {
delete :destroy, email: 'jake@adventuretime.ooo'
}.should raise_error(Discourse::NotLoggedIn)
end
context 'while logged in' do
let!(:user) { log_in }
let!(:invite) { Fabricate(:invite, invited_by: user) }
let(:another_invite) { Fabricate(:invite, email: 'anotheremail@address.com') }
it 'raises an error when the email is missing' do
lambda { delete :destroy }.should raise_error(Discourse::InvalidParameters)
end
it "raises an error when the email cannot be found" do
lambda { delete :destroy, email: 'finn@adventuretime.ooo' }.should raise_error(Discourse::InvalidParameters)
end
it 'raises an error when the invite is not yours' do
lambda { delete :destroy, email: another_invite.email }.should raise_error(Discourse::InvalidParameters)
end
it "destroys the invite" do
Invite.any_instance.expects(:destroy)
delete :destroy, email: invite.email
end
end
end
context '.show' do
context 'with an invalid invite id' do
before do
get :show, id: "doesn't exist"
end
it "redirects to the root" do
response.should redirect_to("/")
end
it "should not change the session" do
session[:current_user_id].should be_blank
end
end
context 'with a deleted invite' do
let(:topic) { Fabricate(:topic) }
let(:invite) { topic.invite_by_email(topic.user, "iceking@adventuretime.ooo") }
let(:deleted_invite) { invite.destroy; invite }
before do
get :show, id: deleted_invite.invite_key
end
it "redirects to the root" do
response.should redirect_to("/")
end
it "should not change the session" do
session[:current_user_id].should be_blank
end
end
context 'with a valid invite id' do
let(:topic) { Fabricate(:topic) }
let(:invite) { topic.invite_by_email(topic.user, "iceking@adventuretime.ooo") }
it 'redeems the invite' do
Invite.any_instance.expects(:redeem)
get :show, id: invite.invite_key
end
context 'when redeem returns a user' do
let(:user) { Fabricate(:coding_horror) }
context 'success' do
before do
Invite.any_instance.expects(:redeem).returns(user)
get :show, id: invite.invite_key
end
it 'logs in the user' do
session[:current_user_id].should == user.id
end
it 'redirects to the first topic the user was invited to' do
response.should redirect_to(topic.relative_url)
end
end
context 'welcome message' do
before do
Invite.any_instance.stubs(:redeem).returns(user)
Jobs.expects(:enqueue).with(:invite_email, has_key(:invite_id))
end
it 'sends a welcome message if set' do
user.send_welcome_message = true
user.expects(:enqueue_welcome_message).with('welcome_invite')
get :show, id: invite.invite_key
end
it "doesn't send a welcome message if not set" do
user.expects(:enqueue_welcome_message).with('welcome_invite').never
get :show, id: invite.invite_key
end
end
context 'access_required' do
it "doesn't set a cookie for access if there is no access required" do
SiteSetting.expects(:restrict_access?).returns(false)
Invite.any_instance.expects(:redeem).returns(user)
get :show, id: invite.invite_key
cookies[:_access].should be_blank
end
it "sets the cookie when access is required" do
SiteSetting.expects(:restrict_access?).returns(true)
SiteSetting.expects(:access_password).returns('adventure time!')
Invite.any_instance.expects(:redeem).returns(user)
get :show, id: invite.invite_key
cookies[:_access].should == 'adventure time!'
end
end
end
end
end
end

View File

@ -0,0 +1,87 @@
require 'spec_helper'
describe ListController do
# we need some data
before do
@user = Fabricate(:coding_horror)
@post = Fabricate(:post, :user => @user)
end
context 'index' do
before do
xhr :get, :index
end
it { should respond_with(:success) }
end
context 'category' do
context 'in a category' do
let(:category) { Fabricate(:category) }
it "raises an invalid access error when the user can't see the category" do
Guardian.any_instance.expects(:can_see?).with(category).returns(false)
xhr :get, :category, category: category.slug
response.should be_forbidden
end
context 'with access to see the category' do
before do
xhr :get, :category, category: category.slug
end
it { should respond_with(:success) }
end
end
context 'uncategorized' do
it "doesn't check access to see the category, since we didn't provide one" do
Guardian.any_instance.expects(:can_see?).never
xhr :get, :category, category: SiteSetting.uncategorized_name
end
it "responds with success" do
xhr :get, :category, category: SiteSetting.uncategorized_name
response.should be_success
end
end
end
context 'favorited' do
it 'raises an error when not logged in' do
lambda { xhr :get, :favorited }.should raise_error(Discourse::NotLoggedIn)
end
context 'when logged in' do
before do
log_in_user(@user)
xhr :get, :favorited
end
it { should respond_with(:success) }
end
end
context 'read' do
it 'raises an error when not logged in' do
lambda { xhr :get, :read }.should raise_error(Discourse::NotLoggedIn)
end
context 'when logged in' do
before do
log_in_user(@user)
xhr :get, :read
end
it { should respond_with(:success) }
end
end
end

View File

@ -0,0 +1,22 @@
require 'spec_helper'
describe NotificationsController do
context 'when logged in' do
let!(:user) { log_in }
before do
xhr :get, :index
end
subject { response }
it { should be_success }
end
context 'when not logged in' do
it 'should raise an error' do
lambda { xhr :get, :index }.should raise_error(Discourse::NotLoggedIn)
end
end
end

View File

@ -0,0 +1,15 @@
require 'spec_helper'
describe OneboxController do
it 'asks the oneboxer for the preview' do
Oneboxer.expects(:preview).with('http://google.com')
xhr :get, :show, url: 'http://google.com'
end
it 'invalidates the cache if refresh is passed' do
Oneboxer.expects(:invalidate).with('http://google.com')
xhr :get, :show, url: 'http://google.com', refresh: true
end
end

View File

@ -0,0 +1,127 @@
require 'spec_helper'
describe PostActionsController do
describe 'create' do
it 'requires you to be logged in' do
lambda { xhr :post, :create }.should raise_error(Discourse::NotLoggedIn)
end
describe 'logged in' do
before do
@user = log_in
@post = Fabricate(:post, user: Fabricate(:coding_horror))
end
it 'raises an error when the id is missing' do
lambda { xhr :post, :create, post_action_type_id: PostActionType.Types[:like] }.should raise_error(Discourse::InvalidParameters)
end
it 'raises an error when the post_action_type_id index is missing' do
lambda { xhr :post, :create, id: @post.id }.should raise_error(Discourse::InvalidParameters)
end
it "fails when the user doesn't have permission to see the post" do
Guardian.any_instance.expects(:can_see?).with(@post).returns(false)
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.Types[:like]
response.should be_forbidden
end
it "fails when the user doesn't have permission to perform that action" do
Guardian.any_instance.expects(:post_can_act?).with(@post, :like).returns(false)
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.Types[:like]
response.should be_forbidden
end
it 'allows us to create an post action on a post' do
PostAction.expects(:act).once.with(@user, @post, PostActionType.Types[:like], nil)
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.Types[:like]
end
end
end
context 'destroy' do
let(:post) { Fabricate(:post, user: Fabricate(:coding_horror)) }
it 'requires you to be logged in' do
lambda { xhr :delete, :destroy, id: post.id }.should raise_error(Discourse::NotLoggedIn)
end
context 'logged in' do
let!(:user) { log_in }
it 'raises an error when the post_action_type_id is missing' do
lambda { xhr :delete, :destroy, id: post.id }.should raise_error(Discourse::InvalidParameters)
end
it "returns 404 when the post action type doesn't exist for that user" do
xhr :delete, :destroy, id: post.id, post_action_type_id: 1
response.code.should == '404'
end
context 'with a post_action record ' do
let!(:post_action) { PostAction.create(user_id: user.id, post_id: post.id, post_action_type_id: 1)}
it 'returns success' do
xhr :delete, :destroy, id: post.id, post_action_type_id: 1
response.should be_success
end
it 'deletes the action' do
xhr :delete, :destroy, id: post.id, post_action_type_id: 1
PostAction.exists?(user_id: user.id, post_id: post.id, post_action_type_id: 1, deleted_at: nil).should be_false
end
it 'ensures it can be deleted' do
Guardian.any_instance.expects(:can_delete?).with(post_action).returns(false)
xhr :delete, :destroy, id: post.id, post_action_type_id: 1
response.should be_forbidden
end
end
end
end
describe 'users' do
let!(:post) { Fabricate(:post, user: log_in) }
it 'raises an error without an id' do
lambda {
xhr :get, :users, post_action_type_id: PostActionType.Types[:like]
}.should raise_error(Discourse::InvalidParameters)
end
it 'raises an error without a post action type' do
lambda {
xhr :get, :users, id: post.id
}.should raise_error(Discourse::InvalidParameters)
end
it "fails when the user doesn't have permission to see the post" do
Guardian.any_instance.expects(:can_see?).with(post).returns(false)
xhr :get, :users, id: post.id, post_action_type_id: PostActionType.Types[:like]
response.should be_forbidden
end
it 'raises an error when the post action type cannot be seen' do
Guardian.any_instance.expects(:can_see_post_actors?).with(instance_of(Topic), PostActionType.Types[:like]).returns(false)
xhr :get, :users, id: post.id, post_action_type_id: PostActionType.Types[:like]
response.should be_forbidden
end
it 'succeeds' do
xhr :get, :users, id: post.id, post_action_type_id: PostActionType.Types[:like]
response.should be_success
end
end
end

View File

@ -0,0 +1,278 @@
require 'spec_helper'
describe PostsController do
describe 'show' do
let(:post) { Fabricate(:post, user: log_in) }
it 'ensures the user can see the post' do
Guardian.any_instance.expects(:can_see?).with(post).returns(false)
xhr :get, :show, id: post.id
response.should be_forbidden
end
it 'suceeds' do
xhr :get, :show, id: post.id
response.should be_success
end
end
describe 'versions' do
it 'raises an exception when not logged in' do
lambda { xhr :get, :versions, post_id: 123 }.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)
xhr :get, :versions, post_id: post.id
response.should be_forbidden
end
it 'renders JSON' do
xhr :get, :versions, post_id: post.id
::JSON.parse(response.body).should be_present
end
end
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
let(:post) { Fabricate(:post, user: log_in(:moderator), post_number: 2) }
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
it "deletes the post" do
Post.any_instance.expects(:destroy)
xhr :delete, :destroy, id: post.id
end
it "updates the highest read data for the forum" do
Topic.expects(:reset_highest).with(post.topic_id)
xhr :delete, :destroy, id: post.id
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)
end
describe 'when logged in' do
let!(:poster) { log_in(:moderator) }
let!(:post1) { Fabricate(:post, user: poster, post_number: 2) }
let!(:post2) { Fabricate(:post, topic_id: post1.topic_id, user: poster, post_number: 3) }
it "raises invalid parameters no post_ids" do
lambda { xhr :delete, :destroy_many }.should raise_error(Discourse::InvalidParameters)
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
Post.any_instance.expects(:destroy).twice
xhr :delete, :destroy_many, post_ids: [post1.id, post2.id]
end
it "updates the highest read data for the forum" do
Topic.expects(:reset_highest)
xhr :delete, :destroy_many, post_ids: [post1.id, post2.id]
end
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
{id: post.id,
post: {raw: 'edited body'},
image_sizes: {'http://image.com/image.jpg' => {'width' => 123, 'height' => 456}}}
end
it 'passes the image sizes through' do
Post.any_instance.expects(:image_sizes=)
xhr :put, :update, update_params
end
it "raises an error when the post parameter is missing" do
update_params.delete(:post)
lambda {
xhr :put, :update, update_params
}.should raise_error(Discourse::InvalidParameters)
end
it "raises an error when the user doesn't have permission to see the post" do
Guardian.any_instance.expects(:can_edit?).with(post).returns(false)
xhr :put, :update, update_params
response.should be_forbidden
end
it "calls revise with valid parameters" do
Post.any_instance.expects(:revise).with(post.user, 'edited body')
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)
xhr :put, :bookmark, post_id: post.id, bookmarked: 'true'
response.should be_forbidden
end
it 'creates a bookmark' do
PostAction.expects(:act).with(post.user, post, PostActionType.Types[:bookmark])
xhr :put, :bookmark, post_id: post.id, bookmarked: 'true'
end
it 'removes a bookmark' do
PostAction.expects(:remove_act).with(post.user, post, PostActionType.Types[:bookmark])
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) }
it "raises an exception without a post parameter" do
lambda { xhr :post, :create }.should raise_error(Discourse::InvalidParameters)
end
it 'calls the post creator' do
PostCreator.any_instance.expects(:create).returns(new_post)
xhr :post, :create, post: {raw: 'test'}
response.should be_success
end
it 'returns JSON of the post' do
PostCreator.any_instance.expects(:create).returns(new_post)
xhr :post, :create, post: {raw: 'test'}
::JSON.parse(response.body).should be_present
end
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
PostCreator.expects(:new).with(user, has_entries(raw: 'hello')).returns(post_creator)
xhr :post, :create, post: {raw: 'hello'}
end
it "passes title through" do
PostCreator.expects(:new).with(user, has_entries(title: 'new topic title')).returns(post_creator)
xhr :post, :create, post: {raw: 'hello'}, title: 'new topic title'
end
it "passes topic_id through" do
PostCreator.expects(:new).with(user, has_entries(topic_id: '1234')).returns(post_creator)
xhr :post, :create, post: {raw: 'hello', topic_id: 1234}
end
it "passes archetype through" do
PostCreator.expects(:new).with(user, has_entries(archetype: 'private_message')).returns(post_creator)
xhr :post, :create, post: {raw: 'hello'}, archetype: 'private_message'
end
it "passes category through" do
PostCreator.expects(:new).with(user, has_entries(category: 'cool')).returns(post_creator)
xhr :post, :create, post: {raw: 'hello', category: 'cool'}
end
it "passes target_usernames through" do
PostCreator.expects(:new).with(user, has_entries(target_usernames: 'evil,trout')).returns(post_creator)
xhr :post, :create, post: {raw: 'hello'}, target_usernames: 'evil,trout'
end
it "passes reply_to_post_number through" do
PostCreator.expects(:new).with(user, has_entries(reply_to_post_number: '6789')).returns(post_creator)
xhr :post, :create, post: {raw: 'hello', reply_to_post_number: 6789}
end
it "passes image_sizes through" do
PostCreator.expects(:new).with(user, has_entries(image_sizes: 'test')).returns(post_creator)
xhr :post, :create, post: {raw: 'hello'}, image_sizes: 'test'
end
it "passes meta_data through" do
PostCreator.expects(:new).with(user, has_entries(meta_data: {'xyz' => 'abc'})).returns(post_creator)
xhr :post, :create, post: {raw: 'hello'}, meta_data: {xyz: 'abc'}
end
end
end
end
end

View File

@ -0,0 +1,56 @@
require 'spec_helper'
describe RequestAccessController do
context '.new' do
it "sets a default return path" do
get :new
assigns(:return_path).should == "/"
end
it "assigns the return path we provide" do
get :new, return_path: '/asdf'
assigns(:return_path).should == "/asdf"
end
end
context '.create' do
context 'without an invalid password' do
before do
post :create, password: 'asdf'
end
it "adds a flash" do
flash[:error].should be_present
end
it "doesn't set the cookie" do
cookies[:_access].should be_blank
end
end
context 'with a valid password' do
before do
SiteSetting.stubs(:access_password).returns 'test password'
post :create, password: 'test password', return_path: '/the-path'
end
it 'creates the cookie' do
cookies[:_access].should == 'test password'
end
it 'redirects to the return path' do
response.should redirect_to('/the-path')
end
it 'sets no flash error' do
flash[:error].should be_blank
end
end
end
end

View File

@ -0,0 +1,16 @@
require 'spec_helper'
describe SearchController do
it 'performs the query' do
Search.expects(:query).with('test', nil)
xhr :get, :query, term: 'test'
end
it 'performs the query with a filter' do
Search.expects(:query).with('test', 'topic')
xhr :get, :query, term: 'test', type_filter: 'topic'
end
end

View File

@ -0,0 +1,130 @@
require 'spec_helper'
describe SessionController do
describe '.create' do
let(:user) { Fabricate(:user) }
it "raises an error when the login isn't present" do
lambda { xhr :post, :create }.should raise_error(Discourse::InvalidParameters)
end
describe 'invalid password' do
it "should return an error with an invalid password" do
xhr :post, :create, login: user.username, password: 'sssss'
::JSON.parse(response.body)['error'].should be_present
end
end
describe 'success by username' do
before do
xhr :post, :create, login: user.username, password: 'myawesomepassword'
user.reload
end
it 'sets a session id' do
session[:current_user_id].should == user.id
end
it 'gives the user an auth token' do
user.auth_token.should be_present
end
it 'sets a cookie with the auth token' do
cookies[:_t].should == user.auth_token
end
end
describe 'strips leading @ symbol' do
before do
xhr :post, :create, login: "@" + user.username, password: 'myawesomepassword'
user.reload
end
it 'sets a session id' do
session[:current_user_id].should == user.id
end
end
describe 'also allow login by email' do
before do
xhr :post, :create, login: user.email, password: 'myawesomepassword'
end
it 'sets a session id' do
session[:current_user_id].should == user.id
end
end
describe "when the site requires approval of users" do
before do
SiteSetting.expects(:must_approve_users?).returns(true)
end
context 'with an unapproved user' do
before do
xhr :post, :create, login: user.email, password: 'myawesomepassword'
end
it "doesn't log in the user" do
session[:current_user_id].should be_blank
end
end
end
end
describe '.destroy' do
before do
@user = log_in
xhr :delete, :destroy, id: @user.username
end
it 'removes the session variable' do
session[:current_user_id].should be_blank
end
it 'removes the auth token cookie' do
cookies[:_t].should be_blank
end
end
describe '.forgot_password' do
it 'raises an error without a username parameter' do
lambda { xhr :post, :forgot_password }.should raise_error(Discourse::InvalidParameters)
end
context 'for a non existant username' do
it "doesn't generate a new token for a made up username" do
lambda { xhr :post, :forgot_password, username: 'made_up'}.should_not change(EmailToken, :count)
end
it "doesn't enqueue an email" do
Jobs.expects(:enqueue).with(:user_mail, anything).never
xhr :post, :forgot_password, username: 'made_up'
end
end
context 'for an existing username' do
let(:user) { Fabricate(:user) }
it "generates a new token for a made up username" do
lambda { xhr :post, :forgot_password, username: user.username}.should change(EmailToken, :count)
end
it "enqueues an email" do
Jobs.expects(:enqueue).with(:user_email, has_entries(type: :forgot_password, user_id: user.id))
xhr :post, :forgot_password, username: user.username
end
end
end
end

View File

@ -0,0 +1,27 @@
require 'spec_helper'
describe StaticController do
context "with a static file that's present" do
before do
xhr :get, :show, :id => 'faq'
end
it 'renders the static file if present' do
response.should be_success
end
it "renders the file" do
response.should render_template('faq')
end
end
context "with a missing file" do
it "should respond 404" do
xhr :get, :show, :id => 'does-not-exist'
response.response_code.should == 404
end
end
end

View File

@ -0,0 +1,419 @@
require 'spec_helper'
describe TopicsController do
context 'move_posts' do
it 'needs you to be logged in' do
lambda { xhr :post, :move_posts, topic_id: 111, title: 'blah', post_ids: [1,2,3] }.should raise_error(Discourse::NotLoggedIn)
end
describe 'when logged in' do
let!(:user) { log_in(:moderator) }
let(:p1) { Fabricate(:post, user: user) }
let(:topic) { p1.topic }
it "raises an error without a title" do
lambda { xhr :post, :move_posts, topic_id: topic.id, post_ids: [1,2,3] }.should raise_error(Discourse::InvalidParameters)
end
it "raises an error without postIds" do
lambda { xhr :post, :move_posts, topic_id: topic.id, title: 'blah' }.should raise_error(Discourse::InvalidParameters)
end
it "raises an error when the user doesn't have permission to move the posts" do
Guardian.any_instance.expects(:can_move_posts?).returns(false)
xhr :post, :move_posts, topic_id: topic.id, title: 'blah', post_ids: [1,2,3]
response.should be_forbidden
end
context 'success' do
let(:p2) { Fabricate(:post, user: user) }
before do
Topic.any_instance.expects(:move_posts).with(user, 'blah', [p2.id]).returns(topic)
xhr :post, :move_posts, topic_id: topic.id, title: 'blah', post_ids: [p2.id]
end
it "returns success" do
response.should be_success
end
it "has a JSON response" do
::JSON.parse(response.body)['success'].should be_true
end
it "has a url" do
::JSON.parse(response.body)['url'].should be_present
end
end
context 'failure' do
let(:p2) { Fabricate(:post, user: user) }
before do
Topic.any_instance.expects(:move_posts).with(user, 'blah', [p2.id]).returns(nil)
xhr :post, :move_posts, topic_id: topic.id, title: 'blah', post_ids: [p2.id]
end
it "returns success" do
response.should be_success
end
it "has success in the JSON" do
::JSON.parse(response.body)['success'].should be_false
end
it "has a url" do
::JSON.parse(response.body)['url'].should be_blank
end
end
end
end
context 'status' do
it 'needs you to be logged in' do
lambda { xhr :put, :status, topic_id: 1, status: 'visible', enabled: true }.should raise_error(Discourse::NotLoggedIn)
end
describe 'when logged in' do
before do
@user = log_in(:moderator)
@topic = Fabricate(:topic, user: @user)
end
it "raises an exception if you can't change it" do
Guardian.any_instance.expects(:can_moderate?).with(@topic).returns(false)
xhr :put, :status, topic_id: @topic.id, status: 'visible', enabled: 'true'
response.should be_forbidden
end
it 'requires the status parameter' do
lambda { xhr :put, :status, topic_id: @topic.id, enabled: true }.should raise_error(Discourse::InvalidParameters)
end
it 'requires the enabled parameter' do
lambda { xhr :put, :status, topic_id: @topic.id, status: 'visible' }.should raise_error(Discourse::InvalidParameters)
end
it 'raises an error with a status not in the whitelist' do
lambda { xhr :put, :status, topic_id: @topic.id, status: 'title', enabled: 'true' }.should raise_error(Discourse::InvalidParameters)
end
it 'calls update_status on the forum topic with false' do
Topic.any_instance.expects(:update_status).with('closed', false, @user)
xhr :put, :status, topic_id: @topic.id, status: 'closed', enabled: 'false'
end
it 'calls update_status on the forum topic with true' do
Topic.any_instance.expects(:update_status).with('closed', true, @user)
xhr :put, :status, topic_id: @topic.id, status: 'closed', enabled: 'true'
end
end
end
context 'delete_timings' do
it 'needs you to be logged in' do
lambda { xhr :delete, :destroy_timings, topic_id: 1 }.should raise_error(Discourse::NotLoggedIn)
end
context 'when logged in' do
before do
@user = log_in
@topic = Fabricate(:topic, user: @user)
@topic_user = TopicUser.get(@topic, @topic.user)
end
it 'deletes the forum topic user record' do
PostTiming.expects(:destroy_for).with(@user.id, @topic.id)
xhr :delete, :destroy_timings, topic_id: @topic.id
end
end
end
describe 'mute/unmute' do
it 'needs you to be logged in' do
lambda { xhr :put, :mute, topic_id: 99}.should raise_error(Discourse::NotLoggedIn)
end
it 'needs you to be logged in' do
lambda { xhr :put, :unmute, topic_id: 99}.should raise_error(Discourse::NotLoggedIn)
end
describe 'when logged in' do
before do
@topic = Fabricate(:topic, user: log_in)
end
it "changes the user's starred flag when the parameter is present" do
Topic.any_instance.expects(:toggle_mute).with(@topic.user, true)
xhr :put, :mute, topic_id: @topic.id, starred: 'true'
end
it "removes the user's starred flag when the parameter is not true" do
Topic.any_instance.expects(:toggle_mute).with(@topic.user, false)
xhr :put, :unmute, topic_id: @topic.id, starred: 'false'
end
end
end
describe 'star' do
it 'needs you to be logged in' do
lambda { xhr :put, :star, topic_id: 1, starred: true }.should raise_error(Discourse::NotLoggedIn)
end
describe 'when logged in' do
before do
@topic = Fabricate(:topic, user: log_in)
end
it "ensures the user can see the topic" do
Guardian.any_instance.expects(:can_see?).with(@topic).returns(false)
xhr :put, :star, topic_id: @topic.id, starred: 'true'
response.should be_forbidden
end
it "changes the user's starred flag when the parameter is present" do
Topic.any_instance.expects(:toggle_star).with(@topic.user, true)
xhr :put, :star, topic_id: @topic.id, starred: 'true'
end
it "removes the user's starred flag when the parameter is not true" do
Topic.any_instance.expects(:toggle_star).with(@topic.user, false)
xhr :put, :star, topic_id: @topic.id, starred: 'false'
end
end
end
describe 'delete' do
it "won't allow us to delete a topic when we're not logged in" do
lambda { xhr :delete, :destroy, id: 1 }.should raise_error(Discourse::NotLoggedIn)
end
describe 'when logged in' do
before do
@topic = Fabricate(:topic, user: log_in)
end
describe 'without access' do
it "raises an exception when the user doesn't have permission to delete the topic" do
Guardian.any_instance.expects(:can_delete?).with(@topic).returns(false)
xhr :delete, :destroy, id: @topic.id
response.should be_forbidden
end
end
describe 'with permission' do
before do
Guardian.any_instance.expects(:can_delete?).with(@topic).returns(true)
end
it 'succeeds' do
xhr :delete, :destroy, id: @topic.id
response.should be_success
end
it 'deletes the topic' do
xhr :delete, :destroy, id: @topic.id
Topic.exists?(id: @topic_id).should be_false
end
end
end
end
describe 'show' do
let(:topic) { Fabricate(:post).topic }
let!(:p1) { Fabricate(:post, user: topic.user) }
let!(:p2) { Fabricate(:post, user: topic.user) }
it 'shows a topic correctly' do
xhr :get, :show, id: topic.id
response.should be_success
end
it 'records a view' do
lambda { xhr :get, :show, id: topic.id }.should change(View, :count).by(1)
end
it 'tracks a visit for all html requests' do
current_user = log_in(:coding_horror)
TopicUser.expects(:track_visit!).with(topic, current_user)
get :show, id: topic.id
end
context 'consider for a promotion' do
let!(:user) { log_in(:coding_horror) }
let(:promotion) do
result = mock
Promotion.stubs(:new).with(user).returns(result)
result
end
it "reviews the user for a promotion if they're new" do
user.update_column(:trust_level, TrustLevel.Levels[:new])
promotion.expects(:review)
get :show, id: topic.id
end
it "doesn't reviews the user for a promotion if they're basic" do
promotion.expects(:review).never
get :show, id: topic.id
end
end
context 'filters' do
it 'grabs first page when no post number is selected' do
TopicView.any_instance.expects(:filter_posts_paged).with(0)
xhr :get, :show, id: topic.id
end
it 'delegates a post_number param to TopicView#filter_posts_near' do
TopicView.any_instance.expects(:filter_posts_near).with(p2.post_number)
xhr :get, :show, id: topic.id, post_number: p2.post_number
end
it 'delegates a posts_after param to TopicView#filter_posts_after' do
TopicView.any_instance.expects(:filter_posts_after).with(p1.post_number)
xhr :get, :show, id: topic.id, posts_after: p1.post_number
end
it 'delegates a posts_before param to TopicView#filter_posts_before' do
TopicView.any_instance.expects(:filter_posts_before).with(p2.post_number)
xhr :get, :show, id: topic.id, posts_before: p2.post_number
end
end
end
describe 'update' do
it "won't allow us to update a topic when we're not logged in" do
lambda { xhr :put, :update, topic_id: 1, slug: 'xyz' }.should raise_error(Discourse::NotLoggedIn)
end
describe 'when logged in' do
before do
@topic = Fabricate(:topic, user: log_in)
end
describe 'without permission' do
it "raises an exception when the user doesn't have permission to update the topic" do
Guardian.any_instance.expects(:can_edit?).with(@topic).returns(false)
xhr :put, :update, topic_id: @topic.id, slug: @topic.title
response.should be_forbidden
end
end
describe 'with permission' do
before do
Guardian.any_instance.expects(:can_edit?).with(@topic).returns(true)
end
it 'succeeds' do
xhr :put, :update, topic_id: @topic.id, slug: @topic.title
response.should be_success
end
it 'allows a change of title' do
xhr :put, :update, topic_id: @topic.id, slug: @topic.title, title: 'new title'
@topic.reload
@topic.title.should == 'new title'
end
it 'triggers a change of category' do
Topic.any_instance.expects(:change_category).with('incredible')
xhr :put, :update, topic_id: @topic.id, slug: @topic.title, category: 'incredible'
end
end
end
end
describe 'invite' do
it "won't allow us to invite toa topic when we're not logged in" do
lambda { xhr :post, :invite, topic_id: 1, email: 'jake@adventuretime.ooo' }.should raise_error(Discourse::NotLoggedIn)
end
describe 'when logged in' do
before do
@topic = Fabricate(:topic, user: log_in)
end
it 'requires an email parameter' do
lambda { xhr :post, :invite, topic_id: @topic.id }.should raise_error(Discourse::InvalidParameters)
end
describe 'without permission' do
it "raises an exception when the user doesn't have permission to invite to the topic" do
Guardian.any_instance.expects(:can_invite_to?).with(@topic).returns(false)
xhr :post, :invite, topic_id: @topic.id, user: 'jake@adventuretime.ooo'
response.should be_forbidden
end
end
describe 'with permission' do
before do
Guardian.any_instance.expects(:can_invite_to?).with(@topic).returns(true)
end
context 'when it returns an invite' do
before do
Topic.any_instance.expects(:invite_by_email).with(@topic.user, 'jake@adventuretime.ooo').returns(Invite.new)
xhr :post, :invite, topic_id: @topic.id, user: 'jake@adventuretime.ooo'
end
it 'should succeed' do
response.should be_success
end
it 'returns success JSON' do
::JSON.parse(response.body).should == {'success' => 'OK'}
end
end
context 'when it fails and returns nil' do
before do
Topic.any_instance.expects(:invite_by_email).with(@topic.user, 'jake@adventuretime.ooo').returns(nil)
xhr :post, :invite, topic_id: @topic.id, user: 'jake@adventuretime.ooo'
end
it 'should succeed' do
response.should_not be_success
end
it 'returns success JSON' do
::JSON.parse(response.body).should == {'failed' => 'FAILED'}
end
end
end
end
end
end

View File

@ -0,0 +1,635 @@
require 'spec_helper'
describe UsersController do
describe '.show' do
let!(:user) { log_in }
it 'returns success' do
xhr :get, :show, username: user.username
response.should be_success
end
it "returns not found when the username doesn't exist" do
xhr :get, :show, username: 'madeuppity'
response.should_not be_success
end
it "raises an error on invalid access" do
Guardian.any_instance.expects(:can_see?).with(user).returns(false)
xhr :get, :show, username: user.username
response.should be_forbidden
end
end
describe '.user_preferences_redirect' do
it 'requires the user to be logged in' do
lambda { get :user_preferences_redirect }.should raise_error(Discourse::NotLoggedIn)
end
it "redirects to their profile when logged in" do
user = log_in
get :user_preferences_redirect
response.should redirect_to("/users/#{user.username_lower}/preferences")
end
end
describe '.authorize_email' do
context 'invalid token' do
before do
EmailToken.expects(:confirm).with('asdfasdf').returns(nil)
get :authorize_email, token: 'asdfasdf'
end
it 'return success' do
response.should be_success
end
it 'sets a flash error' do
flash[:error].should be_present
end
end
context 'valid token' do
let(:user) { Fabricate(:user) }
before do
EmailToken.expects(:confirm).with('asdfasdf').returns(user)
get :authorize_email, token: 'asdfasdf'
end
it 'returns success' do
response.should be_success
end
it "doesn't set an error" do
flash[:error].should be_blank
end
it 'logs in as the user' do
session[:current_user_id].should be_present
end
end
end
describe '.activate_account' do
context 'invalid token' do
before do
EmailToken.expects(:confirm).with('asdfasdf').returns(nil)
get :activate_account, token: 'asdfasdf'
end
it 'return success' do
response.should be_success
end
it 'sets a flash error' do
flash[:error].should be_present
end
end
context 'valid token' do
let(:user) { Fabricate(:user) }
context 'welcome message' do
before do
EmailToken.expects(:confirm).with('asdfasdf').returns(user)
end
it 'enqueues a welcome message if the user object indicates so' do
user.send_welcome_message = true
user.expects(:enqueue_welcome_message).with('welcome_user')
get :activate_account, token: 'asdfasdf'
end
it "doesn't enqueue the welcome message if the object returns false" do
user.send_welcome_message = false
user.expects(:enqueue_welcome_message).with('welcome_user').never
get :activate_account, token: 'asdfasdf'
end
end
context 'reponse' do
before do
EmailToken.expects(:confirm).with('asdfasdf').returns(user)
get :activate_account, token: 'asdfasdf'
end
it 'returns success' do
response.should be_success
end
it "doesn't set an error" do
flash[:error].should be_blank
end
it 'logs in as the user' do
session[:current_user_id].should be_present
end
it "doesn't set @needs_approval" do
assigns[:needs_approval].should be_blank
end
end
context 'must_approve_users' do
before do
SiteSetting.expects(:must_approve_users?).returns(true)
EmailToken.expects(:confirm).with('asdfasdf').returns(user)
get :activate_account, token: 'asdfasdf'
end
it 'returns success' do
response.should be_success
end
it 'sets @needs_approval' do
assigns[:needs_approval].should be_present
end
it "doesn't set an error" do
flash[:error].should be_blank
end
it "doesn't log the user in" do
session[:current_user_id].should be_blank
end
end
end
end
describe '.change_email' do
let(:new_email) { 'bubblegum@adventuretime.ooo' }
it "requires you to be logged in" do
lambda { xhr :put, :change_email, username: 'asdf', email: new_email }.should raise_error(Discourse::NotLoggedIn)
end
context 'when logged in' do
let!(:user) { log_in }
it 'raises an error without an email parameter' do
lambda { xhr :put, :change_email, username: user.username }.should raise_error(Discourse::InvalidParameters)
end
it "raises an error if you can't edit the user" do
Guardian.any_instance.expects(:can_edit?).with(user).returns(false)
xhr :put, :change_email, username: user.username, email: new_email
response.should be_forbidden
end
context 'when the new email address is taken' do
let!(:other_user) { Fabricate(:coding_horror) }
it 'raises an error' do
lambda { xhr :put, :change_email, username: user.username, email: other_user.email }.should raise_error(Discourse::InvalidParameters)
end
end
context 'success' do
it 'has an email token' do
lambda { xhr :put, :change_email, username: user.username, email: new_email }.should change(EmailToken, :count)
end
it 'enqueues an email authorization' do
Jobs.expects(:enqueue).with(:user_email, has_entries(type: :authorize_email, user_id: user.id, to_address: new_email))
xhr :put, :change_email, username: user.username, email: new_email
end
end
end
end
describe '.password_reset' do
let(:user) { Fabricate(:user) }
context 'invalid token' do
before do
EmailToken.expects(:confirm).with('asdfasdf').returns(nil)
get :password_reset, token: 'asdfasdf'
end
it 'return success' do
response.should be_success
end
it 'sets a flash error' do
flash[:error].should be_present
end
it "doesn't log in the user" do
session[:current_user_id].should be_blank
end
end
context 'valid token' do
before do
EmailToken.expects(:confirm).with('asdfasdf').returns(user)
get :password_reset, token: 'asdfasdf'
end
it 'returns success' do
response.should be_success
end
it "doesn't set an error" do
flash[:error].should be_blank
end
end
context 'submit change' do
before do
EmailToken.expects(:confirm).with('asdfasdf').returns(user)
end
it "logs in the user" do
put :password_reset, token: 'asdfasdf', password: 'newpassword'
session[:current_user_id].should be_present
end
it "doesn't log in the user when not approved" do
SiteSetting.expects(:must_approve_users?).returns(true)
put :password_reset, token: 'asdfasdf', password: 'newpassword'
session[:current_user_id].should be_blank
end
end
end
describe '.create' do
before do
@user = Fabricate.build(:user)
@user.password = "strongpassword"
Mothership.stubs(:register_nickname).returns([true, nil])
end
context 'when creating a non active user (unconfirmed email)' do
it 'should enqueue a signup email' do
Jobs.expects(:enqueue).with(:user_email, has_entries(type: :signup))
xhr :post, :create, :name => @user.name, :username => @user.username, :password => "strongpassword", :email => @user.email
end
it "doesn't send a welcome email" do
User.any_instance.expects(:enqueue_welcome_message).with('welcome_user').never
xhr :post, :create, :name => @user.name, :username => @user.username, :password => "strongpassword", :email => @user.email
end
end
context 'when creating an active user (confirmed email)' do
before do
User.any_instance.stubs(:active?).returns(true)
end
it 'should enqueue a signup email' do
User.any_instance.expects(:enqueue_welcome_message).with('welcome_user')
xhr :post, :create, :name => @user.name, :username => @user.username, :password => "strongpassword", :email => @user.email
end
it "should be logged in" do
User.any_instance.expects(:enqueue_welcome_message)
xhr :post, :create, :name => @user.name, :username => @user.username, :password => "strongpassword", :email => @user.email
session[:current_user_id].should be_present
end
it "returns true in the active part of the JSON" do
User.any_instance.expects(:enqueue_welcome_message)
xhr :post, :create, :name => @user.name, :username => @user.username, :password => "strongpassword", :email => @user.email
::JSON.parse(response.body)['active'].should == true
end
context 'when approving of users is required' do
before do
SiteSetting.expects(:must_approve_users).returns(true)
xhr :post, :create, :name => @user.name, :username => @user.username, :password => "strongpassword", :email => @user.email
end
it "doesn't log in the user" do
session[:current_user_id].should be_blank
end
it "doesn't return active in the JSON" do
::JSON.parse(response.body)['active'].should == false
end
end
end
context 'after success' do
before do
xhr :post, :create, :name => @user.name, :username => @user.username, :password => "strongpassword", :email => @user.email
end
it 'should succeed' do
should respond_with(:success)
end
it 'has the proper JSON' do
json = JSON::parse(response.body)
json["success"].should be_true
end
it 'should not result in an active account' do
User.where(username: @user.username).first.active.should be_false
end
end
end
context '.username' do
it 'raises an error when not logged in' do
lambda { xhr :put, :username, username: 'somename' }.should raise_error(Discourse::NotLoggedIn)
end
context 'while logged in' do
let!(:user) { log_in }
let(:new_username) { "#{user.username}1234" }
it 'raises an error without a new_username param' do
lambda { xhr :put, :username, username: user.username }.should raise_error(Discourse::InvalidParameters)
end
it 'raises an error when you don\'t have permission to change the user' do
Guardian.any_instance.expects(:can_edit?).with(user).returns(false)
xhr :put, :username, username: user.username, new_username: new_username
response.should be_forbidden
end
it 'raises an error when change_username fails' do
User.any_instance.expects(:change_username).with(new_username).returns(false)
lambda { xhr :put, :username, username: user.username, new_username: new_username }.should raise_error(Discourse::InvalidParameters)
end
it 'should succeed when the change_username returns true' do
User.any_instance.expects(:change_username).with(new_username).returns(true)
xhr :put, :username, username: user.username, new_username: new_username
response.should be_success
end
end
end
context '.check_username' do
before do
Mothership.stubs(:nickname_available?).returns([true, nil])
end
it 'raises an error without a username parameter' do
lambda { xhr :get, :check_username }.should raise_error(Discourse::InvalidParameters)
end
shared_examples_for 'when username is unavailable locally' do
it 'should return success' do
response.should be_success
end
it 'should return available as false in the JSON' do
::JSON.parse(response.body)['available'].should be_false
end
it 'should return a suggested username' do
::JSON.parse(response.body)['suggestion'].should be_present
end
end
shared_examples_for 'when username is available everywhere' do
it 'should return success' do
response.should be_success
end
it 'should return available in the JSON' do
::JSON.parse(response.body)['available'].should be_true
end
end
context 'when call_mothership is disabled' do
before do
SiteSetting.stubs(:call_mothership?).returns(false)
Mothership.expects(:nickname_available?).never
Mothership.expects(:nickname_match?).never
end
context 'available everywhere' do
before do
xhr :get, :check_username, username: 'BruceWayne'
end
it_should_behave_like 'when username is available everywhere'
end
context 'available locally but not globally' do
before do
xhr :get, :check_username, username: 'BruceWayne'
end
it_should_behave_like 'when username is available everywhere'
end
context 'unavailable locally but available globally' do
let!(:user) { Fabricate(:user) }
before do
xhr :get, :check_username, username: user.username
end
it_should_behave_like 'when username is unavailable locally'
end
context 'unavailable everywhere' do
let!(:user) { Fabricate(:user) }
before do
xhr :get, :check_username, username: user.username
end
it_should_behave_like 'when username is unavailable locally'
end
end
context 'when call_mothership is enabled' do
before do
SiteSetting.stubs(:call_mothership?).returns(true)
end
context 'available locally and globally' do
before do
Mothership.stubs(:nickname_available?).returns([true, nil])
Mothership.stubs(:nickname_match?).returns([false, true, nil]) # match = false, available = true, suggestion = nil
end
shared_examples_for 'check_username when nickname is available everywhere' do
it 'should return success' do
response.should be_success
end
it 'should return available in the JSON' do
::JSON.parse(response.body)['available'].should be_true
end
it 'should return global_match false in the JSON' do
::JSON.parse(response.body)['global_match'].should be_false
end
end
context 'and email is not given' do
before do
xhr :get, :check_username, username: 'BruceWayne'
end
it_should_behave_like 'check_username when nickname is available everywhere'
end
context 'and email is given' do
before do
xhr :get, :check_username, username: 'BruceWayne', email: 'brucie@gmail.com'
end
it_should_behave_like 'check_username when nickname is available everywhere'
end
end
shared_examples_for 'when email is needed to check nickname match' do
it 'should return success' do
response.should be_success
end
it 'should return available as false in the JSON' do
::JSON.parse(response.body)['available'].should be_false
end
it 'should not return a suggested username' do
::JSON.parse(response.body)['suggestion'].should_not be_present
end
end
context 'available locally but not globally' do
before do
Mothership.stubs(:nickname_available?).returns([false, 'suggestion'])
end
context 'email param is not given' do
before do
xhr :get, :check_username, username: 'BruceWayne'
end
it_should_behave_like 'when email is needed to check nickname match'
end
context 'email param is an empty string' do
before do
xhr :get, :check_username, username: 'BruceWayne', email: ''
end
it_should_behave_like 'when email is needed to check nickname match'
end
context 'email matches global nickname' do
before do
Mothership.stubs(:nickname_match?).returns([true, false, nil])
xhr :get, :check_username, username: 'BruceWayne', email: 'brucie@example.com'
end
it_should_behave_like 'when username is available everywhere'
it 'should indicate a global match' do
::JSON.parse(response.body)['global_match'].should be_true
end
end
context 'email does not match global nickname' do
before do
Mothership.stubs(:nickname_match?).returns([false, false, 'suggestion'])
xhr :get, :check_username, username: 'BruceWayne', email: 'brucie@example.com'
end
it_should_behave_like 'when username is unavailable locally'
it 'should not indicate a global match' do
::JSON.parse(response.body)['global_match'].should be_false
end
end
end
context 'unavailable locally and globally' do
let!(:user) { Fabricate(:user) }
before do
Mothership.stubs(:nickname_available?).returns([false, 'suggestion'])
xhr :get, :check_username, username: user.username
end
it_should_behave_like 'when username is unavailable locally'
end
context 'unavailable locally and available globally' do
let!(:user) { Fabricate(:user) }
before do
Mothership.stubs(:nickname_available?).returns([true, nil])
xhr :get, :check_username, username: user.username
end
it_should_behave_like 'when username is unavailable locally'
end
end
context 'when discourse_org_access_key is wrong' do
before do
SiteSetting.stubs(:call_mothership?).returns(true)
Mothership.stubs(:nickname_available?).raises(RestClient::Forbidden)
Mothership.stubs(:nickname_match?).raises(RestClient::Forbidden)
end
it 'should return an error message' do
xhr :get, :check_username, username: 'horsie'
json = JSON.parse(response.body)
json['errors'].should_not be_nil
json['errors'][0].should_not be_nil
end
end
end
describe '.invited' do
let(:user) { Fabricate(:user) }
it 'returns success' do
xhr :get, :invited, username: user.username
response.should be_success
end
end
describe '.update' do
context 'not logged in' do
it 'raises an error when not logged in' do
lambda { xhr :put, :update, username: 'somename' }.should raise_error(Discourse::NotLoggedIn)
end
end
context 'logged in' do
let!(:user) { log_in }
context 'without a token' do
it 'should ensure you can update the user' do
Guardian.any_instance.expects(:can_edit?).with(user).returns(false)
put :update, username: user.username
response.should be_forbidden
end
context 'as a user who can edit the user' do
before do
put :update, username: user.username, bio_raw: 'brand new bio'
user.reload
end
it 'updates the user' do
user.bio_raw.should == 'brand new bio'
end
it 'returns json success' do
response.should be_success
end
end
end
end
end
end