DEV: Extend specs coverage for non-admin access to admin endpoints (#18833)
Replace base controller class inheritance specs with explicit specs for non-staff and moderator access to admin resources
This commit is contained in:
parent
612ab8710a
commit
52be5b3782
|
@ -1,19 +1,65 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::AdminController do
|
||||
describe '#index' do
|
||||
it "needs you to be logged in" do
|
||||
get "/admin.json"
|
||||
expect(response.status).to eq(404)
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
|
||||
describe "#index" do
|
||||
context "when unauthenticated" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
it "should return the right response if user isn't a staff" do
|
||||
sign_in(Fabricate(:user))
|
||||
get "/admin", params: { api_key: 'asdiasiduga' }
|
||||
expect(response.status).to eq(404)
|
||||
context "when authenticated" do
|
||||
context "as an admin" do
|
||||
it "permits access with a 200 response" do
|
||||
sign_in(admin)
|
||||
get "/admin.json"
|
||||
|
||||
get "/admin"
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
context "as a non-admin" do
|
||||
it "denies access with a 403 response" do
|
||||
sign_in(moderator)
|
||||
get "/admin.json"
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("invalid_access"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is admin with api key" do
|
||||
it "permits access with a 200 response" do
|
||||
api_key = Fabricate(:api_key, user: admin)
|
||||
|
||||
get "/admin.json", headers: {
|
||||
HTTP_API_KEY: api_key.key,
|
||||
HTTP_API_USERNAME: admin.username
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is a non-admin with api key" do
|
||||
it "denies access with a 403 response" do
|
||||
api_key = Fabricate(:api_key, user: moderator)
|
||||
|
||||
get "/admin.json", headers: {
|
||||
HTTP_API_KEY: api_key.key,
|
||||
HTTP_API_USERNAME: moderator.username
|
||||
}
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("invalid_access"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,47 +1,73 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::ApiController do
|
||||
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::ApiController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
fab!(:key1, refind: false) { Fabricate(:api_key, description: "my key") }
|
||||
fab!(:key2, refind: false) { Fabricate(:api_key, user: admin) }
|
||||
fab!(:key3, refind: false) { Fabricate(:api_key, user: admin) }
|
||||
|
||||
context "as an admin" do
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
describe '#index' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
describe '#index' do
|
||||
it "succeeds" do
|
||||
it "returns keys successfully" do
|
||||
get "/admin/api/keys.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["keys"].length).to eq(3)
|
||||
end
|
||||
|
||||
it "can paginate results" do
|
||||
get "/admin/api/keys.json?offset=0&limit=2"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["keys"].map { |x| x["id"] }).to contain_exactly(key3.id, key2.id)
|
||||
|
||||
get "/admin/api/keys.json?offset=1&limit=2"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["keys"].map { |x| x["id"] }).to contain_exactly(key2.id, key1.id)
|
||||
|
||||
get "/admin/api/keys.json?offset=2&limit=2"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["keys"].map { |x| x["id"] }).to contain_exactly(key1.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#show' do
|
||||
it "succeeds" do
|
||||
shared_examples "keys inaccessible" do
|
||||
it "denies keys access with a 404 response" do
|
||||
get "/admin/api/keys.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(response.parsed_body["keys"]).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "keys inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "keys inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#show' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns key successfully" do
|
||||
get "/admin/api/keys/#{key1.id}.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
data = response.parsed_body["key"]
|
||||
expect(data["id"]).to eq(key1.id)
|
||||
|
@ -51,7 +77,33 @@ RSpec.describe Admin::ApiController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
shared_examples "key inaccessible" do
|
||||
it "denies key access with a 404 response" do
|
||||
get "/admin/api/keys/#{key1.id}.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(response.parsed_body["key"]).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "key inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "key inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "allows updating the description" do
|
||||
original_key = key1.key
|
||||
|
||||
|
@ -82,7 +134,44 @@ RSpec.describe Admin::ApiController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
shared_examples "key update not allowed" do
|
||||
it "prevents key updates with a 404 response" do
|
||||
key1.reload
|
||||
original_key = key1.key
|
||||
original_description = key1.description
|
||||
|
||||
put "/admin/api/keys/#{key1.id}.json", params: {
|
||||
key: {
|
||||
description: "my new description",
|
||||
key: "overridekey"
|
||||
}
|
||||
}
|
||||
|
||||
key1.reload
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(key1.description).to eq(original_description)
|
||||
expect(key1.key).to eq(original_key)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "key update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "key update not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "works" do
|
||||
expect(ApiKey.exists?(key1.id)).to eq(true)
|
||||
|
||||
|
@ -96,7 +185,35 @@ RSpec.describe Admin::ApiController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
shared_examples "key deletion not allowed" do
|
||||
it "prevents key deletion with a 404 response" do
|
||||
expect(ApiKey.exists?(key1.id)).to eq(true)
|
||||
|
||||
delete "/admin/api/keys/#{key1.id}.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(ApiKey.exists?(key1.id)).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "key deletion not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "key deletion not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "can create a master key" do
|
||||
post "/admin/api/keys.json", params: {
|
||||
key: {
|
||||
|
@ -207,7 +324,37 @@ RSpec.describe Admin::ApiController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#revoke and #undo_revoke" do
|
||||
shared_examples "key creation not allowed" do
|
||||
it "prevents key creation with a 404 response" do
|
||||
post "/admin/api/keys.json", params: {
|
||||
key: {
|
||||
description: "master key description"
|
||||
}
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(response.parsed_body["key"]).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "key creation not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "key creation not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#revoke and #undo_revoke" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "works correctly" do
|
||||
post "/admin/api/keys/#{key1.id}/revoke.json"
|
||||
expect(response.status).to eq 200
|
||||
|
@ -229,37 +376,79 @@ RSpec.describe Admin::ApiController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#scopes' do
|
||||
it 'includes scopes' do
|
||||
get '/admin/api/keys/scopes.json'
|
||||
shared_examples "key revocation/revocation undoing not allowed" do
|
||||
it "prevents revoking/un-revoking key with a 404 response" do
|
||||
key1.reload
|
||||
post "/admin/api/keys/#{key1.id}/revoke.json"
|
||||
|
||||
scopes = response.parsed_body['scopes']
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(key1.revoked_at).to eq(nil)
|
||||
|
||||
expect(scopes.keys).to contain_exactly('topics', 'users', 'email', 'posts', 'uploads', 'global', 'badges', 'categories', 'wordpress')
|
||||
post "/admin/api/keys/#{key1.id}/undo-revoke.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(key1.revoked_at).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "key revocation/revocation undoing not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "key revocation/revocation undoing not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
context "as a moderator" do
|
||||
before do
|
||||
sign_in(Fabricate(:moderator))
|
||||
describe "#scopes" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "includes scopes" do
|
||||
get "/admin/api/keys/scopes.json"
|
||||
|
||||
scopes = response.parsed_body["scopes"]
|
||||
|
||||
expect(scopes.keys).to contain_exactly(
|
||||
"topics",
|
||||
"users",
|
||||
"email",
|
||||
"posts",
|
||||
"uploads",
|
||||
"global",
|
||||
"badges",
|
||||
"categories",
|
||||
"wordpress"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "doesn't allow access" do
|
||||
get "/admin/api/keys.json"
|
||||
expect(response.status).to eq(404)
|
||||
shared_examples "key scopes inaccessible" do
|
||||
it "denies key scopes access with a 404 response" do
|
||||
get "/admin/api/keys/scopes.json"
|
||||
|
||||
get "/admin/api/key/#{key1.id}.json"
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(response.parsed_body["scopes"]).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
post "/admin/api/keys.json", params: {
|
||||
key: {
|
||||
description: "master key description"
|
||||
}
|
||||
}
|
||||
expect(response.status).to eq(404)
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
expect(ApiKey.count).to eq(3)
|
||||
include_examples "key scopes inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "key scopes inaccessible"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,22 +1,47 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::BadgesController do
|
||||
context "while logged in as an admin" do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:badge) { Fabricate(:badge) }
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user, email: 'user1@test.com', username: 'username1') }
|
||||
fab!(:badge) { Fabricate(:badge) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
describe '#index' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
describe '#index' do
|
||||
it 'returns badge index' do
|
||||
it "returns badge index" do
|
||||
get "/admin/badges.json"
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#preview' do
|
||||
shared_examples "badges inaccessible" do
|
||||
it "denies access to badges with a 404 response" do
|
||||
get "/admin/badges.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "badges inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "badges inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#preview' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'allows preview enable_badge_sql is enabled' do
|
||||
SiteSetting.enable_badge_sql = true
|
||||
|
||||
|
@ -39,7 +64,36 @@ RSpec.describe Admin::BadgesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
shared_examples "badge preview inaccessible" do
|
||||
it "denies access to badge preview with a 404 response" do
|
||||
SiteSetting.enable_badge_sql = true
|
||||
|
||||
post "/admin/badges/preview.json", params: {
|
||||
sql: 'select id as user_id, created_at granted_at from users'
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "badge preview inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "badge preview inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'can create badges correctly' do
|
||||
SiteSetting.enable_badge_sql = true
|
||||
|
||||
|
@ -56,7 +110,36 @@ RSpec.describe Admin::BadgesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#save_badge_groupings' do
|
||||
shared_examples "badge creation not allowed" do
|
||||
it "prevents badge creation with a 404 response" do
|
||||
SiteSetting.enable_badge_sql = true
|
||||
|
||||
post "/admin/badges.json", params: {
|
||||
name: 'test', query: 'select 1 as user_id, null as granted_at', badge_type_id: 1
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "badge creation not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "badge creation not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#save_badge_groupings' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'can save badge groupings' do
|
||||
groupings = BadgeGrouping.all.order(:position).to_a
|
||||
groupings << BadgeGrouping.new(name: 'Test 1')
|
||||
|
@ -78,7 +161,41 @@ RSpec.describe Admin::BadgesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#badge_types' do
|
||||
shared_examples "badge grouping creation not allowed" do
|
||||
it "prevents creation of badge groupings with a 404 response" do
|
||||
groupings = BadgeGrouping.all.order(:position).to_a
|
||||
groupings << BadgeGrouping.new(name: "Test 1")
|
||||
groupings << BadgeGrouping.new(name: "Test 2")
|
||||
|
||||
groupings.shuffle!
|
||||
|
||||
names = groupings.map { |g| g.name }
|
||||
ids = groupings.map { |g| g.id.to_s }
|
||||
|
||||
post "/admin/badges/badge_groupings.json", params: { ids: ids, names: names }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "badge grouping creation not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "badge grouping creation not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#badge_types' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'returns JSON' do
|
||||
get "/admin/badges/types.json"
|
||||
|
||||
|
@ -87,7 +204,32 @@ RSpec.describe Admin::BadgesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
shared_examples "badge types inaccessible" do
|
||||
it "denies access to badge types with a 404 response" do
|
||||
get "/admin/badges/types.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "badge types inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "badge types inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'deletes the badge' do
|
||||
delete "/admin/badges/#{badge.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
@ -96,7 +238,33 @@ RSpec.describe Admin::BadgesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
shared_examples "badge deletion not allowed" do
|
||||
it "prevents deletion of badges with a 404 response" do
|
||||
delete "/admin/badges/#{badge.id}.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(Badge.where(id: badge.id).exists?).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "badge deletion not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "badge deletion not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'does not update the name of system badges' do
|
||||
editor_badge = Badge.find(Badge::Editor)
|
||||
editor_badge_name = editor_badge.name
|
||||
|
@ -180,8 +348,49 @@ RSpec.describe Admin::BadgesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#mass_award' do
|
||||
fab!(:user) { Fabricate(:user, email: 'user1@test.com', username: 'username1') }
|
||||
shared_examples "badge update not allowed" do
|
||||
it "prevents badge update with a 404 response" do
|
||||
SiteSetting.enable_badge_sql = true
|
||||
|
||||
sql = "select id user_id, created_at granted_at from users"
|
||||
image = Fabricate(:upload)
|
||||
|
||||
put "/admin/badges/#{badge.id}.json", params: {
|
||||
name: "123456",
|
||||
query: sql,
|
||||
badge_type_id: badge.badge_type_id,
|
||||
allow_title: false,
|
||||
multiple_grant: false,
|
||||
enabled: true,
|
||||
image_upload_id: image.id,
|
||||
icon: "fa-rocket",
|
||||
}
|
||||
|
||||
badge.reload
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(badge.name).not_to eq('123456')
|
||||
expect(badge.query).not_to eq(sql)
|
||||
expect(badge.icon).not_to eq("fa-rocket")
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "badge update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "badge update not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#mass_award' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'does nothing when there is no file' do
|
||||
post "/admin/badges/award/#{badge.id}.json", params: { file: '' }
|
||||
|
@ -359,5 +568,29 @@ RSpec.describe Admin::BadgesController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "mass badge award not allowed" do
|
||||
it "prevents mass badge award with a 404 response" do
|
||||
file = file_from_fixtures('user_emails.csv', 'csv')
|
||||
|
||||
post "/admin/badges/award/#{badge.id}.json", params: { file: fixture_file_upload(file) }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(UserBadge.where(user: user, badge: badge).count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "mass badge award not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "mass badge award not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,26 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::ColorSchemesController do
|
||||
it "is a subclass of AdminController" do
|
||||
expect(described_class < Admin::AdminController).to eq(true)
|
||||
end
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
context "while logged in as an admin" do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
let(:valid_params) { { color_scheme: {
|
||||
name: 'Such Design',
|
||||
colors: [
|
||||
{ name: 'primary', hex: 'FFBB00' },
|
||||
{ name: 'secondary', hex: '888888' }
|
||||
]
|
||||
}
|
||||
} }
|
||||
let(:valid_params) { { color_scheme: {
|
||||
name: 'Such Design',
|
||||
colors: [
|
||||
{ name: 'primary', hex: 'FFBB00' },
|
||||
{ name: 'secondary', hex: '888888' }
|
||||
]
|
||||
}
|
||||
} }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
describe "#index" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
describe "#index" do
|
||||
it "returns JSON" do
|
||||
scheme_name = Fabricate(:color_scheme).name
|
||||
get "/admin/color_schemes.json"
|
||||
|
@ -36,7 +33,32 @@ RSpec.describe Admin::ColorSchemesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
shared_examples "color schemes inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/color_schemes.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "color schemes inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "color schemes inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns JSON" do
|
||||
post "/admin/color_schemes.json", params: valid_params
|
||||
|
||||
|
@ -55,8 +77,38 @@ RSpec.describe Admin::ColorSchemesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
fab!(:existing) { Fabricate(:color_scheme) }
|
||||
shared_examples "color scheme creation not allowed" do
|
||||
it "prevents creation with a 404 response" do
|
||||
params = valid_params
|
||||
params[:color_scheme][:colors][0][:hex] = 'cool color please'
|
||||
|
||||
expect do
|
||||
post "/admin/color_schemes.json", params: valid_params
|
||||
end.not_to change { ColorScheme.count }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "color scheme creation not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "color scheme creation not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
fab!(:existing) { Fabricate(:color_scheme) }
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns success" do
|
||||
put "/admin/color_schemes/#{existing.id}.json", params: valid_params
|
||||
|
@ -84,8 +136,33 @@ RSpec.describe Admin::ColorSchemesController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
fab!(:existing) { Fabricate(:color_scheme) }
|
||||
shared_examples "color scheme update not allowed" do
|
||||
it "prevents update with a 404 response" do
|
||||
put "/admin/color_schemes/#{existing.id}.json", params: valid_params
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "color scheme update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "color scheme update not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
fab!(:existing) { Fabricate(:color_scheme) }
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns success" do
|
||||
expect {
|
||||
|
@ -94,5 +171,26 @@ RSpec.describe Admin::ColorSchemesController do
|
|||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "color scheme deletion not allowed" do
|
||||
it "prevents deletion with a 404 response" do
|
||||
delete "/admin/color_schemes/#{existing.id}.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "color scheme deletion not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "color scheme deletion not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,60 +1,116 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::DashboardController do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
AdminDashboardData.stubs(:fetch_cached_stats).returns(reports: [])
|
||||
Jobs::VersionCheck.any_instance.stubs(:execute).returns(true)
|
||||
end
|
||||
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::DashboardController < Admin::StaffController).to eq(true)
|
||||
def populate_new_features
|
||||
sample_features = [
|
||||
{
|
||||
"id" => "1",
|
||||
"emoji" => "🤾",
|
||||
"title" => "Cool Beans",
|
||||
"description" => "Now beans are included",
|
||||
"created_at" => Time.zone.now - 40.minutes
|
||||
},
|
||||
{
|
||||
"id" => "2",
|
||||
"emoji" => "🙈",
|
||||
"title" => "Fancy Legumes",
|
||||
"description" => "Legumes too!",
|
||||
"created_at" => Time.zone.now - 20.minutes
|
||||
}
|
||||
]
|
||||
|
||||
Discourse.redis.set('new_features', MultiJson.dump(sample_features))
|
||||
end
|
||||
|
||||
context 'while logged in as an admin' do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
describe '#index' do
|
||||
shared_examples "version info present" do
|
||||
it "returns discourse version info" do
|
||||
get "/admin/dashboard.json"
|
||||
|
||||
def populate_new_features
|
||||
sample_features = [
|
||||
{ "id" => "1", "emoji" => "🤾", "title" => "Cool Beans", "description" => "Now beans are included", "created_at" => Time.zone.now - 40.minutes },
|
||||
{ "id" => "2", "emoji" => "🙈", "title" => "Fancy Legumes", "description" => "Legumes too!", "created_at" => Time.zone.now - 20.minutes }
|
||||
]
|
||||
|
||||
Discourse.redis.set('new_features', MultiJson.dump(sample_features))
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["version_check"]).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
shared_examples "version info absent" do
|
||||
before do
|
||||
SiteSetting.version_checks = false
|
||||
end
|
||||
|
||||
it "does not return discourse version info" do
|
||||
get "/admin/dashboard.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["version_check"]).not_to be_present
|
||||
end
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
context 'when version checking is enabled' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
context "when version checking is enabled" do
|
||||
before do
|
||||
SiteSetting.version_checks = true
|
||||
end
|
||||
|
||||
it 'returns discourse version info' do
|
||||
get "/admin/dashboard.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body['version_check']).to be_present
|
||||
end
|
||||
include_examples "version info present"
|
||||
end
|
||||
|
||||
context 'when version checking is disabled' do
|
||||
context "when version checking is disabled" do
|
||||
before do
|
||||
SiteSetting.version_checks = false
|
||||
end
|
||||
|
||||
it 'does not return discourse version info' do
|
||||
get "/admin/dashboard.json"
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json['version_check']).not_to be_present
|
||||
end
|
||||
include_examples "version info absent"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#problems' do
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
context "when version checking is enabled" do
|
||||
before do
|
||||
SiteSetting.version_checks = true
|
||||
end
|
||||
|
||||
include_examples "version info present"
|
||||
end
|
||||
|
||||
context "when version checking is disabled" do
|
||||
before do
|
||||
SiteSetting.version_checks = false
|
||||
end
|
||||
|
||||
include_examples "version info absent"
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/dashboard.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#problems' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
context 'when there are no problems' do
|
||||
before do
|
||||
AdminDashboardData.stubs(:fetch_problems).returns([])
|
||||
|
@ -85,8 +141,40 @@ RSpec.describe Admin::DashboardController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#new_features' do
|
||||
context "when logged in as a moderator" do
|
||||
before do
|
||||
sign_in(moderator)
|
||||
AdminDashboardData
|
||||
.stubs(:fetch_problems)
|
||||
.returns(['Not enough awesome', 'Too much sass'])
|
||||
end
|
||||
|
||||
it 'returns a list of problems' do
|
||||
get "/admin/dashboard/problems.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json['problems'].size).to eq(2)
|
||||
expect(json['problems']).to contain_exactly('Not enough awesome', 'Too much sass')
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/dashboard/problems.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#new_features' do
|
||||
context "when logged in as an admin" do
|
||||
before do
|
||||
sign_in(admin)
|
||||
Discourse.redis.del "new_features_last_seen_user_#{admin.id}"
|
||||
Discourse.redis.del "new_features"
|
||||
end
|
||||
|
@ -131,7 +219,39 @@ RSpec.describe Admin::DashboardController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#mark_new_features_as_seen' do
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
it 'includes new features when available' do
|
||||
populate_new_features
|
||||
|
||||
get "/admin/dashboard/new-features.json"
|
||||
|
||||
json = response.parsed_body
|
||||
|
||||
expect(json['new_features'].length).to eq(2)
|
||||
expect(json['new_features'][0]["emoji"]).to eq("🙈")
|
||||
expect(json['new_features'][0]["title"]).to eq("Fancy Legumes")
|
||||
expect(json['has_unseen_features']).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/dashboard/new-features.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#mark_new_features_as_seen' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'resets last seen for a given user' do
|
||||
populate_new_features
|
||||
put "/admin/dashboard/mark-new-features-as-seen.json"
|
||||
|
@ -141,5 +261,30 @@ RSpec.describe Admin::DashboardController do
|
|||
expect(DiscourseUpdates.has_unseen_features?(admin.id)).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
it "resets last seen for moderator" do
|
||||
populate_new_features
|
||||
|
||||
put "/admin/dashboard/mark-new-features-as-seen.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(DiscourseUpdates.new_features_last_seen(moderator.id)).not_to eq(nil)
|
||||
expect(DiscourseUpdates.has_unseen_features?(moderator.id)).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "prevents marking new feature as seen with a 404 response" do
|
||||
put "/admin/dashboard/mark-new-features-as-seen.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,33 +2,52 @@
|
|||
|
||||
RSpec.describe Admin::EmailController do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:email_log) { Fabricate(:email_log) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::EmailController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
before do
|
||||
Admin::EmailController.any_instance
|
||||
.expects(:action_mailer_settings)
|
||||
.returns(
|
||||
username: 'username',
|
||||
password: 'secret'
|
||||
)
|
||||
context "when logged in as an admin" do
|
||||
before do
|
||||
sign_in(admin)
|
||||
Admin::EmailController.any_instance
|
||||
.expects(:action_mailer_settings)
|
||||
.returns(
|
||||
username: 'username',
|
||||
password: 'secret'
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not include the password in the response' do
|
||||
get "/admin/email.json"
|
||||
mail_settings = response.parsed_body['settings']
|
||||
|
||||
expect(
|
||||
mail_settings.select { |setting| setting['name'] == 'password' }
|
||||
).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not include the password in the response' do
|
||||
get "/admin/email.json"
|
||||
mail_settings = response.parsed_body['settings']
|
||||
shared_examples "email settings inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/email.json"
|
||||
|
||||
expect(
|
||||
mail_settings.select { |setting| setting['name'] == 'password' }
|
||||
).to be_empty
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["settings"]).to be_nil
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "email settings inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "email settings inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -40,40 +59,61 @@ RSpec.describe Admin::EmailController do
|
|||
Fabricate(:post_reply_key, post: post, user: email_log.user)
|
||||
end
|
||||
|
||||
it "should return the right response" do
|
||||
email_log
|
||||
get "/admin/email/sent.json"
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
log = response.parsed_body.first
|
||||
expect(log["id"]).to eq(email_log.id)
|
||||
expect(log["reply_key"]).to eq(nil)
|
||||
it "should return the right response" do
|
||||
email_log
|
||||
get "/admin/email/sent.json"
|
||||
|
||||
post_reply_key
|
||||
expect(response.status).to eq(200)
|
||||
log = response.parsed_body.first
|
||||
expect(log["id"]).to eq(email_log.id)
|
||||
expect(log["reply_key"]).to eq(nil)
|
||||
|
||||
get "/admin/email/sent.json"
|
||||
post_reply_key
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
log = response.parsed_body.first
|
||||
expect(log["id"]).to eq(email_log.id)
|
||||
expect(log["reply_key"]).to eq(post_reply_key.reply_key)
|
||||
end
|
||||
get "/admin/email/sent.json"
|
||||
|
||||
it 'should be able to filter by reply key' do
|
||||
email_log_2 = Fabricate(:email_log, post: post)
|
||||
expect(response.status).to eq(200)
|
||||
log = response.parsed_body.first
|
||||
expect(log["id"]).to eq(email_log.id)
|
||||
expect(log["reply_key"]).to eq(post_reply_key.reply_key)
|
||||
end
|
||||
|
||||
post_reply_key_2 = Fabricate(:post_reply_key,
|
||||
post: post,
|
||||
user: email_log_2.user,
|
||||
reply_key: "2d447423-c625-4fb9-8717-ff04ac60eee8"
|
||||
)
|
||||
it 'should be able to filter by reply key' do
|
||||
email_log_2 = Fabricate(:email_log, post: post)
|
||||
|
||||
post_reply_key_2 = Fabricate(:post_reply_key,
|
||||
post: post,
|
||||
user: email_log_2.user,
|
||||
reply_key: "2d447423-c625-4fb9-8717-ff04ac60eee8"
|
||||
)
|
||||
|
||||
[
|
||||
"17ff04",
|
||||
"2d447423c6254fb98717ff04ac60eee8"
|
||||
].each do |reply_key|
|
||||
get "/admin/email/sent.json", params: {
|
||||
reply_key: reply_key
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
logs = response.parsed_body
|
||||
|
||||
expect(logs.size).to eq(1)
|
||||
expect(logs.first["reply_key"]).to eq(post_reply_key_2.reply_key)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should be able to filter by smtp_transaction_response' do
|
||||
email_log_2 = Fabricate(:email_log, smtp_transaction_response: <<~RESPONSE)
|
||||
250 Ok: queued as pYoKuQ1aUG5vdpgh-k2K11qcpF4C1ZQ5qmvmmNW25SM=@mailhog.example
|
||||
RESPONSE
|
||||
|
||||
[
|
||||
"17ff04",
|
||||
"2d447423c6254fb98717ff04ac60eee8"
|
||||
].each do |reply_key|
|
||||
get "/admin/email/sent.json", params: {
|
||||
reply_key: reply_key
|
||||
smtp_transaction_response: "pYoKu"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
@ -81,219 +121,448 @@ RSpec.describe Admin::EmailController do
|
|||
logs = response.parsed_body
|
||||
|
||||
expect(logs.size).to eq(1)
|
||||
expect(logs.first["reply_key"]).to eq(post_reply_key_2.reply_key)
|
||||
expect(logs.first["smtp_transaction_response"]).to eq(email_log_2.smtp_transaction_response)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should be able to filter by smtp_transaction_response' do
|
||||
email_log_2 = Fabricate(:email_log, smtp_transaction_response: <<~RESPONSE)
|
||||
250 Ok: queued as pYoKuQ1aUG5vdpgh-k2K11qcpF4C1ZQ5qmvmmNW25SM=@mailhog.example
|
||||
RESPONSE
|
||||
shared_examples "sent emails inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/email/sent.json"
|
||||
|
||||
get "/admin/email/sent.json", params: {
|
||||
smtp_transaction_response: "pYoKu"
|
||||
}
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
logs = response.parsed_body
|
||||
include_examples "sent emails inaccessible"
|
||||
end
|
||||
|
||||
expect(logs.size).to eq(1)
|
||||
expect(logs.first["smtp_transaction_response"]).to eq(email_log_2.smtp_transaction_response)
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "sent emails inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#skipped' do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
# fab!(:user) { Fabricate(:user) }
|
||||
fab!(:log1) { Fabricate(:skipped_email_log, user: user, created_at: 20.minutes.ago) }
|
||||
fab!(:log2) { Fabricate(:skipped_email_log, created_at: 10.minutes.ago) }
|
||||
|
||||
it "succeeds" do
|
||||
get "/admin/email/skipped.json"
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
logs = response.parsed_body
|
||||
|
||||
expect(logs.first["id"]).to eq(log2.id)
|
||||
expect(logs.last["id"]).to eq(log1.id)
|
||||
end
|
||||
|
||||
describe 'when filtered by username' do
|
||||
it 'should return the right response' do
|
||||
get "/admin/email/skipped.json", params: {
|
||||
user: user.username
|
||||
}
|
||||
it "succeeds" do
|
||||
get "/admin/email/skipped.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
logs = response.parsed_body
|
||||
|
||||
expect(logs.count).to eq(1)
|
||||
expect(logs.first["id"]).to eq(log1.id)
|
||||
expect(logs.first["id"]).to eq(log2.id)
|
||||
expect(logs.last["id"]).to eq(log1.id)
|
||||
end
|
||||
|
||||
context "when filtered by username" do
|
||||
it 'should return the right response' do
|
||||
get "/admin/email/skipped.json", params: {
|
||||
user: user.username
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
logs = response.parsed_body
|
||||
|
||||
expect(logs.count).to eq(1)
|
||||
expect(logs.first["id"]).to eq(log1.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "skipped emails inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/email/skipped.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "skipped emails inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "skipped emails inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#test' do
|
||||
it 'raises an error without the email parameter' do
|
||||
post "/admin/email/test.json"
|
||||
expect(response.status).to eq(400)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'raises an error without the email parameter' do
|
||||
post "/admin/email/test.json"
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
|
||||
context 'with an email address' do
|
||||
it 'enqueues a test email job' do
|
||||
post "/admin/email/test.json", params: { email_address: 'eviltrout@test.domain' }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(ActionMailer::Base.deliveries.map(&:to).flatten).to include('eviltrout@test.domain')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with SiteSetting.disable_emails' do
|
||||
fab!(:eviltrout) { Fabricate(:evil_trout) }
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
|
||||
it 'bypasses disable when setting is "yes"' do
|
||||
SiteSetting.disable_emails = 'yes'
|
||||
post "/admin/email/test.json", params: { email_address: admin.email }
|
||||
|
||||
expect(ActionMailer::Base.deliveries.first.to).to contain_exactly(
|
||||
admin.email
|
||||
)
|
||||
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['sent_test_email_message']).to eq(I18n.t("admin.email.sent_test"))
|
||||
end
|
||||
|
||||
it 'bypasses disable when setting is "non-staff"' do
|
||||
SiteSetting.disable_emails = 'non-staff'
|
||||
|
||||
post "/admin/email/test.json", params: { email_address: eviltrout.email }
|
||||
|
||||
expect(ActionMailer::Base.deliveries.first.to).to contain_exactly(
|
||||
eviltrout.email
|
||||
)
|
||||
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['sent_test_email_message']).to eq(I18n.t("admin.email.sent_test"))
|
||||
end
|
||||
|
||||
it 'works when setting is "no"' do
|
||||
SiteSetting.disable_emails = 'no'
|
||||
|
||||
post "/admin/email/test.json", params: { email_address: eviltrout.email }
|
||||
|
||||
expect(ActionMailer::Base.deliveries.first.to).to contain_exactly(
|
||||
eviltrout.email
|
||||
)
|
||||
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['sent_test_email_message']).to eq(I18n.t("admin.email.sent_test"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an email address' do
|
||||
it 'enqueues a test email job' do
|
||||
shared_examples "email tests not allowed" do
|
||||
it "prevents email tests with a 404 response" do
|
||||
post "/admin/email/test.json", params: { email_address: 'eviltrout@test.domain' }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(ActionMailer::Base.deliveries.map(&:to).flatten).to include('eviltrout@test.domain')
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context 'with SiteSetting.disable_emails' do
|
||||
fab!(:eviltrout) { Fabricate(:evil_trout) }
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
it 'bypasses disable when setting is "yes"' do
|
||||
SiteSetting.disable_emails = 'yes'
|
||||
post "/admin/email/test.json", params: { email_address: admin.email }
|
||||
include_examples "email tests not allowed"
|
||||
end
|
||||
|
||||
expect(ActionMailer::Base.deliveries.first.to).to contain_exactly(
|
||||
admin.email
|
||||
)
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['sent_test_email_message']).to eq(I18n.t("admin.email.sent_test"))
|
||||
end
|
||||
|
||||
it 'bypasses disable when setting is "non-staff"' do
|
||||
SiteSetting.disable_emails = 'non-staff'
|
||||
|
||||
post "/admin/email/test.json", params: { email_address: eviltrout.email }
|
||||
|
||||
expect(ActionMailer::Base.deliveries.first.to).to contain_exactly(
|
||||
eviltrout.email
|
||||
)
|
||||
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['sent_test_email_message']).to eq(I18n.t("admin.email.sent_test"))
|
||||
end
|
||||
|
||||
it 'works when setting is "no"' do
|
||||
SiteSetting.disable_emails = 'no'
|
||||
|
||||
post "/admin/email/test.json", params: { email_address: eviltrout.email }
|
||||
|
||||
expect(ActionMailer::Base.deliveries.first.to).to contain_exactly(
|
||||
eviltrout.email
|
||||
)
|
||||
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['sent_test_email_message']).to eq(I18n.t("admin.email.sent_test"))
|
||||
end
|
||||
include_examples "email tests not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#preview_digest' do
|
||||
it 'raises an error without the last_seen_at parameter' do
|
||||
get "/admin/email/preview-digest.json"
|
||||
expect(response.status).to eq(400)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'raises an error without the last_seen_at parameter' do
|
||||
get "/admin/email/preview-digest.json"
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
|
||||
it "returns the right response when username is invalid" do
|
||||
get "/admin/email/preview-digest.json", params: {
|
||||
last_seen_at: 1.week.ago, username: "somerandomeusername"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
|
||||
it "previews the digest" do
|
||||
get "/admin/email/preview-digest.json", params: {
|
||||
last_seen_at: 1.week.ago, username: admin.username
|
||||
}
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the right response when username is invalid" do
|
||||
get "/admin/email/preview-digest.json", params: {
|
||||
last_seen_at: 1.week.ago, username: "somerandomeusername"
|
||||
}
|
||||
shared_examples "preview digest inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/email/preview-digest.json", params: {
|
||||
last_seen_at: 1.week.ago, username: moderator.username
|
||||
}
|
||||
|
||||
expect(response.status).to eq(400)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
it "previews the digest" do
|
||||
get "/admin/email/preview-digest.json", params: {
|
||||
last_seen_at: 1.week.ago, username: admin.username
|
||||
}
|
||||
expect(response.status).to eq(200)
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "preview digest inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "preview digest inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#handle_mail' do
|
||||
it "returns a bad request if neither email parameter is present" do
|
||||
post "/admin/email/handle_mail.json"
|
||||
expect(response.status).to eq(400)
|
||||
expect(response.body).to include("param is missing")
|
||||
end
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'should enqueue the right job, and show a deprecation warning (email_encoded param should be used)' do
|
||||
expect_enqueued_with(
|
||||
job: :process_email,
|
||||
args: { mail: email('cc'), retry_on_rate_limit: true, source: :handle_mail }
|
||||
) do
|
||||
post "/admin/email/handle_mail.json", params: { email: email('cc') }
|
||||
it "returns a bad request if neither email parameter is present" do
|
||||
post "/admin/email/handle_mail.json"
|
||||
expect(response.status).to eq(400)
|
||||
expect(response.body).to include("param is missing")
|
||||
end
|
||||
|
||||
it 'should enqueue the right job, and show a deprecation warning (email_encoded param should be used)' do
|
||||
expect_enqueued_with(
|
||||
job: :process_email,
|
||||
args: { mail: email('cc'), retry_on_rate_limit: true, source: :handle_mail }
|
||||
) do
|
||||
post "/admin/email/handle_mail.json", params: { email: email('cc') }
|
||||
end
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to eq("warning: the email parameter is deprecated. all POST requests to this route should be sent with a base64 strict encoded email_encoded parameter instead. email has been received and is queued for processing")
|
||||
end
|
||||
|
||||
it 'should enqueue the right job, decoding the raw email param' do
|
||||
expect_enqueued_with(
|
||||
job: :process_email,
|
||||
args: { mail: email('cc'), retry_on_rate_limit: true, source: :handle_mail }
|
||||
) do
|
||||
post "/admin/email/handle_mail.json", params: { email_encoded: Base64.strict_encode64(email('cc')) }
|
||||
end
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to eq("email has been received and is queued for processing")
|
||||
end
|
||||
|
||||
it "retries enqueueing with forced UTF-8 encoding when encountering Encoding::UndefinedConversionError" do
|
||||
post "/admin/email/handle_mail.json", params: { email_encoded: Base64.strict_encode64(email('encoding_undefined_conversion')) }
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to eq("email has been received and is queued for processing")
|
||||
end
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to eq("warning: the email parameter is deprecated. all POST requests to this route should be sent with a base64 strict encoded email_encoded parameter instead. email has been received and is queued for processing")
|
||||
end
|
||||
|
||||
it 'should enqueue the right job, decoding the raw email param' do
|
||||
expect_enqueued_with(
|
||||
job: :process_email,
|
||||
args: { mail: email('cc'), retry_on_rate_limit: true, source: :handle_mail }
|
||||
) do
|
||||
shared_examples "email handling not allowed" do
|
||||
it "prevents email handling with a 404 response" do
|
||||
post "/admin/email/handle_mail.json", params: { email_encoded: Base64.strict_encode64(email('cc')) }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to eq("email has been received and is queued for processing")
|
||||
end
|
||||
|
||||
it "retries enqueueing with forced UTF-8 encoding when encountering Encoding::UndefinedConversionError" do
|
||||
post "/admin/email/handle_mail.json", params: { email_encoded: Base64.strict_encode64(email('encoding_undefined_conversion')) }
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to eq("email has been received and is queued for processing")
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "email handling not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "email handling not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#rejected' do
|
||||
it 'should provide a string for a blank error' do
|
||||
Fabricate(:incoming_email, error: "")
|
||||
get "/admin/email/rejected.json"
|
||||
expect(response.status).to eq(200)
|
||||
rejected = response.parsed_body
|
||||
expect(rejected.first['error']).to eq(I18n.t("emails.incoming.unrecognized_error"))
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'should provide a string for a blank error' do
|
||||
Fabricate(:incoming_email, error: "")
|
||||
get "/admin/email/rejected.json"
|
||||
expect(response.status).to eq(200)
|
||||
rejected = response.parsed_body
|
||||
expect(rejected.first['error']).to eq(I18n.t("emails.incoming.unrecognized_error"))
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "rejected emails inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/email/rejected.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "rejected emails inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "rejected emails inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#incoming' do
|
||||
it 'should provide a string for a blank error' do
|
||||
incoming_email = Fabricate(:incoming_email, error: "")
|
||||
get "/admin/email/incoming/#{incoming_email.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['error']).to eq(I18n.t("emails.incoming.unrecognized_error"))
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'should provide a string for a blank error' do
|
||||
incoming_email = Fabricate(:incoming_email, error: "")
|
||||
get "/admin/email/incoming/#{incoming_email.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['error']).to eq(I18n.t("emails.incoming.unrecognized_error"))
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "incoming emails inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
incoming_email = Fabricate(:incoming_email, error: "")
|
||||
|
||||
get "/admin/email/incoming/#{incoming_email.id}.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "incoming emails inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "incoming emails inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#incoming_from_bounced' do
|
||||
it 'raises an error when the email log entry does not exist' do
|
||||
get "/admin/email/incoming_from_bounced/12345.json"
|
||||
expect(response.status).to eq(404)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["errors"]).to include("Discourse::InvalidParameters")
|
||||
it 'raises an error when the email log entry does not exist' do
|
||||
get "/admin/email/incoming_from_bounced/12345.json"
|
||||
expect(response.status).to eq(404)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["errors"]).to include("Discourse::InvalidParameters")
|
||||
end
|
||||
|
||||
it 'raises an error when the email log entry is not marked as bounced' do
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(404)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["errors"]).to include("Discourse::InvalidParameters")
|
||||
end
|
||||
|
||||
context 'when bounced email log entry exists' do
|
||||
fab!(:email_log) { Fabricate(:email_log, bounced: true, bounce_key: SecureRandom.hex) }
|
||||
let(:error_message) { "Email::Receiver::BouncedEmailError" }
|
||||
|
||||
it 'returns an incoming email sent to the reply_by_email_address' do
|
||||
SiteSetting.reply_by_email_address = "replies+%{reply_key}@example.com"
|
||||
|
||||
Fabricate(:incoming_email,
|
||||
is_bounce: true,
|
||||
error: error_message,
|
||||
to_addresses: Email::Sender.bounce_address(email_log.bounce_key)
|
||||
)
|
||||
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["error"]).to eq(error_message)
|
||||
end
|
||||
|
||||
it 'returns an incoming email sent to the notification_email address' do
|
||||
Fabricate(:incoming_email,
|
||||
is_bounce: true,
|
||||
error: error_message,
|
||||
to_addresses: SiteSetting.notification_email.sub("@", "+verp-#{email_log.bounce_key}@")
|
||||
)
|
||||
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["error"]).to eq(error_message)
|
||||
end
|
||||
|
||||
it 'returns an incoming email sent to the notification_email address' do
|
||||
SiteSetting.reply_by_email_address = "replies+%{reply_key}@subdomain.example.com"
|
||||
Fabricate(:incoming_email,
|
||||
is_bounce: true,
|
||||
error: error_message,
|
||||
to_addresses: "subdomain+verp-#{email_log.bounce_key}@example.com"
|
||||
)
|
||||
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["error"]).to eq(error_message)
|
||||
end
|
||||
|
||||
it 'raises an error if the bounce_key is blank' do
|
||||
email_log.update(bounce_key: nil)
|
||||
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(404)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["errors"]).to include("Discourse::InvalidParameters")
|
||||
end
|
||||
|
||||
it 'raises an error if there is no incoming email' do
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(404)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["errors"]).to include("Discourse::NotFound")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises an error when the email log entry is not marked as bounced' do
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(404)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["errors"]).to include("Discourse::InvalidParameters")
|
||||
end
|
||||
|
||||
context 'when bounced email log entry exists' do
|
||||
fab!(:email_log) { Fabricate(:email_log, bounced: true, bounce_key: SecureRandom.hex) }
|
||||
let(:error_message) { "Email::Receiver::BouncedEmailError" }
|
||||
|
||||
it 'returns an incoming email sent to the reply_by_email_address' do
|
||||
shared_examples "bounced incoming emails inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
email_log = Fabricate(:email_log, bounced: true, bounce_key: SecureRandom.hex)
|
||||
error_message = "Email::Receiver::BouncedEmailError"
|
||||
SiteSetting.reply_by_email_address = "replies+%{reply_key}@example.com"
|
||||
|
||||
Fabricate(:incoming_email,
|
||||
|
@ -303,82 +572,75 @@ RSpec.describe Admin::EmailController do
|
|||
)
|
||||
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["error"]).to eq(error_message)
|
||||
end
|
||||
|
||||
it 'returns an incoming email sent to the notification_email address' do
|
||||
Fabricate(:incoming_email,
|
||||
is_bounce: true,
|
||||
error: error_message,
|
||||
to_addresses: SiteSetting.notification_email.sub("@", "+verp-#{email_log.bounce_key}@")
|
||||
)
|
||||
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["error"]).to eq(error_message)
|
||||
end
|
||||
|
||||
it 'returns an incoming email sent to the notification_email address' do
|
||||
SiteSetting.reply_by_email_address = "replies+%{reply_key}@subdomain.example.com"
|
||||
Fabricate(:incoming_email,
|
||||
is_bounce: true,
|
||||
error: error_message,
|
||||
to_addresses: "subdomain+verp-#{email_log.bounce_key}@example.com"
|
||||
)
|
||||
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["error"]).to eq(error_message)
|
||||
end
|
||||
|
||||
it 'raises an error if the bounce_key is blank' do
|
||||
email_log.update(bounce_key: nil)
|
||||
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(404)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["errors"]).to include("Discourse::InvalidParameters")
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises an error if there is no incoming email' do
|
||||
get "/admin/email/incoming_from_bounced/#{email_log.id}.json"
|
||||
expect(response.status).to eq(404)
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["errors"]).to include("Discourse::NotFound")
|
||||
end
|
||||
include_examples "bounced incoming emails inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "bounced incoming emails inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#advanced_test' do
|
||||
it 'should ...' do
|
||||
email = <<~EMAIL
|
||||
From: "somebody" <somebody@example.com>
|
||||
To: someone@example.com
|
||||
Date: Mon, 3 Dec 2018 00:00:00 -0000
|
||||
Subject: This is some subject
|
||||
Content-Type: text/plain; charset="UTF-8"
|
||||
let(:email) do
|
||||
<<~EMAIL
|
||||
From: "somebody" <somebody@example.com>
|
||||
To: someone@example.com
|
||||
Date: Mon, 3 Dec 2018 00:00:00 -0000
|
||||
Subject: This is some subject
|
||||
Content-Type: text/plain; charset="UTF-8"
|
||||
|
||||
Hello, this is a test!
|
||||
Hello, this is a test!
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
This part should be elided.
|
||||
EMAIL
|
||||
post "/admin/email/advanced-test.json", params: { email: email }
|
||||
expect(response.status).to eq(200)
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['format']).to eq(1)
|
||||
expect(incoming['text']).to eq("Hello, this is a test!")
|
||||
expect(incoming['elided']).to eq("---\n\nThis part should be elided.")
|
||||
This part should be elided.
|
||||
EMAIL
|
||||
end
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'should ...' do
|
||||
post "/admin/email/advanced-test.json", params: { email: email }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
incoming = response.parsed_body
|
||||
expect(incoming['format']).to eq(1)
|
||||
expect(incoming['text']).to eq("Hello, this is a test!")
|
||||
expect(incoming['elided']).to eq("---\n\nThis part should be elided.")
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "advanced email tests not allowed" do
|
||||
it "prevents advanced email tests with a 404 response" do
|
||||
post "/admin/email/advanced-test.json", params: { email: email }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "advanced email tests not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "advanced email tests not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,41 +2,61 @@
|
|||
|
||||
RSpec.describe Admin::EmailStylesController do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
let(:default_html) { File.read("#{Rails.root}/app/views/email/default_template.html") }
|
||||
let(:default_css) { "" }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
after do
|
||||
SiteSetting.remove_override!(:email_custom_template)
|
||||
SiteSetting.remove_override!(:email_custom_css)
|
||||
end
|
||||
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::EmailStylesController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
|
||||
describe 'show' do
|
||||
it 'returns default values' do
|
||||
get '/admin/customize/email_style.json'
|
||||
expect(response.status).to eq(200)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
json = response.parsed_body['email_style']
|
||||
expect(json['html']).to eq(default_html)
|
||||
expect(json['css']).to eq(default_css)
|
||||
it 'returns default values' do
|
||||
get '/admin/customize/email_style.json'
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body['email_style']
|
||||
expect(json['html']).to eq(default_html)
|
||||
expect(json['css']).to eq(default_css)
|
||||
end
|
||||
|
||||
it 'returns customized values' do
|
||||
SiteSetting.email_custom_template = "For you: %{email_content}"
|
||||
SiteSetting.email_custom_css = ".user-name { font-size: 24px; }"
|
||||
get '/admin/customize/email_style.json'
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body['email_style']
|
||||
expect(json['html']).to eq("For you: %{email_content}")
|
||||
expect(json['css']).to eq(".user-name { font-size: 24px; }")
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns customized values' do
|
||||
SiteSetting.email_custom_template = "For you: %{email_content}"
|
||||
SiteSetting.email_custom_css = ".user-name { font-size: 24px; }"
|
||||
get '/admin/customize/email_style.json'
|
||||
expect(response.status).to eq(200)
|
||||
shared_examples "email styles inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get '/admin/customize/email_style.json'
|
||||
|
||||
json = response.parsed_body['email_style']
|
||||
expect(json['html']).to eq("For you: %{email_content}")
|
||||
expect(json['css']).to eq(".user-name { font-size: 24px; }")
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "email styles inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "email styles inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -48,26 +68,51 @@ RSpec.describe Admin::EmailStylesController do
|
|||
}
|
||||
end
|
||||
|
||||
it 'changes the settings' do
|
||||
SiteSetting.email_custom_css = ".user-name { font-size: 24px; }"
|
||||
put '/admin/customize/email_style.json', params: { email_style: valid_params }
|
||||
expect(response.status).to eq(200)
|
||||
expect(SiteSetting.email_custom_template).to eq(valid_params[:html])
|
||||
expect(SiteSetting.email_custom_css).to eq(valid_params[:css])
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'changes the settings' do
|
||||
SiteSetting.email_custom_css = ".user-name { font-size: 24px; }"
|
||||
put '/admin/customize/email_style.json', params: { email_style: valid_params }
|
||||
expect(response.status).to eq(200)
|
||||
expect(SiteSetting.email_custom_template).to eq(valid_params[:html])
|
||||
expect(SiteSetting.email_custom_css).to eq(valid_params[:css])
|
||||
end
|
||||
|
||||
it 'reports errors' do
|
||||
put '/admin/customize/email_style.json', params: {
|
||||
email_style: valid_params.merge(html: 'No email content')
|
||||
}
|
||||
expect(response.status).to eq(422)
|
||||
json = response.parsed_body
|
||||
expect(json['errors']).to include(
|
||||
I18n.t(
|
||||
'email_style.html_missing_placeholder',
|
||||
placeholder: '%{email_content}'
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it 'reports errors' do
|
||||
put '/admin/customize/email_style.json', params: {
|
||||
email_style: valid_params.merge(html: 'No email content')
|
||||
}
|
||||
expect(response.status).to eq(422)
|
||||
json = response.parsed_body
|
||||
expect(json['errors']).to include(
|
||||
I18n.t(
|
||||
'email_style.html_missing_placeholder',
|
||||
placeholder: '%{email_content}'
|
||||
)
|
||||
)
|
||||
shared_examples "email style update not allowed" do
|
||||
it "denies access with a 404 response" do
|
||||
put '/admin/customize/email_style.json', params: { email_style: valid_params }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "email style update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "email style update not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,90 +18,70 @@ RSpec.describe Admin::EmailTemplatesController do
|
|||
I18n.reload!
|
||||
end
|
||||
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::EmailTemplatesController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
|
||||
describe "#index" do
|
||||
it "raises an error if you aren't logged in" do
|
||||
get '/admin/customize/email_templates.json'
|
||||
expect(response.status).to eq(404)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "should work if you are an admin" do
|
||||
get '/admin/customize/email_templates.json'
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json['email_templates']).to be_present
|
||||
end
|
||||
|
||||
it 'returns overridden = true if subject or body has translation_overrides record' do
|
||||
put '/admin/customize/email_templates/user_notifications.admin_login', params: {
|
||||
email_template: { subject: original_subject, body: original_body }
|
||||
}, headers: headers
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
get '/admin/customize/email_templates.json'
|
||||
expect(response.status).to eq(200)
|
||||
templates = response.parsed_body['email_templates']
|
||||
template = templates.find { |t| t['id'] == 'user_notifications.admin_login' }
|
||||
expect(template['can_revert']).to eq(true)
|
||||
|
||||
TranslationOverride.destroy_all
|
||||
|
||||
get '/admin/customize/email_templates.json'
|
||||
expect(response.status).to eq(200)
|
||||
templates = response.parsed_body['email_templates']
|
||||
template = templates.find { |t| t['id'] == 'user_notifications.admin_login' }
|
||||
expect(template['can_revert']).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an error if you aren't an admin" do
|
||||
sign_in(user)
|
||||
get '/admin/customize/email_templates.json'
|
||||
expect(response.status).to eq(404)
|
||||
shared_examples "email templates inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/customize/email_templates.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an error if you are a moderator" do
|
||||
sign_in(moderator)
|
||||
get "/admin/customize/email_templates.json"
|
||||
expect(response.status).to eq(404)
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "email templates inaccessible"
|
||||
end
|
||||
|
||||
it "should work if you are an admin" do
|
||||
sign_in(admin)
|
||||
get '/admin/customize/email_templates.json'
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json['email_templates']).to be_present
|
||||
include_examples "email templates inaccessible"
|
||||
end
|
||||
|
||||
it 'returns overridden = true if subject or body has translation_overrides record' do
|
||||
sign_in(admin)
|
||||
|
||||
put '/admin/customize/email_templates/user_notifications.admin_login', params: {
|
||||
email_template: { subject: original_subject, body: original_body }
|
||||
}, headers: headers
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
get '/admin/customize/email_templates.json'
|
||||
expect(response.status).to eq(200)
|
||||
templates = response.parsed_body['email_templates']
|
||||
template = templates.find { |t| t['id'] == 'user_notifications.admin_login' }
|
||||
expect(template['can_revert']).to eq(true)
|
||||
|
||||
TranslationOverride.destroy_all
|
||||
|
||||
get '/admin/customize/email_templates.json'
|
||||
expect(response.status).to eq(200)
|
||||
templates = response.parsed_body['email_templates']
|
||||
template = templates.find { |t| t['id'] == 'user_notifications.admin_login' }
|
||||
expect(template['can_revert']).to eq(false)
|
||||
context "when not logged in" do
|
||||
include_examples "email templates inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
it "raises an error if you aren't logged in" do
|
||||
put '/admin/customize/email_templates/some_id', params: {
|
||||
email_template: { subject: 'Subject', body: 'Body' }
|
||||
}, headers: headers
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "raises an error if you aren't an admin" do
|
||||
sign_in(user)
|
||||
put '/admin/customize/email_templates/some_id', params: {
|
||||
email_template: { subject: 'Subject', body: 'Body' }
|
||||
}, headers: headers
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "raises an error if you are a moderator" do
|
||||
sign_in(moderator)
|
||||
put "/admin/customize/email_templates/some_id", params: {
|
||||
email_template: { subject: "Subject", body: "Body" }
|
||||
}, headers: headers
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
context "when logged in as admin" do
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns 'not found' when an unknown email template id is used" do
|
||||
put '/admin/customize/email_templates/non_existent_template', params: {
|
||||
|
@ -273,30 +253,37 @@ RSpec.describe Admin::EmailTemplatesController do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples "email template update not allowed" do
|
||||
it "prevents updates with a 404 response" do
|
||||
put "/admin/customize/email_templates/some_id", params: {
|
||||
email_template: { subject: 'Subject', body: 'Body' }
|
||||
}, headers: headers
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "email template update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "email template update not allowed"
|
||||
end
|
||||
|
||||
context "when not logged in" do
|
||||
include_examples "email template update not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#revert" do
|
||||
it "raises an error if you aren't logged in" do
|
||||
delete '/admin/customize/email_templates/some_id', headers: headers
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "raises an error if you aren't an admin" do
|
||||
sign_in(user)
|
||||
delete '/admin/customize/email_templates/some_id', headers: headers
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "raises an error if you are a moderator" do
|
||||
sign_in(moderator)
|
||||
delete "/admin/customize/email_templates/some_id", headers: headers
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
context "when logged in as admin" do
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns 'not found' when an unknown email template id is used" do
|
||||
delete '/admin/customize/email_templates/non_existent_template', headers: headers
|
||||
|
@ -364,6 +351,30 @@ RSpec.describe Admin::EmailTemplatesController do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples "email template reversal not allowed" do
|
||||
it "prevents reversals with a 404 response" do
|
||||
delete "/admin/customize/email_templates/some_id", headers: headers
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "email template reversal not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "email template reversal not allowed"
|
||||
end
|
||||
|
||||
context "when not logged in" do
|
||||
include_examples "email template reversal not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
it "uses only existing email templates" do
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::EmbeddableHostsController do
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::EmbeddableHostsController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:embeddable_host) { Fabricate(:embeddable_host) }
|
||||
|
||||
context 'while logged in as an admin' do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:embeddable_host) { Fabricate(:embeddable_host) }
|
||||
describe '#create' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
it "logs embeddable host create" do
|
||||
post "/admin/embeddable_hosts.json", params: {
|
||||
embeddable_host: { host: "test.com" }
|
||||
|
@ -25,7 +21,34 @@ RSpec.describe Admin::EmbeddableHostsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
shared_examples "embeddable host creation not allowed" do
|
||||
it "prevents embeddable host creation with a 404 response" do
|
||||
post "/admin/embeddable_hosts.json", params: {
|
||||
embeddable_host: { host: "test.com" }
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "embeddable host creation not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "embeddable host creation not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "logs embeddable host update" do
|
||||
category = Fabricate(:category)
|
||||
|
||||
|
@ -41,11 +64,39 @@ RSpec.describe Admin::EmbeddableHostsController do
|
|||
new_value: "category_id: #{category.id}, class_name: test-class, host: test.com").exists?
|
||||
|
||||
expect(history_exists).to eq(true)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
shared_examples "embeddable host update not allowed" do
|
||||
it "prevents updates with a 404 response" do
|
||||
category = Fabricate(:category)
|
||||
|
||||
put "/admin/embeddable_hosts/#{embeddable_host.id}.json", params: {
|
||||
embeddable_host: { host: "test.com", class_name: "test-class", category_id: category.id }
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "embeddable host update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "embeddable host update not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "logs embeddable host destroy" do
|
||||
delete "/admin/embeddable_hosts/#{embeddable_host.id}.json", params: {}
|
||||
|
||||
|
@ -53,5 +104,26 @@ RSpec.describe Admin::EmbeddableHostsController do
|
|||
expect(UserHistory.where(acting_user_id: admin.id, action: UserHistory.actions[:embeddable_host_destroy]).exists?).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "embeddable host deletion not allowed" do
|
||||
it "prevents deletion with a 404 response" do
|
||||
delete "/admin/embeddable_hosts/#{embeddable_host.id}.json", params: {}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "embeddable host deletion not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "embeddable host deletion not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,87 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::EmbeddingController do
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::EmbeddingController < Admin::AdminController).to eq(true)
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
describe "#show" do
|
||||
context 'when logged in as an admin' do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns embedding" do
|
||||
get "/admin/customize/embedding.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["embedding"]).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "embedding accessible" do
|
||||
it "returns embedding" do
|
||||
get "/admin/customize/embedding.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "embedding accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "embedding accessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
context 'when logged in as an admin' do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "updates embedding" do
|
||||
put "/admin/customize/embedding.json", params: {
|
||||
embedding: {
|
||||
embed_by_username: "system",
|
||||
embed_post_limit: 200
|
||||
}
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["embedding"]["embed_by_username"]).to eq("system")
|
||||
expect(response.parsed_body["embedding"]["embed_post_limit"]).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "embedding updates not allowed" do
|
||||
it "prevents updates with a 404 response" do
|
||||
put "/admin/customize/embedding.json", params: {
|
||||
embedding: {
|
||||
embed_by_username: "system",
|
||||
embed_post_limit: 200
|
||||
}
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(response.parsed_body["embedding"]).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "embedding updates not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "embedding updates not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,139 +2,219 @@
|
|||
|
||||
RSpec.describe Admin::EmojisController do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:upload) { Fabricate(:upload) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
it "returns a list of custom emojis" do
|
||||
CustomEmoji.create!(name: 'osama-test-emoji', upload: upload)
|
||||
Emoji.clear_cache
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
get "/admin/customize/emojis.json"
|
||||
expect(response.status).to eq(200)
|
||||
it "returns a list of custom emojis" do
|
||||
CustomEmoji.create!(name: 'osama-test-emoji', upload: upload)
|
||||
Emoji.clear_cache
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json[0]["name"]).to eq("osama-test-emoji")
|
||||
expect(json[0]["url"]).to eq(upload.url)
|
||||
get "/admin/customize/emojis.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json[0]["name"]).to eq("osama-test-emoji")
|
||||
expect(json[0]["url"]).to eq(upload.url)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "custom emojis inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/customize/emojis.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "custom emojis inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "custom emojis inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
describe 'when upload is invalid' do
|
||||
it 'should publish the right error' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/fake.jpg")
|
||||
}
|
||||
context 'when upload is invalid' do
|
||||
it 'should publish the right error' do
|
||||
|
||||
expect(response.status).to eq(422)
|
||||
parsed = response.parsed_body
|
||||
expect(parsed["errors"]).to eq([I18n.t('upload.images.size_not_found')])
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/fake.jpg")
|
||||
}
|
||||
|
||||
expect(response.status).to eq(422)
|
||||
parsed = response.parsed_body
|
||||
expect(parsed["errors"]).to eq([I18n.t('upload.images.size_not_found')])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when emoji name already exists' do
|
||||
it 'should publish the right error' do
|
||||
CustomEmoji.create!(name: 'test', upload: upload)
|
||||
context 'when emoji name already exists' do
|
||||
it 'should publish the right error' do
|
||||
CustomEmoji.create!(name: 'test', upload: upload)
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
expect(response.status).to eq(422)
|
||||
parsed = response.parsed_body
|
||||
expect(parsed["errors"]).to eq([
|
||||
"Name #{I18n.t('activerecord.errors.models.custom_emoji.attributes.name.taken')}"
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
it 'should allow an admin to add a custom emoji' do
|
||||
Emoji.expects(:clear_cache)
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
expect(response.status).to eq(422)
|
||||
parsed = response.parsed_body
|
||||
expect(parsed["errors"]).to eq([
|
||||
"Name #{I18n.t('activerecord.errors.models.custom_emoji.attributes.name.taken')}"
|
||||
])
|
||||
custom_emoji = CustomEmoji.last
|
||||
upload = custom_emoji.upload
|
||||
|
||||
expect(upload.original_filename).to eq('logo.png')
|
||||
|
||||
data = response.parsed_body
|
||||
expect(response.status).to eq(200)
|
||||
expect(data["errors"]).to eq(nil)
|
||||
expect(data["name"]).to eq(custom_emoji.name)
|
||||
expect(data["url"]).to eq(upload.url)
|
||||
expect(custom_emoji.group).to eq(nil)
|
||||
end
|
||||
|
||||
it 'should allow an admin to add a custom emoji with a custom group' do
|
||||
Emoji.expects(:clear_cache)
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test',
|
||||
group: 'Foo',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
custom_emoji = CustomEmoji.last
|
||||
|
||||
data = response.parsed_body
|
||||
expect(response.status).to eq(200)
|
||||
expect(custom_emoji.group).to eq("foo")
|
||||
end
|
||||
|
||||
it 'should fix up the emoji name' do
|
||||
Emoji.expects(:clear_cache).times(3)
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test.png',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
custom_emoji = CustomEmoji.last
|
||||
upload = custom_emoji.upload
|
||||
|
||||
expect(upload.original_filename).to eq('logo.png')
|
||||
expect(custom_emoji.name).to eq("test")
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'st&#* onk$',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
custom_emoji = CustomEmoji.last
|
||||
expect(custom_emoji.name).to eq("st_onk_")
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'PaRTYpaRrot',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
custom_emoji = CustomEmoji.last
|
||||
expect(custom_emoji.name).to eq("partyparrot")
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should allow an admin to add a custom emoji' do
|
||||
Emoji.expects(:clear_cache)
|
||||
shared_examples "custom emoji creation not allowed" do
|
||||
it "prevents creation with a 404 response" do
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
custom_emoji = CustomEmoji.last
|
||||
upload = custom_emoji.upload
|
||||
|
||||
expect(upload.original_filename).to eq('logo.png')
|
||||
|
||||
data = response.parsed_body
|
||||
expect(response.status).to eq(200)
|
||||
expect(data["errors"]).to eq(nil)
|
||||
expect(data["name"]).to eq(custom_emoji.name)
|
||||
expect(data["url"]).to eq(upload.url)
|
||||
expect(custom_emoji.group).to eq(nil)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
it 'should allow an admin to add a custom emoji with a custom group' do
|
||||
Emoji.expects(:clear_cache)
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test',
|
||||
group: 'Foo',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
custom_emoji = CustomEmoji.last
|
||||
|
||||
data = response.parsed_body
|
||||
expect(response.status).to eq(200)
|
||||
expect(custom_emoji.group).to eq("foo")
|
||||
include_examples "custom emoji creation not allowed"
|
||||
end
|
||||
|
||||
it 'should fix up the emoji name' do
|
||||
Emoji.expects(:clear_cache).times(3)
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'test.png',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
custom_emoji = CustomEmoji.last
|
||||
upload = custom_emoji.upload
|
||||
|
||||
expect(upload.original_filename).to eq('logo.png')
|
||||
expect(custom_emoji.name).to eq("test")
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'st&#* onk$',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
custom_emoji = CustomEmoji.last
|
||||
expect(custom_emoji.name).to eq("st_onk_")
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
post "/admin/customize/emojis.json", params: {
|
||||
name: 'PaRTYpaRrot',
|
||||
file: fixture_file_upload("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
}
|
||||
|
||||
custom_emoji = CustomEmoji.last
|
||||
expect(custom_emoji.name).to eq("partyparrot")
|
||||
expect(response.status).to eq(200)
|
||||
include_examples "custom emoji creation not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
it 'should allow an admin to delete a custom emoji' do
|
||||
custom_emoji = CustomEmoji.create!(name: 'test', upload: upload)
|
||||
Emoji.clear_cache
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'should allow an admin to delete a custom emoji' do
|
||||
custom_emoji = CustomEmoji.create!(name: 'test', upload: upload)
|
||||
Emoji.clear_cache
|
||||
|
||||
expect do
|
||||
delete "/admin/customize/emojis/#{custom_emoji.name}.json",
|
||||
params: { name: 'test' }
|
||||
end.to change { CustomEmoji.count }.by(-1)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "custom emoji deletion not allowed" do
|
||||
it "prevents deletion with a 404 response" do
|
||||
custom_emoji = CustomEmoji.create!(name: 'test', upload: upload)
|
||||
Emoji.clear_cache
|
||||
|
||||
expect do
|
||||
delete "/admin/customize/emojis/#{custom_emoji.name}.json",
|
||||
params: { name: 'test' }
|
||||
end.to change { CustomEmoji.count }.by(-1)
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "custom emoji deletion not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "custom emoji deletion not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,28 +1,48 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::ImpersonateController do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:another_admin) { Fabricate(:admin) }
|
||||
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::ImpersonateController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
describe '#index' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
context 'while logged in as an admin' do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:another_admin) { Fabricate(:admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
it 'returns success' do
|
||||
get "/admin/impersonate.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
shared_examples "impersonation inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/impersonate.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "impersonation inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "impersonation inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'requires a username_or_email parameter' do
|
||||
post "/admin/impersonate.json"
|
||||
expect(response.status).to eq(400)
|
||||
|
@ -58,5 +78,32 @@ RSpec.describe Admin::ImpersonateController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "impersonation not allowed" do
|
||||
it "prevents impersonation with a with 404 response" do
|
||||
expect do
|
||||
post "/admin/impersonate.json", params: { username_or_email: user.username }
|
||||
end.not_to change { UserHistory.where(action: UserHistory.actions[:impersonate]).count }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(session[:current_user_id]).to eq(current_user.id)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "impersonation not allowed" do
|
||||
let(:current_user) { moderator }
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "impersonation not allowed" do
|
||||
let(:current_user) { user }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,109 +1,160 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::PermalinksController do
|
||||
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::PermalinksController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
describe '#index' do
|
||||
it 'filters url' do
|
||||
Fabricate(:permalink, url: "/forum/23")
|
||||
Fabricate(:permalink, url: "/forum/98")
|
||||
Fabricate(:permalink, url: "/discuss/topic/45")
|
||||
Fabricate(:permalink, url: "/discuss/topic/76")
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
get "/admin/permalinks.json", params: { filter: "topic" }
|
||||
it 'filters url' do
|
||||
Fabricate(:permalink, url: "/forum/23")
|
||||
Fabricate(:permalink, url: "/forum/98")
|
||||
Fabricate(:permalink, url: "/discuss/topic/45")
|
||||
Fabricate(:permalink, url: "/discuss/topic/76")
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result.length).to eq(2)
|
||||
get "/admin/permalinks.json", params: { filter: "topic" }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result.length).to eq(2)
|
||||
end
|
||||
|
||||
it 'filters external url' do
|
||||
Fabricate(:permalink, external_url: "http://google.com")
|
||||
Fabricate(:permalink, external_url: "http://wikipedia.org")
|
||||
Fabricate(:permalink, external_url: "http://www.discourse.org")
|
||||
Fabricate(:permalink, external_url: "http://try.discourse.org")
|
||||
|
||||
get "/admin/permalinks.json", params: { filter: "discourse" }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result.length).to eq(2)
|
||||
end
|
||||
|
||||
it 'filters url and external url both' do
|
||||
Fabricate(:permalink, url: "/forum/23", external_url: "http://google.com")
|
||||
Fabricate(:permalink, url: "/discourse/98", external_url: "http://wikipedia.org")
|
||||
Fabricate(:permalink, url: "/discuss/topic/45", external_url: "http://discourse.org")
|
||||
Fabricate(:permalink, url: "/discuss/topic/76", external_url: "http://try.discourse.org")
|
||||
|
||||
get "/admin/permalinks.json", params: { filter: "discourse" }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result.length).to eq(3)
|
||||
end
|
||||
end
|
||||
|
||||
it 'filters external url' do
|
||||
Fabricate(:permalink, external_url: "http://google.com")
|
||||
Fabricate(:permalink, external_url: "http://wikipedia.org")
|
||||
Fabricate(:permalink, external_url: "http://www.discourse.org")
|
||||
Fabricate(:permalink, external_url: "http://try.discourse.org")
|
||||
shared_examples "permalinks inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/permalinks.json", params: { filter: "topic" }
|
||||
|
||||
get "/admin/permalinks.json", params: { filter: "discourse" }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result.length).to eq(2)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
it 'filters url and external url both' do
|
||||
Fabricate(:permalink, url: "/forum/23", external_url: "http://google.com")
|
||||
Fabricate(:permalink, url: "/discourse/98", external_url: "http://wikipedia.org")
|
||||
Fabricate(:permalink, url: "/discuss/topic/45", external_url: "http://discourse.org")
|
||||
Fabricate(:permalink, url: "/discuss/topic/76", external_url: "http://try.discourse.org")
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
get "/admin/permalinks.json", params: { filter: "discourse" }
|
||||
include_examples "permalinks inaccessible"
|
||||
end
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result.length).to eq(3)
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "permalinks inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
it "works for topics" do
|
||||
topic = Fabricate(:topic)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
post "/admin/permalinks.json", params: {
|
||||
url: "/topics/771",
|
||||
permalink_type: "topic_id",
|
||||
permalink_type_value: topic.id
|
||||
}
|
||||
it "works for topics" do
|
||||
topic = Fabricate(:topic)
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(Permalink.last).to have_attributes(url: "topics/771", topic_id: topic.id, post_id: nil, category_id: nil, tag_id: nil)
|
||||
post "/admin/permalinks.json", params: {
|
||||
url: "/topics/771",
|
||||
permalink_type: "topic_id",
|
||||
permalink_type_value: topic.id
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(Permalink.last).to have_attributes(url: "topics/771", topic_id: topic.id, post_id: nil, category_id: nil, tag_id: nil)
|
||||
end
|
||||
|
||||
it "works for posts" do
|
||||
some_post = Fabricate(:post)
|
||||
|
||||
post "/admin/permalinks.json", params: {
|
||||
url: "/topics/771/8291",
|
||||
permalink_type: "post_id",
|
||||
permalink_type_value: some_post.id
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(Permalink.last).to have_attributes(url: "topics/771/8291", topic_id: nil, post_id: some_post.id, category_id: nil, tag_id: nil)
|
||||
end
|
||||
|
||||
it "works for categories" do
|
||||
category = Fabricate(:category)
|
||||
|
||||
post "/admin/permalinks.json", params: {
|
||||
url: "/forums/11",
|
||||
permalink_type: "category_id",
|
||||
permalink_type_value: category.id
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(Permalink.last).to have_attributes(url: "forums/11", topic_id: nil, post_id: nil, category_id: category.id, tag_id: nil)
|
||||
end
|
||||
|
||||
it "works for tags" do
|
||||
tag = Fabricate(:tag)
|
||||
|
||||
post "/admin/permalinks.json", params: {
|
||||
url: "/forums/12",
|
||||
permalink_type: "tag_name",
|
||||
permalink_type_value: tag.name
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(Permalink.last).to have_attributes(url: "forums/12", topic_id: nil, post_id: nil, category_id: nil, tag_id: tag.id)
|
||||
end
|
||||
end
|
||||
|
||||
it "works for posts" do
|
||||
some_post = Fabricate(:post)
|
||||
shared_examples "permalink creation not allowed" do
|
||||
it "prevents creation with a 404 response" do
|
||||
topic = Fabricate(:topic)
|
||||
|
||||
post "/admin/permalinks.json", params: {
|
||||
url: "/topics/771/8291",
|
||||
permalink_type: "post_id",
|
||||
permalink_type_value: some_post.id
|
||||
}
|
||||
expect do
|
||||
post "/admin/permalinks.json", params: {
|
||||
url: "/topics/771",
|
||||
permalink_type: "topic_id",
|
||||
permalink_type_value: topic.id
|
||||
}
|
||||
end.not_to change { Permalink.count }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(Permalink.last).to have_attributes(url: "topics/771/8291", topic_id: nil, post_id: some_post.id, category_id: nil, tag_id: nil)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
it "works for categories" do
|
||||
category = Fabricate(:category)
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
post "/admin/permalinks.json", params: {
|
||||
url: "/forums/11",
|
||||
permalink_type: "category_id",
|
||||
permalink_type_value: category.id
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(Permalink.last).to have_attributes(url: "forums/11", topic_id: nil, post_id: nil, category_id: category.id, tag_id: nil)
|
||||
include_examples "permalink creation not allowed"
|
||||
end
|
||||
|
||||
it "works for tags" do
|
||||
tag = Fabricate(:tag)
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
post "/admin/permalinks.json", params: {
|
||||
url: "/forums/12",
|
||||
permalink_type: "tag_name",
|
||||
permalink_type_value: tag.name
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(Permalink.last).to have_attributes(url: "forums/12", topic_id: nil, post_id: nil, category_id: nil, tag_id: tag.id)
|
||||
include_examples "permalink creation not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,20 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::PluginsController do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::PluginsController < Admin::StaffController).to eq(true)
|
||||
end
|
||||
describe "#index" do
|
||||
context "while logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
context "while logged in as an admin" do
|
||||
before do
|
||||
sign_in(Fabricate(:admin))
|
||||
it "returns plugins" do
|
||||
get "/admin/plugins.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body.has_key?('plugins')).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should return JSON' do
|
||||
get "/admin/plugins.json"
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body.has_key?('plugins')).to eq(true)
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
it "returns plugins" do
|
||||
get "/admin/plugins.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body.has_key?('plugins')).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/plugins.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::ReportsController do
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::ReportsController < Admin::StaffController).to eq(true)
|
||||
end
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
context 'while logged in as an admin' do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
describe '#bulk' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe '#bulk' do
|
||||
context "with valid params" do
|
||||
it "renders the reports as JSON" do
|
||||
Fabricate(:topic)
|
||||
|
@ -66,7 +61,45 @@ RSpec.describe Admin::ReportsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#show' do
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
it "returns report" do
|
||||
Fabricate(:topic)
|
||||
|
||||
get "/admin/reports/bulk.json", params: {
|
||||
reports: {
|
||||
topics: { limit: 10 },
|
||||
likes: { limit: 10 }
|
||||
}
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["reports"].count).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/reports/bulk.json", params: {
|
||||
reports: {
|
||||
topics: { limit: 10 },
|
||||
not_found: { limit: 10 }
|
||||
}
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#show' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
context "with invalid id form" do
|
||||
let(:invalid_id) { "!!&asdfasdf" }
|
||||
|
||||
|
@ -131,5 +164,29 @@ RSpec.describe Admin::ReportsController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
it "returns report" do
|
||||
Fabricate(:topic)
|
||||
|
||||
get "/admin/reports/topics.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["report"]["total"]).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/reports/topics.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,31 +1,123 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::RobotsTxtController do
|
||||
it "is a subclass of AdminController" do
|
||||
expect(described_class < Admin::AdminController).to eq(true)
|
||||
end
|
||||
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
context "when logged in as a non-admin user" do
|
||||
shared_examples "access_forbidden" do
|
||||
it "can't see #show" do
|
||||
describe "#show" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns default content if there are no overrides" do
|
||||
get "/admin/customize/robots.json"
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["robots_txt"]).to be_present
|
||||
expect(json["overridden"]).to eq(false)
|
||||
end
|
||||
|
||||
it "can't perform #update" do
|
||||
put "/admin/customize/robots.json", params: { robots_txt: "adasdasd" }
|
||||
it "returns overridden content if there are overrides" do
|
||||
SiteSetting.overridden_robots_txt = "something"
|
||||
get "/admin/customize/robots.json"
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["robots_txt"]).to eq("something")
|
||||
expect(json["overridden"]).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "robot.txt inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/customize/robots.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "robot.txt inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "robot.txt inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "overrides the site's default robots.txt" do
|
||||
put "/admin/customize/robots.json", params: { robots_txt: "new_content" }
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["robots_txt"]).to eq("new_content")
|
||||
expect(json["overridden"]).to eq(true)
|
||||
expect(SiteSetting.overridden_robots_txt).to eq("new_content")
|
||||
|
||||
get "/robots.txt"
|
||||
expect(response.body).to include("new_content")
|
||||
end
|
||||
|
||||
it "requires `robots_txt` param to be present" do
|
||||
SiteSetting.overridden_robots_txt = "overridden_content"
|
||||
put "/admin/customize/robots.json", params: { robots_txt: "" }
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "robot.txt update not allowed" do
|
||||
it "prevents updates with a 404 response" do
|
||||
put "/admin/customize/robots.json", params: { robots_txt: "adasdasd" }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(SiteSetting.overridden_robots_txt).to eq("")
|
||||
end
|
||||
end
|
||||
|
||||
it "can't perform #reset" do
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "robot.txt update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "robot.txt update not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#reset" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "resets robots.txt file to the default version" do
|
||||
SiteSetting.overridden_robots_txt = "overridden_content"
|
||||
delete "/admin/customize/robots.json"
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["robots_txt"]).not_to include("overridden_content")
|
||||
expect(json["overridden"]).to eq(false)
|
||||
expect(SiteSetting.overridden_robots_txt).to eq("")
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "robot.txt reset not allowed" do
|
||||
it "prevents resets with a 404 response" do
|
||||
SiteSetting.overridden_robots_txt = "overridden_content"
|
||||
|
||||
delete "/admin/customize/robots.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(SiteSetting.overridden_robots_txt).to eq("overridden_content")
|
||||
end
|
||||
end
|
||||
|
@ -33,70 +125,13 @@ RSpec.describe Admin::RobotsTxtController do
|
|||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "access_forbidden"
|
||||
include_examples "robot.txt reset not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as non-staff user" do
|
||||
before { sign_in(user) }
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "access_forbidden"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#show" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns default content if there are no overrides" do
|
||||
get "/admin/customize/robots.json"
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["robots_txt"]).to be_present
|
||||
expect(json["overridden"]).to eq(false)
|
||||
end
|
||||
|
||||
it "returns overridden content if there are overrides" do
|
||||
SiteSetting.overridden_robots_txt = "something"
|
||||
get "/admin/customize/robots.json"
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["robots_txt"]).to eq("something")
|
||||
expect(json["overridden"]).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "overrides the site's default robots.txt" do
|
||||
put "/admin/customize/robots.json", params: { robots_txt: "new_content" }
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["robots_txt"]).to eq("new_content")
|
||||
expect(json["overridden"]).to eq(true)
|
||||
expect(SiteSetting.overridden_robots_txt).to eq("new_content")
|
||||
|
||||
get "/robots.txt"
|
||||
expect(response.body).to include("new_content")
|
||||
end
|
||||
|
||||
it "requires `robots_txt` param to be present" do
|
||||
SiteSetting.overridden_robots_txt = "overridden_content"
|
||||
put "/admin/customize/robots.json", params: { robots_txt: "" }
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#reset" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "resets robots.txt file to the default version" do
|
||||
SiteSetting.overridden_robots_txt = "overridden_content"
|
||||
delete "/admin/customize/robots.json"
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["robots_txt"]).not_to include("overridden_content")
|
||||
expect(json["overridden"]).to eq(false)
|
||||
expect(SiteSetting.overridden_robots_txt).to eq("")
|
||||
include_examples "robot.txt reset not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,21 +1,78 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::ScreenedEmailsController do
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::ScreenedEmailsController < Admin::StaffController).to eq(true)
|
||||
end
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:screened_email) { Fabricate(:screened_email) }
|
||||
|
||||
describe '#index' do
|
||||
before do
|
||||
sign_in(Fabricate(:admin))
|
||||
shared_examples "screened emails accessible" do
|
||||
it "returns screened emails" do
|
||||
get "/admin/logs/screened_emails.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json.size).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns JSON' do
|
||||
Fabricate(:screened_email)
|
||||
get "/admin/logs/screened_emails.json"
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json.size).to eq(1)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
include_examples "screened emails accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "screened emails accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/logs/screened_emails.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
shared_examples "screened email deletion possible" do
|
||||
it "deletes screened email" do
|
||||
expect do
|
||||
delete "/admin/logs/screened_emails/#{screened_email.id}.json"
|
||||
end.to change { ScreenedEmail.count }.by(-1)
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
include_examples "screened email deletion possible"
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "screened email deletion possible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "prevents deletion with a 404 response" do
|
||||
delete "/admin/logs/screened_emails/#{screened_email.id}.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,47 +1,65 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::ScreenedIpAddressesController do
|
||||
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::ScreenedIpAddressesController < Admin::StaffController).to eq(true)
|
||||
end
|
||||
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
describe '#index' do
|
||||
it 'filters screened ip addresses' do
|
||||
Fabricate(:screened_ip_address, ip_address: "1.2.3.4")
|
||||
Fabricate(:screened_ip_address, ip_address: "1.2.3.5")
|
||||
Fabricate(:screened_ip_address, ip_address: "1.2.3.6")
|
||||
Fabricate(:screened_ip_address, ip_address: "4.5.6.7")
|
||||
Fabricate(:screened_ip_address, ip_address: "5.0.0.0/8")
|
||||
shared_examples "screened ip addresses accessible" do
|
||||
it 'filters screened ip addresses' do
|
||||
Fabricate(:screened_ip_address, ip_address: "1.2.3.4")
|
||||
Fabricate(:screened_ip_address, ip_address: "1.2.3.5")
|
||||
Fabricate(:screened_ip_address, ip_address: "1.2.3.6")
|
||||
Fabricate(:screened_ip_address, ip_address: "4.5.6.7")
|
||||
Fabricate(:screened_ip_address, ip_address: "5.0.0.0/8")
|
||||
|
||||
get "/admin/logs/screened_ip_addresses.json", params: { filter: "1.2.*" }
|
||||
get "/admin/logs/screened_ip_addresses.json", params: { filter: "1.2.*" }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body.map { |record| record["ip_address"] })
|
||||
.to contain_exactly("1.2.3.4", "1.2.3.5", "1.2.3.6")
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body.map { |record| record["ip_address"] })
|
||||
.to contain_exactly("1.2.3.4", "1.2.3.5", "1.2.3.6")
|
||||
|
||||
get "/admin/logs/screened_ip_addresses.json", params: { filter: "4.5.6.7" }
|
||||
get "/admin/logs/screened_ip_addresses.json", params: { filter: "4.5.6.7" }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body.map { |record| record["ip_address"] })
|
||||
.to contain_exactly("4.5.6.7")
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body.map { |record| record["ip_address"] })
|
||||
.to contain_exactly("4.5.6.7")
|
||||
|
||||
get "/admin/logs/screened_ip_addresses.json", params: { filter: "5.0.0.1" }
|
||||
get "/admin/logs/screened_ip_addresses.json", params: { filter: "5.0.0.1" }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body.map { |record| record["ip_address"] })
|
||||
.to contain_exactly("5.0.0.0/8")
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body.map { |record| record["ip_address"] })
|
||||
.to contain_exactly("5.0.0.0/8")
|
||||
|
||||
get "/admin/logs/screened_ip_addresses.json", params: { filter: "6.0.0.1" }
|
||||
get "/admin/logs/screened_ip_addresses.json", params: { filter: "6.0.0.1" }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body).to be_blank
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body).to be_blank
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
include_examples "screened ip addresses accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "screened ip addresses accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/logs/screened_ip_addresses.json", params: { filter: "1.2.*" }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,21 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::ScreenedUrlsController do
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::ScreenedUrlsController < Admin::StaffController).to eq(true)
|
||||
end
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:screened_url) { Fabricate(:screened_url) }
|
||||
|
||||
describe '#index' do
|
||||
before do
|
||||
sign_in(Fabricate(:admin))
|
||||
shared_examples "screened urls accessible" do
|
||||
it "returns screened urls" do
|
||||
get "/admin/logs/screened_urls.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json.size).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns JSON' do
|
||||
Fabricate(:screened_url)
|
||||
get "/admin/logs/screened_urls.json"
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json.size).to eq(1)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
include_examples "screened urls accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "screened urls accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/logs/screened_urls.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,99 +6,89 @@ RSpec.describe Admin::SearchLogsController do
|
|||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
SearchLog.log(term: 'ruby', search_type: :header, ip_address: '127.0.0.1')
|
||||
SearchLog.log(term: "ruby", search_type: :header, ip_address: "127.0.0.1")
|
||||
end
|
||||
|
||||
after do
|
||||
SearchLog.clear_debounce_cache!
|
||||
end
|
||||
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::SearchLogsController < Admin::StaffController).to eq(true)
|
||||
end
|
||||
|
||||
describe "#index" do
|
||||
it "raises an error if you aren't logged in" do
|
||||
get '/admin/logs/search_logs.json'
|
||||
expect(response.status).to eq(404)
|
||||
shared_examples "search logs accessible" do
|
||||
it "returns search logs" do
|
||||
get '/admin/logs/search_logs.json'
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json[0]["term"]).to eq("ruby")
|
||||
expect(json[0]["searches"]).to eq(1)
|
||||
expect(json[0]["ctr"]).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an error if you aren't an admin" do
|
||||
sign_in(user)
|
||||
get '/admin/logs/search_logs.json'
|
||||
expect(response.status).to eq(404)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
include_examples "search logs accessible"
|
||||
end
|
||||
|
||||
it "should work if you are an admin" do
|
||||
sign_in(admin)
|
||||
get '/admin/logs/search_logs.json'
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json[0]['term']).to eq('ruby')
|
||||
expect(json[0]['searches']).to eq(1)
|
||||
expect(json[0]['ctr']).to eq(0)
|
||||
include_examples "search logs accessible"
|
||||
end
|
||||
|
||||
it "should work if you are a moderator" do
|
||||
sign_in(moderator)
|
||||
get "/admin/logs/search_logs.json"
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/logs/search_logs.json"
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json[0]["term"]).to eq("ruby")
|
||||
expect(json[0]["searches"]).to eq(1)
|
||||
expect(json[0]["ctr"]).to eq(0)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#term" do
|
||||
it "raises an error if you aren't logged in" do
|
||||
get '/admin/logs/search_logs/term.json', params: {
|
||||
term: "ruby"
|
||||
}
|
||||
shared_examples "search log term accessible" do
|
||||
it "returns search log term" do
|
||||
get '/admin/logs/search_logs/term.json', params: {
|
||||
term: "ruby"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json['term']['type']).to eq('search_log_term')
|
||||
expect(json['term']['search_result']).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an error if you aren't an admin" do
|
||||
sign_in(user)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
get '/admin/logs/search_logs/term.json', params: {
|
||||
term: "ruby"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
include_examples "search log term accessible"
|
||||
end
|
||||
|
||||
it "should work if you are an admin" do
|
||||
sign_in(admin)
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
get '/admin/logs/search_logs/term.json', params: {
|
||||
term: "ruby"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json['term']['type']).to eq('search_log_term')
|
||||
expect(json['term']['search_result']).to be_present
|
||||
include_examples "search log term accessible"
|
||||
end
|
||||
|
||||
it "should work if you are a moderator" do
|
||||
sign_in(moderator)
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
get "/admin/logs/search_logs/term.json", params: {
|
||||
term: "ruby"
|
||||
}
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/logs/search_logs/term.json", params: {
|
||||
term: "ruby"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = response.parsed_body
|
||||
expect(json["term"]["type"]).to eq("search_log_term")
|
||||
expect(json["term"]["search_result"]).to be_present
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::SiteSettingsController do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::SiteSettingsController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
describe "#index" do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
context 'while logged in as an admin' do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
it 'returns valid info' do
|
||||
it "returns valid info" do
|
||||
get "/admin/site_settings.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["site_settings"].length).to be > 100
|
||||
|
@ -28,12 +24,205 @@ RSpec.describe Admin::SiteSettingsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
before do
|
||||
SiteSetting.setting(:test_setting, "default")
|
||||
SiteSetting.setting(:test_upload, "", type: :upload)
|
||||
SiteSetting.refresh!
|
||||
shared_examples "site settings inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/site_settings.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "site settings inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "site settings inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#user_count" do
|
||||
fab!(:staged_user) { Fabricate(:staged) }
|
||||
let(:tracking) { NotificationLevels.all[:tracking] }
|
||||
|
||||
before do
|
||||
SiteSetting.setting(:test_setting, "default")
|
||||
SiteSetting.setting(:test_upload, "", type: :upload)
|
||||
SiteSetting.refresh!
|
||||
end
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'should return correct user count for default categories change' do
|
||||
category_id = Fabricate(:category).id
|
||||
|
||||
put "/admin/site_settings/default_categories_watching/user_count.json", params: {
|
||||
default_categories_watching: category_id
|
||||
}
|
||||
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.where(staged: false).count)
|
||||
|
||||
CategoryUser.create!(category_id: category_id, notification_level: tracking, user: user)
|
||||
|
||||
put "/admin/site_settings/default_categories_watching/user_count.json", params: {
|
||||
default_categories_watching: category_id
|
||||
}
|
||||
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.where(staged: false).count - 1)
|
||||
|
||||
SiteSetting.setting(:default_categories_watching, "")
|
||||
end
|
||||
|
||||
it 'should return correct user count for default tags change' do
|
||||
tag = Fabricate(:tag)
|
||||
|
||||
put "/admin/site_settings/default_tags_watching/user_count.json", params: {
|
||||
default_tags_watching: tag.name
|
||||
}
|
||||
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.where(staged: false).count)
|
||||
|
||||
TagUser.create!(tag_id: tag.id, notification_level: tracking, user: user)
|
||||
|
||||
put "/admin/site_settings/default_tags_watching/user_count.json", params: {
|
||||
default_tags_watching: tag.name
|
||||
}
|
||||
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.where(staged: false).count - 1)
|
||||
|
||||
SiteSetting.setting(:default_tags_watching, "")
|
||||
end
|
||||
|
||||
context "for sidebar defaults" do
|
||||
it 'returns the right count for the default_sidebar_categories site setting' do
|
||||
category = Fabricate(:category)
|
||||
|
||||
put "/admin/site_settings/default_sidebar_categories/user_count.json", params: {
|
||||
default_sidebar_categories: "#{category.id}"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.not_staged.count)
|
||||
end
|
||||
|
||||
it 'returns the right count for the default_sidebar_tags site setting' do
|
||||
tag = Fabricate(:tag)
|
||||
|
||||
put "/admin/site_settings/default_sidebar_tags/user_count.json", params: {
|
||||
default_sidebar_tags: "#{tag.name}"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.not_staged.count)
|
||||
end
|
||||
end
|
||||
|
||||
context "with user options" do
|
||||
def expect_user_count(site_setting_name:, user_setting_name:, current_site_setting_value:, new_site_setting_value:,
|
||||
current_user_setting_value: nil, new_user_setting_value: nil)
|
||||
|
||||
current_user_setting_value ||= current_site_setting_value
|
||||
new_user_setting_value ||= new_site_setting_value
|
||||
|
||||
SiteSetting.public_send("#{site_setting_name}=", current_site_setting_value)
|
||||
UserOption.human_users.update_all(user_setting_name => current_user_setting_value)
|
||||
user_count = User.human_users.count
|
||||
|
||||
# Correctly counts users when all of them have default value
|
||||
put "/admin/site_settings/#{site_setting_name}/user_count.json", params: {
|
||||
site_setting_name => new_site_setting_value
|
||||
}
|
||||
expect(response.parsed_body["user_count"]).to eq(user_count)
|
||||
|
||||
# Correctly counts users when one of them already has new value
|
||||
user.user_option.update!(user_setting_name => new_user_setting_value)
|
||||
put "/admin/site_settings/#{site_setting_name}/user_count.json", params: {
|
||||
site_setting_name => new_site_setting_value
|
||||
}
|
||||
expect(response.parsed_body["user_count"]).to eq(user_count - 1)
|
||||
|
||||
# Correctly counts users when site setting value has been changed
|
||||
SiteSetting.public_send("#{site_setting_name}=", new_site_setting_value)
|
||||
put "/admin/site_settings/#{site_setting_name}/user_count.json", params: {
|
||||
site_setting_name => current_site_setting_value
|
||||
}
|
||||
expect(response.parsed_body["user_count"]).to eq(1)
|
||||
end
|
||||
|
||||
it "should return correct user count for boolean setting" do
|
||||
expect_user_count(
|
||||
site_setting_name: "default_other_external_links_in_new_tab",
|
||||
user_setting_name: "external_links_in_new_tab",
|
||||
current_site_setting_value: false,
|
||||
new_site_setting_value: true
|
||||
)
|
||||
end
|
||||
|
||||
it "should return correct user count for 'text_size_key'" do
|
||||
expect_user_count(
|
||||
site_setting_name: "default_text_size",
|
||||
user_setting_name: "text_size_key",
|
||||
current_site_setting_value: "normal",
|
||||
new_site_setting_value: "larger",
|
||||
current_user_setting_value: UserOption.text_sizes[:normal],
|
||||
new_user_setting_value: UserOption.text_sizes[:larger]
|
||||
)
|
||||
end
|
||||
|
||||
it "should return correct user count for 'title_count_mode_key'" do
|
||||
expect_user_count(
|
||||
site_setting_name: "default_title_count_mode",
|
||||
user_setting_name: "title_count_mode_key",
|
||||
current_site_setting_value: "notifications",
|
||||
new_site_setting_value: "contextual",
|
||||
current_user_setting_value: UserOption.title_count_modes[:notifications],
|
||||
new_user_setting_value: UserOption.title_count_modes[:contextual]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "user counts inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
category_id = Fabricate(:category).id
|
||||
|
||||
put "/admin/site_settings/default_categories_watching/user_count.json", params: {
|
||||
default_categories_watching: category_id
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "user counts inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "user counts inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
before do
|
||||
SiteSetting.setting(:test_setting, "default")
|
||||
SiteSetting.setting(:test_upload, "", type: :upload)
|
||||
SiteSetting.refresh!
|
||||
end
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'sets the value when the param is present' do
|
||||
put "/admin/site_settings/test_setting.json", params: {
|
||||
|
@ -70,7 +259,7 @@ RSpec.describe Admin::SiteSettingsController do
|
|||
expect(SiteSetting.test_setting).to eq('')
|
||||
end
|
||||
|
||||
describe 'default user options' do
|
||||
context "with default user options" do
|
||||
let!(:user1) { Fabricate(:user) }
|
||||
let!(:user2) { Fabricate(:user) }
|
||||
|
||||
|
@ -154,7 +343,7 @@ RSpec.describe Admin::SiteSettingsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'default categories' do
|
||||
context "with default categories" do
|
||||
fab!(:user1) { Fabricate(:user) }
|
||||
fab!(:user2) { Fabricate(:user) }
|
||||
fab!(:staged_user) { Fabricate(:staged) }
|
||||
|
@ -219,7 +408,7 @@ RSpec.describe Admin::SiteSettingsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'default tags' do
|
||||
context "with default tags" do
|
||||
fab!(:user1) { Fabricate(:user) }
|
||||
fab!(:user2) { Fabricate(:user) }
|
||||
fab!(:staged_user) { Fabricate(:staged) }
|
||||
|
@ -258,141 +447,7 @@ RSpec.describe Admin::SiteSettingsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#user_count' do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:staged_user) { Fabricate(:staged) }
|
||||
let(:tracking) { NotificationLevels.all[:tracking] }
|
||||
|
||||
it 'should return correct user count for default categories change' do
|
||||
category_id = Fabricate(:category).id
|
||||
|
||||
put "/admin/site_settings/default_categories_watching/user_count.json", params: {
|
||||
default_categories_watching: category_id
|
||||
}
|
||||
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.where(staged: false).count)
|
||||
|
||||
CategoryUser.create!(category_id: category_id, notification_level: tracking, user: user)
|
||||
|
||||
put "/admin/site_settings/default_categories_watching/user_count.json", params: {
|
||||
default_categories_watching: category_id
|
||||
}
|
||||
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.where(staged: false).count - 1)
|
||||
|
||||
SiteSetting.setting(:default_categories_watching, "")
|
||||
end
|
||||
|
||||
it 'should return correct user count for default tags change' do
|
||||
tag = Fabricate(:tag)
|
||||
|
||||
put "/admin/site_settings/default_tags_watching/user_count.json", params: {
|
||||
default_tags_watching: tag.name
|
||||
}
|
||||
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.where(staged: false).count)
|
||||
|
||||
TagUser.create!(tag_id: tag.id, notification_level: tracking, user: user)
|
||||
|
||||
put "/admin/site_settings/default_tags_watching/user_count.json", params: {
|
||||
default_tags_watching: tag.name
|
||||
}
|
||||
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.where(staged: false).count - 1)
|
||||
|
||||
SiteSetting.setting(:default_tags_watching, "")
|
||||
end
|
||||
|
||||
context "for sidebar defaults" do
|
||||
it 'returns the right count for the default_sidebar_categories site setting' do
|
||||
category = Fabricate(:category)
|
||||
|
||||
put "/admin/site_settings/default_sidebar_categories/user_count.json", params: {
|
||||
default_sidebar_categories: "#{category.id}"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.not_staged.count)
|
||||
end
|
||||
|
||||
it 'returns the right count for the default_sidebar_tags site setting' do
|
||||
tag = Fabricate(:tag)
|
||||
|
||||
put "/admin/site_settings/default_sidebar_tags/user_count.json", params: {
|
||||
default_sidebar_tags: "#{tag.name}"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["user_count"]).to eq(User.real.not_staged.count)
|
||||
end
|
||||
end
|
||||
|
||||
context "with user options" do
|
||||
def expect_user_count(site_setting_name:, user_setting_name:, current_site_setting_value:, new_site_setting_value:,
|
||||
current_user_setting_value: nil, new_user_setting_value: nil)
|
||||
|
||||
current_user_setting_value ||= current_site_setting_value
|
||||
new_user_setting_value ||= new_site_setting_value
|
||||
|
||||
SiteSetting.public_send("#{site_setting_name}=", current_site_setting_value)
|
||||
UserOption.human_users.update_all(user_setting_name => current_user_setting_value)
|
||||
user_count = User.human_users.count
|
||||
|
||||
# Correctly counts users when all of them have default value
|
||||
put "/admin/site_settings/#{site_setting_name}/user_count.json", params: {
|
||||
site_setting_name => new_site_setting_value
|
||||
}
|
||||
expect(response.parsed_body["user_count"]).to eq(user_count)
|
||||
|
||||
# Correctly counts users when one of them already has new value
|
||||
user.user_option.update!(user_setting_name => new_user_setting_value)
|
||||
put "/admin/site_settings/#{site_setting_name}/user_count.json", params: {
|
||||
site_setting_name => new_site_setting_value
|
||||
}
|
||||
expect(response.parsed_body["user_count"]).to eq(user_count - 1)
|
||||
|
||||
# Correctly counts users when site setting value has been changed
|
||||
SiteSetting.public_send("#{site_setting_name}=", new_site_setting_value)
|
||||
put "/admin/site_settings/#{site_setting_name}/user_count.json", params: {
|
||||
site_setting_name => current_site_setting_value
|
||||
}
|
||||
expect(response.parsed_body["user_count"]).to eq(1)
|
||||
end
|
||||
|
||||
it "should return correct user count for boolean setting" do
|
||||
expect_user_count(
|
||||
site_setting_name: "default_other_external_links_in_new_tab",
|
||||
user_setting_name: "external_links_in_new_tab",
|
||||
current_site_setting_value: false,
|
||||
new_site_setting_value: true
|
||||
)
|
||||
end
|
||||
|
||||
it "should return correct user count for 'text_size_key'" do
|
||||
expect_user_count(
|
||||
site_setting_name: "default_text_size",
|
||||
user_setting_name: "text_size_key",
|
||||
current_site_setting_value: "normal",
|
||||
new_site_setting_value: "larger",
|
||||
current_user_setting_value: UserOption.text_sizes[:normal],
|
||||
new_user_setting_value: UserOption.text_sizes[:larger]
|
||||
)
|
||||
end
|
||||
|
||||
it "should return correct user count for 'title_count_mode_key'" do
|
||||
expect_user_count(
|
||||
site_setting_name: "default_title_count_mode",
|
||||
user_setting_name: "title_count_mode_key",
|
||||
current_site_setting_value: "notifications",
|
||||
new_site_setting_value: "contextual",
|
||||
current_user_setting_value: UserOption.title_count_modes[:notifications],
|
||||
new_user_setting_value: UserOption.title_count_modes[:contextual]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'upload site settings' do
|
||||
context "with upload site settings" do
|
||||
it 'can remove the site setting' do
|
||||
SiteSetting.test_upload = Fabricate(:upload)
|
||||
|
||||
|
@ -467,5 +522,28 @@ RSpec.describe Admin::SiteSettingsController do
|
|||
expect(response.status).to eq(422)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "site setting update not allowed" do
|
||||
it "prevents updates with a 404 response" do
|
||||
put "/admin/site_settings/test_setting.json", params: {
|
||||
test_setting: 'hello'
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "site setting update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "site setting update not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
RSpec.describe Admin::SiteTextsController do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
let(:default_locale) { I18n.locale }
|
||||
|
||||
|
@ -10,40 +11,10 @@ RSpec.describe Admin::SiteTextsController do
|
|||
I18n.reload!
|
||||
end
|
||||
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::SiteTextsController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
describe '#index' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
context "when not logged in as an admin" do
|
||||
it "raises an error if you aren't logged in" do
|
||||
put '/admin/customize/site_texts/some_key.json', params: {
|
||||
site_text: { value: 'foo' }, locale: default_locale
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "raises an error if you aren't an admin" do
|
||||
sign_in(user)
|
||||
|
||||
put "/admin/customize/site_texts/some_key.json", params: {
|
||||
site_text: { value: 'foo' }, locale: default_locale
|
||||
}
|
||||
expect(response.status).to eq(404)
|
||||
|
||||
put "/admin/customize/reseed.json", params: {
|
||||
category_ids: [], topic_ids: []
|
||||
}
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as admin" do
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
it 'returns json' do
|
||||
get "/admin/customize/site_texts.json", params: { q: 'title', locale: default_locale }
|
||||
expect(response.status).to eq(200)
|
||||
|
@ -232,7 +203,32 @@ RSpec.describe Admin::SiteTextsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#show' do
|
||||
shared_examples "site texts inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/customize/site_texts.json", params: { q: 'title', locale: default_locale }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "site texts inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "site texts inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#show' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'returns a site text for a key that exists' do
|
||||
get "/admin/customize/site_texts/js.topic.list.json", params: { locale: default_locale }
|
||||
expect(response.status).to eq(200)
|
||||
|
@ -373,7 +369,32 @@ RSpec.describe Admin::SiteTextsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#update & #revert' do
|
||||
shared_examples "site text inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/customize/site_texts/js.topic.list.json", params: { locale: default_locale }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "site text inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "site text inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update & #revert' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns 'not found' when an unknown key is used" do
|
||||
put '/admin/customize/site_texts/some_key.json', params: {
|
||||
site_text: { value: 'foo', locale: default_locale }
|
||||
|
@ -551,26 +572,53 @@ RSpec.describe Admin::SiteTextsController do
|
|||
end
|
||||
end
|
||||
|
||||
context "when reseeding" do
|
||||
before do
|
||||
staff_category = Fabricate(
|
||||
:category,
|
||||
name: "Staff EN",
|
||||
user: Discourse.system_user
|
||||
)
|
||||
SiteSetting.staff_category_id = staff_category.id
|
||||
shared_examples "site text update not allowed" do
|
||||
it "prevents updates with a 404 response" do
|
||||
put "/admin/customize/site_texts/js.emoji_picker.animals_%26_nature.json", params: {
|
||||
site_text: { value: 'foo', locale: default_locale }
|
||||
}
|
||||
|
||||
guidelines_topic = Fabricate(
|
||||
:topic,
|
||||
title: "The English Guidelines",
|
||||
category: @staff_category,
|
||||
user: Discourse.system_user
|
||||
)
|
||||
Fabricate(:post, topic: guidelines_topic, user: Discourse.system_user)
|
||||
SiteSetting.guidelines_topic_id = guidelines_topic.id
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "site text update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "site text update not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
context "when reseeding" do
|
||||
before do
|
||||
staff_category = Fabricate(
|
||||
:category,
|
||||
name: "Staff EN",
|
||||
user: Discourse.system_user
|
||||
)
|
||||
SiteSetting.staff_category_id = staff_category.id
|
||||
|
||||
guidelines_topic = Fabricate(
|
||||
:topic,
|
||||
title: "The English Guidelines",
|
||||
category: @staff_category,
|
||||
user: Discourse.system_user
|
||||
)
|
||||
Fabricate(:post, topic: guidelines_topic, user: Discourse.system_user)
|
||||
SiteSetting.guidelines_topic_id = guidelines_topic.id
|
||||
end
|
||||
|
||||
describe '#get_reseed_options' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
describe '#get_reseed_options' do
|
||||
it 'returns correct json' do
|
||||
get "/admin/customize/reseed.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
@ -587,7 +635,32 @@ RSpec.describe Admin::SiteTextsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#reseed' do
|
||||
shared_examples "reseed options inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/customize/reseed.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "reseed options inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "reseed options inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reseed' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'reseeds categories and topics' do
|
||||
SiteSetting.default_locale = :de
|
||||
|
||||
|
@ -601,6 +674,30 @@ RSpec.describe Admin::SiteTextsController do
|
|||
expect(Topic.find(SiteSetting.guidelines_topic_id).title).to eq(I18n.t("guidelines_topic.title", locale: :de))
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "reseed not allowed" do
|
||||
it "prevents reseeds with a 404 response" do
|
||||
post "/admin/customize/reseed.json", params: {
|
||||
category_ids: ["staff_category_id"],
|
||||
topic_ids: ["guidelines_topic_id"]
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "reseed not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "reseed not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,99 +1,146 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::StaffActionLogsController do
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::StaffActionLogsController < Admin::StaffController).to eq(true)
|
||||
end
|
||||
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
describe '#index' do
|
||||
it 'generates logs' do
|
||||
topic = Fabricate(:topic)
|
||||
StaffActionLogger.new(Discourse.system_user).log_topic_delete_recover(topic, "delete_topic")
|
||||
shared_examples "staff action logs accessible" do
|
||||
it 'returns logs' do
|
||||
topic = Fabricate(:topic)
|
||||
StaffActionLogger.new(Discourse.system_user).log_topic_delete_recover(topic, "delete_topic")
|
||||
|
||||
get "/admin/logs/staff_action_logs.json", params: { action_id: UserHistory.actions[:delete_topic] }
|
||||
|
||||
json = response.parsed_body
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
expect(json["staff_action_logs"].length).to eq(1)
|
||||
expect(json["staff_action_logs"][0]["action_name"]).to eq("delete_topic")
|
||||
|
||||
expect(json["extras"]["user_history_actions"]).to include(
|
||||
"id" => 'delete_topic', "action_id" => UserHistory.actions[:delete_topic]
|
||||
)
|
||||
end
|
||||
|
||||
it 'generates logs with pages' do
|
||||
1.upto(4).each do |idx|
|
||||
StaffActionLogger.new(Discourse.system_user).log_site_setting_change("title", "value #{idx - 1}", "value #{idx}")
|
||||
end
|
||||
|
||||
get "/admin/logs/staff_action_logs.json", params: { limit: 3 }
|
||||
|
||||
json = response.parsed_body
|
||||
expect(response.status).to eq(200)
|
||||
expect(json["staff_action_logs"].length).to eq(3)
|
||||
expect(json["staff_action_logs"][0]["new_value"]).to eq("value 4")
|
||||
|
||||
get "/admin/logs/staff_action_logs.json", params: { limit: 3, page: 1 }
|
||||
|
||||
json = response.parsed_body
|
||||
expect(response.status).to eq(200)
|
||||
expect(json["staff_action_logs"].length).to eq(1)
|
||||
expect(json["staff_action_logs"][0]["new_value"]).to eq("value 1")
|
||||
end
|
||||
|
||||
context 'when staff actions are extended' do
|
||||
let(:plugin_extended_action) { :confirmed_ham }
|
||||
before { UserHistory.stubs(:staff_actions).returns([plugin_extended_action]) }
|
||||
after { UserHistory.unstub(:staff_actions) }
|
||||
|
||||
it 'Uses the custom_staff id' do
|
||||
get "/admin/logs/staff_action_logs.json", params: {}
|
||||
get "/admin/logs/staff_action_logs.json", params: { action_id: UserHistory.actions[:delete_topic] }
|
||||
|
||||
json = response.parsed_body
|
||||
action = json['extras']['user_history_actions'].first
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
expect(action['id']).to eq plugin_extended_action.to_s
|
||||
expect(action['action_id']).to eq UserHistory.actions[:custom_staff]
|
||||
expect(json["staff_action_logs"].length).to eq(1)
|
||||
expect(json["staff_action_logs"][0]["action_name"]).to eq("delete_topic")
|
||||
|
||||
expect(json["extras"]["user_history_actions"]).to include(
|
||||
"id" => 'delete_topic', "action_id" => UserHistory.actions[:delete_topic]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
include_examples "staff action logs accessible"
|
||||
|
||||
it 'generates logs with pages' do
|
||||
1.upto(4).each do |idx|
|
||||
StaffActionLogger.new(Discourse.system_user).log_site_setting_change("title", "value #{idx - 1}", "value #{idx}")
|
||||
end
|
||||
|
||||
get "/admin/logs/staff_action_logs.json", params: { limit: 3 }
|
||||
|
||||
json = response.parsed_body
|
||||
expect(response.status).to eq(200)
|
||||
expect(json["staff_action_logs"].length).to eq(3)
|
||||
expect(json["staff_action_logs"][0]["new_value"]).to eq("value 4")
|
||||
|
||||
get "/admin/logs/staff_action_logs.json", params: { limit: 3, page: 1 }
|
||||
|
||||
json = response.parsed_body
|
||||
expect(response.status).to eq(200)
|
||||
expect(json["staff_action_logs"].length).to eq(1)
|
||||
expect(json["staff_action_logs"][0]["new_value"]).to eq("value 1")
|
||||
end
|
||||
|
||||
context 'when staff actions are extended' do
|
||||
let(:plugin_extended_action) { :confirmed_ham }
|
||||
before { UserHistory.stubs(:staff_actions).returns([plugin_extended_action]) }
|
||||
after { UserHistory.unstub(:staff_actions) }
|
||||
|
||||
it 'Uses the custom_staff id' do
|
||||
get "/admin/logs/staff_action_logs.json", params: {}
|
||||
|
||||
json = response.parsed_body
|
||||
action = json['extras']['user_history_actions'].first
|
||||
|
||||
expect(action['id']).to eq plugin_extended_action.to_s
|
||||
expect(action['action_id']).to eq UserHistory.actions[:custom_staff]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "staff action logs accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/logs/staff_action_logs.json", params: { action_id: UserHistory.actions[:delete_topic] }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#diff' do
|
||||
it 'can generate diffs for theme changes' do
|
||||
theme = Fabricate(:theme)
|
||||
theme.set_field(target: :mobile, name: :scss, value: 'body {.up}')
|
||||
theme.set_field(target: :common, name: :scss, value: 'omit-dupe')
|
||||
shared_examples "theme diffs accessible" do
|
||||
it 'generates diffs for theme changes' do
|
||||
theme = Fabricate(:theme)
|
||||
theme.set_field(target: :mobile, name: :scss, value: 'body {.up}')
|
||||
theme.set_field(target: :common, name: :scss, value: 'omit-dupe')
|
||||
|
||||
original_json = ThemeSerializer.new(theme, root: false).to_json
|
||||
original_json = ThemeSerializer.new(theme, root: false).to_json
|
||||
|
||||
theme.set_field(target: :mobile, name: :scss, value: 'body {.down}')
|
||||
theme.set_field(target: :mobile, name: :scss, value: 'body {.down}')
|
||||
|
||||
record = StaffActionLogger.new(Discourse.system_user)
|
||||
.log_theme_change(original_json, theme)
|
||||
record = StaffActionLogger.new(Discourse.system_user)
|
||||
.log_theme_change(original_json, theme)
|
||||
|
||||
get "/admin/logs/staff_action_logs/#{record.id}/diff.json"
|
||||
expect(response.status).to eq(200)
|
||||
get "/admin/logs/staff_action_logs/#{record.id}/diff.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
parsed = response.parsed_body
|
||||
expect(parsed["side_by_side"]).to include("up")
|
||||
expect(parsed["side_by_side"]).to include("down")
|
||||
parsed = response.parsed_body
|
||||
expect(parsed["side_by_side"]).to include("up")
|
||||
expect(parsed["side_by_side"]).to include("down")
|
||||
|
||||
expect(parsed["side_by_side"]).not_to include("omit-dupe")
|
||||
expect(parsed["side_by_side"]).not_to include("omit-dupe")
|
||||
end
|
||||
end
|
||||
|
||||
it 'is not erroring when current value is empty' do
|
||||
theme = Fabricate(:theme)
|
||||
StaffActionLogger.new(admin).log_theme_destroy(theme)
|
||||
get "/admin/logs/staff_action_logs/#{UserHistory.last.id}/diff.json"
|
||||
expect(response.status).to eq(200)
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
include_examples "theme diffs accessible"
|
||||
|
||||
it 'is not erroring when current value is empty' do
|
||||
theme = Fabricate(:theme)
|
||||
StaffActionLogger.new(admin).log_theme_destroy(theme)
|
||||
get "/admin/logs/staff_action_logs/#{UserHistory.last.id}/diff.json"
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "theme diffs accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
theme = Fabricate(:theme)
|
||||
StaffActionLogger.new(admin).log_theme_destroy(theme)
|
||||
|
||||
get "/admin/logs/staff_action_logs/#{UserHistory.last.id}/diff.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,18 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::UserFieldsController do
|
||||
it "is a subclass of AdminController" do
|
||||
expect(Admin::UserFieldsController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
context "when logged in" do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
describe '#create' do
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
it "creates a user field" do
|
||||
expect {
|
||||
post "/admin/customize/user_fields.json", params: {
|
||||
|
@ -41,8 +37,37 @@ RSpec.describe Admin::UserFieldsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
fab!(:user_field) { Fabricate(:user_field) }
|
||||
shared_examples "user field creation not allowed" do
|
||||
it "prevents creation with a 404 response" do
|
||||
expect do
|
||||
post "/admin/customize/user_fields.json", params: {
|
||||
user_field: { name: 'hello', description: 'hello desc', field_type: 'text' }
|
||||
}
|
||||
end.not_to change { UserField.count }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "user field creation not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "user field creation not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
fab!(:user_field) { Fabricate(:user_field) }
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "returns a list of user fields" do
|
||||
get "/admin/customize/user_fields.json"
|
||||
|
@ -52,8 +77,34 @@ RSpec.describe Admin::UserFieldsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
fab!(:user_field) { Fabricate(:user_field) }
|
||||
shared_examples "user fields inaccessible" do
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/customize/user_fields.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(response.parsed_body['user_fields']).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "user fields inaccessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "user fields inaccessible"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
fab!(:user_field) { Fabricate(:user_field) }
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "deletes the user field" do
|
||||
expect {
|
||||
|
@ -63,8 +114,35 @@ RSpec.describe Admin::UserFieldsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
fab!(:user_field) { Fabricate(:user_field) }
|
||||
shared_examples "user field deletion not allowed" do
|
||||
it "prevents deletion with a 404 response" do
|
||||
expect do
|
||||
delete "/admin/customize/user_fields/#{user_field.id}.json"
|
||||
end.not_to change { UserField.count }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "user field deletion not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "user field deletion not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
fab!(:user_field) { Fabricate(:user_field) }
|
||||
|
||||
context "when logged in as an admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "updates the user field" do
|
||||
put "/admin/customize/user_fields/#{user_field.id}.json", params: {
|
||||
|
@ -138,5 +216,34 @@ RSpec.describe Admin::UserFieldsController do
|
|||
}.to change { DirectoryColumn.count }.by(-1)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "user field update not allowed" do
|
||||
it "prevents updates with a 404 response" do
|
||||
user_field.reload
|
||||
original_name = user_field.name
|
||||
|
||||
put "/admin/customize/user_fields/#{user_field.id}.json", params: {
|
||||
user_field: { name: 'fraggle', field_type: 'confirm', description: 'muppet' }
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
|
||||
user_field.reload
|
||||
expect(user_field.name).to eq(original_name)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "user field update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "user field update not allowed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::VersionsController do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
Jobs::VersionCheck.any_instance.stubs(:execute).returns(true)
|
||||
|
@ -9,17 +12,8 @@ RSpec.describe Admin::VersionsController do
|
|||
DiscourseUpdates.stubs(:critical_updates_available?).returns(false)
|
||||
end
|
||||
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::VersionsController < Admin::StaffController).to eq(true)
|
||||
end
|
||||
|
||||
context 'while logged in as an admin' do
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe 'show' do
|
||||
describe "#show" do
|
||||
shared_examples "version info accessible" do
|
||||
it 'should return the currently available version' do
|
||||
get "/admin/version_check.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
@ -34,5 +28,30 @@ RSpec.describe Admin::VersionsController do
|
|||
expect(json['installed_version']).to eq(Discourse::VERSION::STRING)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when logged in as admin' do
|
||||
before { sign_in(admin) }
|
||||
|
||||
include_examples "version info accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "version info accessible"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
it "denies access with a 404 response" do
|
||||
get "/admin/version_check.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(response.parsed_body["latest_version"]).to be_nil
|
||||
expect(response.parsed_body["installed_version"]).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,10 +6,6 @@ RSpec.describe Admin::WatchedWordsController do
|
|||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
it "is a subclass of StaffController" do
|
||||
expect(Admin::WatchedWordsController < Admin::StaffController).to eq(true)
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
fab!(:watched_word) { Fabricate(:watched_word) }
|
||||
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Admin::WebHooksController do
|
||||
fab!(:web_hook) { Fabricate(:web_hook) }
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
|
||||
it 'is a subclass of AdminController' do
|
||||
expect(Admin::WebHooksController < Admin::AdminController).to eq(true)
|
||||
end
|
||||
describe '#create' do
|
||||
context "when logged in as admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
context 'while logged in as an admin' do
|
||||
fab!(:web_hook) { Fabricate(:web_hook) }
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
it 'creates a webhook' do
|
||||
post "/admin/api/web_hooks.json", params: {
|
||||
web_hook: {
|
||||
|
@ -58,7 +53,45 @@ RSpec.describe Admin::WebHooksController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
shared_examples "webhook creation not allowed" do
|
||||
it "prevents creation with a 404 response" do
|
||||
post "/admin/api/web_hooks.json", params: {
|
||||
web_hook: {
|
||||
payload_url: 'https://meta.discourse.org/',
|
||||
content_type: 1,
|
||||
secret: "a_secret_for_webhooks",
|
||||
wildcard_web_hook: false,
|
||||
active: true,
|
||||
verify_certificate: true,
|
||||
web_hook_event_type_ids: [1],
|
||||
group_ids: [],
|
||||
category_ids: []
|
||||
}
|
||||
}
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(response.parsed_body["web_hook"]).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "webhook creation not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "webhook creation not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
context "when logged in as admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "logs webhook update" do
|
||||
put "/admin/api/web_hooks/#{web_hook.id}.json", params: {
|
||||
web_hook: { active: false, payload_url: "https://test.com" }
|
||||
|
@ -71,7 +104,37 @@ RSpec.describe Admin::WebHooksController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
shared_examples "webhook update not allowed" do
|
||||
it "prevents updates with a 404 response" do
|
||||
current_payload_url = web_hook.payload_url
|
||||
put "/admin/api/web_hooks/#{web_hook.id}.json", params: {
|
||||
web_hook: { active: false, payload_url: "https://test.com" }
|
||||
}
|
||||
|
||||
web_hook.reload
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(web_hook.payload_url).to eq(current_payload_url)
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "webhook update not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "webhook update not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
context "when logged in as admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it "logs webhook destroy" do
|
||||
delete "/admin/api/web_hooks/#{web_hook.id}.json", params: {
|
||||
web_hook: { active: false, payload_url: "https://test.com" }
|
||||
|
@ -82,7 +145,33 @@ RSpec.describe Admin::WebHooksController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#ping' do
|
||||
shared_examples "webhook deletion not allowed" do
|
||||
it "prevents deletion with a 404 response" do
|
||||
delete "/admin/api/web_hooks/#{web_hook.id}.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
expect(web_hook.reload).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "webhook deletion not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "webhook deletion not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#ping' do
|
||||
context "when logged in as admin" do
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'enqueues the ping event' do
|
||||
expect do
|
||||
post "/admin/api/web_hooks/#{web_hook.id}/ping.json"
|
||||
|
@ -95,62 +184,87 @@ RSpec.describe Admin::WebHooksController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#redeliver_event' do
|
||||
let!(:web_hook_event) do
|
||||
WebHookEvent.create!(
|
||||
web_hook: web_hook,
|
||||
payload: "abc",
|
||||
headers: JSON.dump(aa: "1", bb: "2"),
|
||||
shared_examples "webhook ping not allowed" do
|
||||
it "fails to enqueue a ping with 404 response" do
|
||||
expect do
|
||||
post "/admin/api/web_hooks/#{web_hook.id}/ping.json"
|
||||
end.not_to change { Jobs::EmitWebHookEvent.jobs.size }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in as a moderator" do
|
||||
before { sign_in(moderator) }
|
||||
|
||||
include_examples "webhook ping not allowed"
|
||||
end
|
||||
|
||||
context "when logged in as a non-staff user" do
|
||||
before { sign_in(user) }
|
||||
|
||||
include_examples "webhook ping not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#redeliver_event' do
|
||||
let!(:web_hook_event) do
|
||||
WebHookEvent.create!(
|
||||
web_hook: web_hook,
|
||||
payload: "abc",
|
||||
headers: JSON.dump(aa: "1", bb: "2"),
|
||||
)
|
||||
end
|
||||
|
||||
before { sign_in(admin) }
|
||||
|
||||
it 'emits the web hook and updates the response headers and body' do
|
||||
stub_request(:post, web_hook.payload_url)
|
||||
.with(body: "abc", headers: { "aa" => 1, "bb" => 2 })
|
||||
.to_return(
|
||||
status: 402,
|
||||
body: "efg",
|
||||
headers: { "Content-Type" => "application/json", "yoo" => "man" }
|
||||
)
|
||||
end
|
||||
post "/admin/api/web_hooks/#{web_hook.id}/events/#{web_hook_event.id}/redeliver.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
it 'emits the web hook and updates the response headers and body' do
|
||||
stub_request(:post, web_hook.payload_url)
|
||||
.with(body: "abc", headers: { "aa" => 1, "bb" => 2 })
|
||||
.to_return(
|
||||
status: 402,
|
||||
body: "efg",
|
||||
headers: { "Content-Type" => "application/json", "yoo" => "man" }
|
||||
)
|
||||
parsed_event = response.parsed_body["web_hook_event"]
|
||||
expect(parsed_event["id"]).to eq(web_hook_event.id)
|
||||
expect(parsed_event["status"]).to eq(402)
|
||||
|
||||
expect(JSON.parse(parsed_event["headers"])).to eq({ "aa" => "1", "bb" => "2" })
|
||||
expect(parsed_event["payload"]).to eq("abc")
|
||||
|
||||
expect(JSON.parse(parsed_event["response_headers"])).to eq({ "content-type" => "application/json", "yoo" => "man" })
|
||||
expect(parsed_event["response_body"]).to eq("efg")
|
||||
end
|
||||
|
||||
it "doesn't emit the web hook if the payload URL resolves to an internal IP" do
|
||||
FinalDestination::TestHelper.stub_to_fail do
|
||||
post "/admin/api/web_hooks/#{web_hook.id}/events/#{web_hook_event.id}/redeliver.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
parsed_event = response.parsed_body["web_hook_event"]
|
||||
expect(parsed_event["id"]).to eq(web_hook_event.id)
|
||||
expect(parsed_event["status"]).to eq(402)
|
||||
|
||||
expect(JSON.parse(parsed_event["headers"])).to eq({ "aa" => "1", "bb" => "2" })
|
||||
expect(parsed_event["payload"]).to eq("abc")
|
||||
|
||||
expect(JSON.parse(parsed_event["response_headers"])).to eq({ "content-type" => "application/json", "yoo" => "man" })
|
||||
expect(parsed_event["response_body"]).to eq("efg")
|
||||
end
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
it "doesn't emit the web hook if the payload URL resolves to an internal IP" do
|
||||
FinalDestination::TestHelper.stub_to_fail do
|
||||
post "/admin/api/web_hooks/#{web_hook.id}/events/#{web_hook_event.id}/redeliver.json"
|
||||
end
|
||||
expect(response.status).to eq(200)
|
||||
parsed_event = response.parsed_body["web_hook_event"]
|
||||
expect(parsed_event["id"]).to eq(web_hook_event.id)
|
||||
expect(parsed_event["response_headers"]).to eq({ error: I18n.t("webhooks.payload_url.blocked_or_internal") }.to_json)
|
||||
expect(parsed_event["status"]).to eq(-1)
|
||||
expect(parsed_event["response_body"]).to eq(nil)
|
||||
end
|
||||
|
||||
parsed_event = response.parsed_body["web_hook_event"]
|
||||
expect(parsed_event["id"]).to eq(web_hook_event.id)
|
||||
expect(parsed_event["response_headers"]).to eq({ error: I18n.t("webhooks.payload_url.blocked_or_internal") }.to_json)
|
||||
expect(parsed_event["status"]).to eq(-1)
|
||||
expect(parsed_event["response_body"]).to eq(nil)
|
||||
it "doesn't emit the web hook if the payload URL resolves to a blocked IP" do
|
||||
FinalDestination::TestHelper.stub_to_fail do
|
||||
post "/admin/api/web_hooks/#{web_hook.id}/events/#{web_hook_event.id}/redeliver.json"
|
||||
end
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
it "doesn't emit the web hook if the payload URL resolves to a blocked IP" do
|
||||
FinalDestination::TestHelper.stub_to_fail do
|
||||
post "/admin/api/web_hooks/#{web_hook.id}/events/#{web_hook_event.id}/redeliver.json"
|
||||
end
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
parsed_event = response.parsed_body["web_hook_event"]
|
||||
expect(parsed_event["id"]).to eq(web_hook_event.id)
|
||||
expect(parsed_event["response_headers"]).to eq({ error: I18n.t("webhooks.payload_url.blocked_or_internal") }.to_json)
|
||||
expect(parsed_event["status"]).to eq(-1)
|
||||
expect(parsed_event["response_body"]).to eq(nil)
|
||||
end
|
||||
parsed_event = response.parsed_body["web_hook_event"]
|
||||
expect(parsed_event["id"]).to eq(web_hook_event.id)
|
||||
expect(parsed_event["response_headers"]).to eq({ error: I18n.t("webhooks.payload_url.blocked_or_internal") }.to_json)
|
||||
expect(parsed_event["status"]).to eq(-1)
|
||||
expect(parsed_event["response_body"]).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue