2015-10-11 17:41:23 +08:00
|
|
|
require 'rails_helper'
|
2013-03-26 09:04:28 +08:00
|
|
|
|
2013-11-11 07:50:48 +08:00
|
|
|
describe TopicsController do
|
|
|
|
before do
|
|
|
|
TopicUser.stubs(:track_visit!)
|
|
|
|
end
|
|
|
|
|
|
|
|
let :topic do
|
|
|
|
Fabricate(:post).topic
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_referer(ref)
|
|
|
|
request.env['HTTP_REFERER'] = ref
|
|
|
|
end
|
|
|
|
|
2016-02-07 03:49:39 +08:00
|
|
|
def set_accept_language(locale)
|
|
|
|
request.env['HTTP_ACCEPT_LANGUAGE'] = locale
|
|
|
|
end
|
|
|
|
|
2017-05-13 00:41:26 +08:00
|
|
|
describe "themes" do
|
2017-05-16 00:48:08 +08:00
|
|
|
let :theme do
|
|
|
|
Theme.create!(user_id: -1, name: 'bob', user_selectable: true)
|
|
|
|
end
|
|
|
|
|
|
|
|
let :theme2 do
|
|
|
|
Theme.create!(user_id: -1, name: 'bobbob', user_selectable: true)
|
|
|
|
end
|
|
|
|
|
2017-05-13 00:41:26 +08:00
|
|
|
it "selects the theme the user has selected" do
|
|
|
|
user = log_in
|
|
|
|
user.user_option.update_columns(theme_key: theme.key)
|
|
|
|
|
|
|
|
get :show, id: 666
|
|
|
|
expect(controller.theme_key).to eq(theme.key)
|
|
|
|
|
|
|
|
theme.update_columns(user_selectable: false)
|
|
|
|
|
|
|
|
get :show, id: 666
|
|
|
|
expect(controller.theme_key).not_to eq(theme.key)
|
|
|
|
end
|
2017-05-16 00:48:08 +08:00
|
|
|
|
|
|
|
it "can be overridden with a cookie" do
|
|
|
|
user = log_in
|
|
|
|
user.user_option.update_columns(theme_key: theme.key)
|
|
|
|
|
|
|
|
cookies['theme_key'] = "#{theme2.key},#{user.user_option.theme_key_seq}"
|
|
|
|
|
|
|
|
get :show, id: 666
|
|
|
|
expect(controller.theme_key).to eq(theme2.key)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
it "cookie can fail back to user if out of sync" do
|
|
|
|
user = log_in
|
|
|
|
user.user_option.update_columns(theme_key: theme.key)
|
|
|
|
cookies['theme_key'] = "#{theme2.key},#{user.user_option.theme_key_seq-1}"
|
|
|
|
|
|
|
|
get :show, id: 666
|
|
|
|
expect(controller.theme_key).to eq(theme.key)
|
|
|
|
end
|
2017-05-13 00:41:26 +08:00
|
|
|
end
|
|
|
|
|
2013-11-11 07:50:48 +08:00
|
|
|
it "doesn't store an incoming link when there's no referer" do
|
2015-01-10 01:04:02 +08:00
|
|
|
expect {
|
2013-11-11 07:50:48 +08:00
|
|
|
get :show, id: topic.id
|
2015-01-10 01:04:02 +08:00
|
|
|
}.not_to change(IncomingLink, :count)
|
2013-11-11 07:50:48 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
it "doesn't raise an error on a very long link" do
|
|
|
|
set_referer("http://#{'a' * 2000}.com")
|
2015-01-10 01:04:02 +08:00
|
|
|
expect { get :show, {id: topic.id} }.not_to raise_error
|
2013-11-11 07:50:48 +08:00
|
|
|
end
|
|
|
|
|
2014-02-21 06:02:26 +08:00
|
|
|
describe "has_escaped_fragment?" do
|
|
|
|
render_views
|
|
|
|
|
|
|
|
context "when the SiteSetting is disabled" do
|
|
|
|
|
|
|
|
it "uses the application layout even with an escaped fragment param" do
|
2017-05-13 00:41:26 +08:00
|
|
|
SiteSetting.enable_escaped_fragments = false
|
2016-02-07 03:49:39 +08:00
|
|
|
get :show, {'topic_id' => topic.id, 'slug' => topic.slug, '_escaped_fragment_' => 'true'}
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response).to render_template(layout: 'application')
|
2014-02-21 06:02:26 +08:00
|
|
|
assert_select "meta[name=fragment]", false, "it doesn't have the meta tag"
|
|
|
|
end
|
2017-05-13 00:41:26 +08:00
|
|
|
|
2014-02-21 06:02:26 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
context "when the SiteSetting is enabled" do
|
|
|
|
before do
|
2017-05-13 00:41:26 +08:00
|
|
|
SiteSetting.enable_escaped_fragments = true
|
2014-02-21 06:02:26 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
it "uses the application layout when there's no param" do
|
2014-07-29 14:35:15 +08:00
|
|
|
get :show, topic_id: topic.id, slug: topic.slug
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response).to render_template(layout: 'application')
|
2014-02-21 06:02:26 +08:00
|
|
|
assert_select "meta[name=fragment]", true, "it has the meta tag"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "uses the crawler layout when there's an _escaped_fragment_ param" do
|
2016-02-07 03:49:39 +08:00
|
|
|
get :show, topic_id: topic.id, slug: topic.slug, _escaped_fragment_: 'true'
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response).to render_template(layout: 'crawler')
|
2014-02-21 06:02:26 +08:00
|
|
|
assert_select "meta[name=fragment]", false, "it doesn't have the meta tag"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "crawler" do
|
|
|
|
render_views
|
|
|
|
|
|
|
|
context "when not a crawler" do
|
|
|
|
it "renders with the application layout" do
|
2014-07-29 14:35:15 +08:00
|
|
|
get :show, topic_id: topic.id, slug: topic.slug
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response).to render_template(layout: 'application')
|
2014-02-21 06:02:26 +08:00
|
|
|
assert_select "meta[name=fragment]", true, "it has the meta tag"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when a crawler" do
|
|
|
|
it "renders with the crawler layout" do
|
2016-03-17 12:46:16 +08:00
|
|
|
request.env["HTTP_USER_AGENT"] = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
2014-07-29 14:35:15 +08:00
|
|
|
get :show, topic_id: topic.id, slug: topic.slug
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response).to render_template(layout: 'crawler')
|
2014-02-21 06:02:26 +08:00
|
|
|
assert_select "meta[name=fragment]", false, "it doesn't have the meta tag"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2016-08-08 07:01:23 +08:00
|
|
|
describe "print" do
|
|
|
|
render_views
|
|
|
|
|
|
|
|
context "when the SiteSetting is enabled" do
|
|
|
|
it "uses the application layout when there's no param" do
|
|
|
|
get :show, topic_id: topic.id, slug: topic.slug
|
|
|
|
expect(response).to render_template(layout: 'application')
|
|
|
|
assert_select "meta[name=fragment]", true, "it has the meta tag"
|
|
|
|
end
|
|
|
|
|
|
|
|
it "uses the crawler layout when there's an print param" do
|
|
|
|
get :show, topic_id: topic.id, slug: topic.slug, print: 'true'
|
|
|
|
expect(response).to render_template(layout: 'crawler')
|
|
|
|
assert_select "meta[name=fragment]", false, "it doesn't have the meta tag"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-15 16:29:35 +08:00
|
|
|
describe 'clear_notifications' do
|
|
|
|
it 'correctly clears notifications if specified via cookie' do
|
|
|
|
notification = Fabricate(:notification)
|
|
|
|
log_in_user(notification.user)
|
|
|
|
|
|
|
|
request.cookies['cn'] = "2828,100,#{notification.id}"
|
|
|
|
|
|
|
|
get :show, {topic_id: 100}
|
|
|
|
|
|
|
|
expect(response.cookies['cn']).to eq nil
|
|
|
|
|
|
|
|
notification.reload
|
|
|
|
expect(notification.read).to eq true
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'correctly clears notifications if specified via header' do
|
|
|
|
notification = Fabricate(:notification)
|
|
|
|
log_in_user(notification.user)
|
|
|
|
|
|
|
|
request.headers['Discourse-Clear-Notifications'] = "2828,100,#{notification.id}"
|
|
|
|
|
|
|
|
get :show, {topic_id: 100}
|
|
|
|
|
|
|
|
notification.reload
|
|
|
|
expect(notification.read).to eq true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-07 03:49:39 +08:00
|
|
|
describe "set_locale" do
|
|
|
|
context "allow_user_locale disabled" do
|
|
|
|
context "accept-language header differs from default locale" do
|
|
|
|
before do
|
|
|
|
SiteSetting.stubs(:allow_user_locale).returns(false)
|
|
|
|
SiteSetting.stubs(:default_locale).returns("en")
|
|
|
|
set_accept_language("fr")
|
|
|
|
end
|
|
|
|
|
|
|
|
context "with an anonymous user" do
|
|
|
|
it "uses the default locale" do
|
|
|
|
get :show, {topic_id: topic.id}
|
|
|
|
|
|
|
|
expect(I18n.locale).to eq(:en)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "with a logged in user" do
|
|
|
|
it "it uses the default locale" do
|
|
|
|
user = Fabricate(:user, locale: :fr)
|
|
|
|
log_in_user(user)
|
|
|
|
|
|
|
|
get :show, {topic_id: topic.id}
|
|
|
|
|
|
|
|
expect(I18n.locale).to eq(:en)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-03-15 07:18:19 +08:00
|
|
|
context "set_locale_from_accept_language_header enabled" do
|
2016-02-07 03:49:39 +08:00
|
|
|
context "accept-language header differs from default locale" do
|
|
|
|
before do
|
|
|
|
SiteSetting.stubs(:allow_user_locale).returns(true)
|
2016-03-15 07:18:19 +08:00
|
|
|
SiteSetting.stubs(:set_locale_from_accept_language_header).returns(true)
|
2016-02-07 03:49:39 +08:00
|
|
|
SiteSetting.stubs(:default_locale).returns("en")
|
|
|
|
set_accept_language("fr")
|
|
|
|
end
|
2014-02-08 11:24:10 +08:00
|
|
|
|
2016-02-07 03:49:39 +08:00
|
|
|
context "with an anonymous user" do
|
|
|
|
it "uses the locale from the headers" do
|
|
|
|
get :show, {topic_id: topic.id}
|
2014-02-08 11:24:10 +08:00
|
|
|
|
2016-02-07 03:49:39 +08:00
|
|
|
expect(I18n.locale).to eq(:fr)
|
|
|
|
end
|
|
|
|
end
|
2014-02-08 11:24:10 +08:00
|
|
|
|
2016-02-07 03:49:39 +08:00
|
|
|
context "with a logged in user" do
|
|
|
|
it "uses the user's preferred locale" do
|
|
|
|
user = Fabricate(:user, locale: :fr)
|
|
|
|
log_in_user(user)
|
2014-02-09 09:35:46 +08:00
|
|
|
|
2016-02-07 03:49:39 +08:00
|
|
|
get :show, {topic_id: topic.id}
|
2014-02-09 09:35:46 +08:00
|
|
|
|
2016-02-07 03:49:39 +08:00
|
|
|
expect(I18n.locale).to eq(:fr)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "the preferred locale includes a region" do
|
|
|
|
it "returns the locale and region separated by an underscore" do
|
2016-03-15 07:18:19 +08:00
|
|
|
SiteSetting.stubs(:set_locale_from_accept_language_header).returns(true)
|
2016-02-07 03:49:39 +08:00
|
|
|
SiteSetting.stubs(:default_locale).returns("en")
|
|
|
|
set_accept_language("zh-CN")
|
|
|
|
|
|
|
|
get :show, {topic_id: topic.id}
|
|
|
|
|
|
|
|
expect(I18n.locale).to eq(:zh_CN)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'accept-language header is not set' do
|
|
|
|
it 'uses the site default locale' do
|
|
|
|
SiteSetting.stubs(:allow_user_locale).returns(true)
|
|
|
|
SiteSetting.stubs(:default_locale).returns('en')
|
|
|
|
set_accept_language('')
|
2014-02-09 09:35:46 +08:00
|
|
|
|
2016-02-07 03:49:39 +08:00
|
|
|
get :show, {topic_id: topic.id}
|
|
|
|
|
|
|
|
expect(I18n.locale).to eq(:en)
|
|
|
|
end
|
|
|
|
end
|
2014-02-09 09:35:46 +08:00
|
|
|
end
|
2014-02-08 11:24:10 +08:00
|
|
|
end
|
|
|
|
|
2015-04-25 02:32:18 +08:00
|
|
|
describe "read only header" do
|
|
|
|
it "returns no read only header by default" do
|
|
|
|
get :show, {topic_id: topic.id}
|
|
|
|
expect(response.headers['Discourse-Readonly']).to eq(nil)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns a readonly header if the site is read only" do
|
2015-04-29 23:49:58 +08:00
|
|
|
Discourse.received_readonly!
|
2015-04-25 02:32:18 +08:00
|
|
|
get :show, {topic_id: topic.id}
|
|
|
|
expect(response.headers['Discourse-Readonly']).to eq('true')
|
|
|
|
end
|
|
|
|
end
|
2013-11-11 07:50:48 +08:00
|
|
|
end
|
|
|
|
|
2013-04-30 08:34:19 +08:00
|
|
|
describe 'api' do
|
2014-05-23 06:42:58 +08:00
|
|
|
|
|
|
|
before do
|
|
|
|
ActionController::Base.allow_forgery_protection = true
|
|
|
|
end
|
|
|
|
|
|
|
|
after do
|
|
|
|
ActionController::Base.allow_forgery_protection = false
|
|
|
|
end
|
|
|
|
|
2013-03-26 09:04:28 +08:00
|
|
|
describe PostsController do
|
|
|
|
let(:user) do
|
|
|
|
Fabricate(:user)
|
|
|
|
end
|
|
|
|
|
2013-04-30 08:34:19 +08:00
|
|
|
let(:post) do
|
2013-03-26 09:04:28 +08:00
|
|
|
Fabricate(:post)
|
|
|
|
end
|
2013-04-30 08:34:19 +08:00
|
|
|
|
2013-10-23 03:53:08 +08:00
|
|
|
let(:api_key) { user.generate_api_key(user) }
|
|
|
|
let(:master_key) { ApiKey.create_master_key }
|
|
|
|
|
2013-03-26 09:04:28 +08:00
|
|
|
# choosing an arbitrarily easy to mock trusted activity
|
|
|
|
it 'allows users with api key to bookmark posts' do
|
2013-04-30 08:34:19 +08:00
|
|
|
PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).once
|
2013-10-23 03:53:08 +08:00
|
|
|
put :bookmark, bookmarked: "true", post_id: post.id, api_key: api_key.key, format: :json
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response).to be_success
|
2013-10-23 23:05:49 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'raises an error with a user key that does not match an optionally specified username' do
|
|
|
|
PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).never
|
|
|
|
put :bookmark, bookmarked: "true", post_id: post.id, api_key: api_key.key, api_username: 'made_up', format: :json
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response).not_to be_success
|
2013-10-23 03:53:08 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'allows users with a master api key to bookmark posts' do
|
|
|
|
PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).once
|
|
|
|
put :bookmark, bookmarked: "true", post_id: post.id, api_key: master_key.key, api_username: user.username, format: :json
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response).to be_success
|
2013-03-26 09:04:28 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'disallows phonies to bookmark posts' do
|
2013-04-30 08:34:19 +08:00
|
|
|
PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).never
|
2014-05-23 06:13:25 +08:00
|
|
|
put :bookmark, bookmarked: "true", post_id: post.id, api_key: SecureRandom.hex(32), api_username: user.username, format: :json
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response.code.to_i).to eq(403)
|
2013-03-26 09:04:28 +08:00
|
|
|
end
|
2013-04-30 08:34:19 +08:00
|
|
|
|
2013-03-26 09:04:28 +08:00
|
|
|
it 'disallows blank api' do
|
2013-04-30 08:34:19 +08:00
|
|
|
PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).never
|
2014-05-23 06:13:25 +08:00
|
|
|
put :bookmark, bookmarked: "true", post_id: post.id, api_key: "", api_username: user.username, format: :json
|
2015-01-10 01:04:02 +08:00
|
|
|
expect(response.code.to_i).to eq(403)
|
2013-03-26 09:04:28 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|