Merge remote-tracking branch 'parent/main' into kb-upstream-20231014
This commit is contained in:
commit
60195928e1
76 changed files with 1282 additions and 1205 deletions
|
@ -16,37 +16,63 @@ describe Rack::Attack, type: :request do
|
|||
# https://github.com/rack/rack-attack/blob/v6.6.1/lib/rack/attack/cache.rb#L64-L66
|
||||
# So we want to minimize `Time.now.to_i % period`
|
||||
|
||||
travel_to Time.zone.at((Time.now.to_i / period.seconds).to_i * period.seconds)
|
||||
travel_to Time.zone.at(counter_prefix * period.seconds)
|
||||
end
|
||||
|
||||
context 'when the number of requests is lower than the limit' do
|
||||
before do
|
||||
below_limit.times { increment_counter }
|
||||
end
|
||||
|
||||
it 'does not change the request status' do
|
||||
limit.times do
|
||||
request.call
|
||||
expect(response).to_not have_http_status(429)
|
||||
end
|
||||
expect { request.call }.to change { throttle_count }.by(1)
|
||||
|
||||
expect(response).to_not have_http_status(429)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the number of requests is higher than the limit' do
|
||||
before do
|
||||
above_limit.times { increment_counter }
|
||||
end
|
||||
|
||||
it 'returns http too many requests after limit and returns to normal status after period' do
|
||||
(limit * 2).times do |i|
|
||||
request.call
|
||||
expect(response).to have_http_status(429) if i > limit
|
||||
end
|
||||
expect { request.call }.to change { throttle_count }.by(1)
|
||||
expect(response).to have_http_status(429)
|
||||
|
||||
travel period
|
||||
|
||||
request.call
|
||||
expect { request.call }.to change { throttle_count }.by(1)
|
||||
expect(response).to_not have_http_status(429)
|
||||
end
|
||||
end
|
||||
|
||||
def below_limit
|
||||
limit - 1
|
||||
end
|
||||
|
||||
def above_limit
|
||||
limit * 2
|
||||
end
|
||||
|
||||
def throttle_count
|
||||
described_class.cache.read("#{counter_prefix}:#{throttle}:#{remote_ip}") || 0
|
||||
end
|
||||
|
||||
def counter_prefix
|
||||
(Time.now.to_i / period.seconds).to_i
|
||||
end
|
||||
|
||||
def increment_counter
|
||||
described_class.cache.count("#{throttle}:#{remote_ip}", period)
|
||||
end
|
||||
end
|
||||
|
||||
let(:remote_ip) { '1.2.3.5' }
|
||||
|
||||
describe 'throttle excessive sign-up requests by IP address' do
|
||||
context 'when accessed through the website' do
|
||||
let(:throttle) { 'throttle_sign_up_attempts/ip' }
|
||||
let(:limit) { 25 }
|
||||
let(:period) { 5.minutes }
|
||||
let(:request) { -> { post path, headers: { 'REMOTE_ADDR' => remote_ip } } }
|
||||
|
@ -65,6 +91,7 @@ describe Rack::Attack, type: :request do
|
|||
end
|
||||
|
||||
context 'when accessed through the API' do
|
||||
let(:throttle) { 'throttle_api_sign_up' }
|
||||
let(:limit) { 5 }
|
||||
let(:period) { 30.minutes }
|
||||
let(:request) { -> { post path, headers: { 'REMOTE_ADDR' => remote_ip } } }
|
||||
|
@ -87,6 +114,7 @@ describe Rack::Attack, type: :request do
|
|||
end
|
||||
|
||||
describe 'throttle excessive sign-in requests by IP address' do
|
||||
let(:throttle) { 'throttle_login_attempts/ip' }
|
||||
let(:limit) { 25 }
|
||||
let(:period) { 5.minutes }
|
||||
let(:request) { -> { post path, headers: { 'REMOTE_ADDR' => remote_ip } } }
|
||||
|
|
|
@ -14,11 +14,8 @@ RSpec.describe Api::OEmbedController do
|
|||
get :show, params: { url: short_account_status_url(alice, status) }, format: :json
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns private cache control headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,11 +41,9 @@ describe Api::V1::Accounts::CredentialsController do
|
|||
}
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates account info', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates account info' do
|
||||
user.reload
|
||||
user.account.reload
|
||||
|
||||
|
@ -55,9 +53,7 @@ describe Api::V1::Accounts::CredentialsController do
|
|||
expect(user.account.header).to exist
|
||||
expect(user.setting_default_privacy).to eq('unlisted')
|
||||
expect(user.setting_default_sensitive).to be(true)
|
||||
end
|
||||
|
||||
it 'queues up an account update distribution' do
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(user.account_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,23 +18,19 @@ describe Api::V1::Accounts::FollowerAccountsController do
|
|||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
it 'returns accounts following the given account', :aggregate_failures do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns accounts following the given account' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(body_as_json.size).to eq 2
|
||||
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
|
||||
end
|
||||
|
||||
it 'does not return blocked users' do
|
||||
it 'does not return blocked users', :aggregate_failures do
|
||||
user.account.block!(bob)
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
expect(body_as_json[0][:id]).to eq alice.id.to_s
|
||||
end
|
||||
|
|
|
@ -18,23 +18,19 @@ describe Api::V1::Accounts::FollowingAccountsController do
|
|||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
it 'returns accounts followed by the given account', :aggregate_failures do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns accounts followed by the given account' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(body_as_json.size).to eq 2
|
||||
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
|
||||
end
|
||||
|
||||
it 'does not return blocked users' do
|
||||
it 'does not return blocked users', :aggregate_failures do
|
||||
user.account.block!(bob)
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
expect(body_as_json[0][:id]).to eq alice.id.to_s
|
||||
end
|
||||
|
|
|
@ -19,30 +19,24 @@ describe Api::V1::Accounts::NotesController do
|
|||
post :create, params: { account_id: account.id, comment: comment }
|
||||
end
|
||||
|
||||
context 'when account note has reasonable length' do
|
||||
context 'when account note has reasonable length', :aggregate_failures do
|
||||
let(:comment) { 'foo' }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates account note' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(AccountNote.find_by(account_id: user.account.id, target_account_id: account.id).comment).to eq comment
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account note exceeds allowed length' do
|
||||
context 'when account note exceeds allowed length', :aggregate_failures do
|
||||
let(:comment) { 'a' * 2_001 }
|
||||
|
||||
it 'returns 422' do
|
||||
subject
|
||||
expect(response).to have_http_status(422)
|
||||
end
|
||||
|
||||
it 'does not create account note' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(422)
|
||||
expect(AccountNote.where(account_id: user.account.id, target_account_id: account.id)).to_not exist
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,14 +15,11 @@ RSpec.describe Api::V1::Accounts::PinsController do
|
|||
describe 'POST #create' do
|
||||
subject { post :create, params: { account_id: kevin.account.id } }
|
||||
|
||||
it 'returns 200' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates account_pin' do
|
||||
it 'creates account_pin', :aggregate_failures do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(1)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -33,14 +30,11 @@ RSpec.describe Api::V1::Accounts::PinsController do
|
|||
Fabricate(:account_pin, account: john.account, target_account: kevin.account)
|
||||
end
|
||||
|
||||
it 'returns 200' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'destroys account_pin' do
|
||||
it 'destroys account_pin', :aggregate_failures do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(-1)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,13 +26,10 @@ describe Api::V1::Accounts::RelationshipsController do
|
|||
get :index, params: { id: simon.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns JSON with correct data' do
|
||||
it 'returns JSON with correct data', :aggregate_failures do
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json).to be_a Enumerable
|
||||
expect(json.first[:following]).to be true
|
||||
expect(json.first[:followed_by]).to be false
|
||||
|
@ -51,11 +48,14 @@ describe Api::V1::Accounts::RelationshipsController do
|
|||
context 'when there is returned JSON data' do
|
||||
let(:json) { body_as_json }
|
||||
|
||||
it 'returns an enumerable json' do
|
||||
it 'returns an enumerable json with correct elements', :aggregate_failures do
|
||||
expect(json).to be_a Enumerable
|
||||
|
||||
expect_simon_item_one
|
||||
expect_lewis_item_two
|
||||
end
|
||||
|
||||
it 'returns a correct first element' do
|
||||
def expect_simon_item_one
|
||||
expect(json.first[:id]).to eq simon.id.to_s
|
||||
expect(json.first[:following]).to be true
|
||||
expect(json.first[:showing_reblogs]).to be true
|
||||
|
@ -65,7 +65,7 @@ describe Api::V1::Accounts::RelationshipsController do
|
|||
expect(json.first[:domain_blocking]).to be false
|
||||
end
|
||||
|
||||
it 'returns a correct second element' do
|
||||
def expect_lewis_item_two
|
||||
expect(json.second[:id]).to eq lewis.id.to_s
|
||||
expect(json.second[:following]).to be false
|
||||
expect(json.second[:showing_reblogs]).to be false
|
||||
|
|
|
@ -14,15 +14,10 @@ describe Api::V1::Accounts::StatusesController do
|
|||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
it 'returns expected headers', :aggregate_failures do
|
||||
get :index, params: { account_id: user.account.id, limit: 1 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns expected headers' do
|
||||
get :index, params: { account_id: user.account.id, limit: 1 }
|
||||
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
|
||||
|
@ -44,14 +39,11 @@ describe Api::V1::Accounts::StatusesController do
|
|||
get :index, params: { account_id: user.account.id, exclude_replies: true }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns posts along with self replies' do
|
||||
it 'returns posts along with self replies', :aggregate_failures do
|
||||
json = body_as_json
|
||||
post_ids = json.map { |item| item[:id].to_i }.sort
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(post_ids).to eq [status.id, status_self_reply.id]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,15 +25,10 @@ RSpec.describe Api::V1::AccountsController do
|
|||
context 'when given truthy agreement' do
|
||||
let(:agreement) { 'true' }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns a new access token as JSON' do
|
||||
expect(body_as_json[:access_token]).to_not be_blank
|
||||
end
|
||||
|
||||
it 'creates a user' do
|
||||
user = User.find_by(email: 'hello@world.tld')
|
||||
expect(user).to_not be_nil
|
||||
expect(user.created_by_application_id).to eq app.id
|
||||
|
@ -65,18 +60,14 @@ RSpec.describe Api::V1::AccountsController do
|
|||
context 'with unlocked account' do
|
||||
let(:locked) { false }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a following relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns JSON with following=true and requested=false' do
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:following]).to be true
|
||||
expect(json[:requested]).to be false
|
||||
end
|
||||
|
||||
it 'creates a following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -86,18 +77,14 @@ RSpec.describe Api::V1::AccountsController do
|
|||
context 'with locked account' do
|
||||
let(:locked) { true }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a follow request relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns JSON with following=false and requested=true' do
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:following]).to be false
|
||||
expect(json[:requested]).to be true
|
||||
end
|
||||
|
||||
it 'creates a follow request relation between user and target user' do
|
||||
expect(user.account.requested?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -177,11 +164,8 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :unfollow, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the following relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
@ -197,11 +181,8 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :remove_from_followers, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the followed relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the followed relation between user and target user' do
|
||||
expect(user.account.followed_by?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
@ -217,15 +198,9 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :block, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a blocking relation', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be false
|
||||
end
|
||||
|
||||
it 'creates a blocking relation' do
|
||||
expect(user.account.blocking?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -241,11 +216,8 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :unblock, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the blocking relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the blocking relation between user and target user' do
|
||||
expect(user.account.blocking?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
@ -261,19 +233,10 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :mute, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'mutes notifications', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'does not remove the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'creates a muting relation' do
|
||||
expect(user.account.muting?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'mutes notifications' do
|
||||
expect(user.account.muting_notifications?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -289,19 +252,10 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :mute, params: { id: other_account.id, notifications: false }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'does not mute notifications', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'does not remove the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'creates a muting relation' do
|
||||
expect(user.account.muting?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'does not mute notifications' do
|
||||
expect(user.account.muting_notifications?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
@ -317,19 +271,10 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :mute, params: { id: other_account.id, duration: 300 }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'mutes notifications', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'does not remove the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'creates a muting relation' do
|
||||
expect(user.account.muting?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'mutes notifications' do
|
||||
expect(user.account.muting_notifications?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -345,11 +290,8 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :unmute, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the muting relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the muting relation between user and target user' do
|
||||
expect(user.account.muting?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
|
|
@ -44,11 +44,9 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
context "when called with #{params.inspect}" do
|
||||
let(:params) { params }
|
||||
|
||||
it 'returns http success' do
|
||||
it "returns the correct accounts (#{expected_results.inspect})", :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it "returns the correct accounts (#{expected_results.inspect})" do
|
||||
json = body_as_json
|
||||
|
||||
expect(json.map { |a| a[:id].to_i }).to eq(expected_results.map { |symbol| send(symbol).id })
|
||||
|
@ -79,15 +77,10 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'approves user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'approves user' do
|
||||
expect(account.reload.user_approved?).to be true
|
||||
end
|
||||
|
||||
it 'logs action' do
|
||||
log_item = Admin::ActionLog.last
|
||||
|
||||
expect(log_item).to_not be_nil
|
||||
|
@ -106,15 +99,10 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes user' do
|
||||
expect(User.where(id: account.user.id).count).to eq 0
|
||||
end
|
||||
|
||||
it 'logs action' do
|
||||
log_item = Admin::ActionLog.last
|
||||
|
||||
expect(log_item).to_not be_nil
|
||||
|
@ -133,11 +121,8 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'enables user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'enables user' do
|
||||
expect(account.reload.user_disabled?).to be false
|
||||
end
|
||||
end
|
||||
|
@ -151,11 +136,8 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'unsuspends account', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'unsuspends account' do
|
||||
expect(account.reload.suspended?).to be false
|
||||
end
|
||||
end
|
||||
|
@ -169,11 +151,8 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'unsensitizes account', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'unsensitizes account' do
|
||||
expect(account.reload.sensitized?).to be false
|
||||
end
|
||||
end
|
||||
|
@ -187,11 +166,8 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'unsilences account', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'unsilences account' do
|
||||
expect(account.reload.silenced?).to be false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Admin::Trends::LinksController do
|
||||
render_views
|
||||
|
||||
let(:role) { UserRole.find_by(name: 'Admin') }
|
||||
let(:user) { Fabricate(:user, role: role) }
|
||||
let(:scopes) { 'admin:read admin:write' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:preview_card) { Fabricate(:preview_card) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #approve' do
|
||||
before do
|
||||
post :approve, params: { id: preview_card.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #reject' do
|
||||
before do
|
||||
post :reject, params: { id: preview_card.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -25,11 +25,8 @@ RSpec.describe Api::V1::Announcements::ReactionsController do
|
|||
put :update, params: { announcement_id: announcement.id, id: '😂' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates reaction', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates reaction' do
|
||||
expect(announcement.announcement_reactions.find_by(name: '😂', account: user.account)).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
@ -53,11 +50,8 @@ RSpec.describe Api::V1::Announcements::ReactionsController do
|
|||
delete :destroy, params: { announcement_id: announcement.id, id: '😂' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates reaction', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates reaction' do
|
||||
expect(announcement.announcement_reactions.find_by(name: '😂', account: user.account)).to be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,11 +47,8 @@ RSpec.describe Api::V1::AnnouncementsController do
|
|||
post :dismiss, params: { id: announcement.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'dismisses announcement', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'dismisses announcement' do
|
||||
expect(announcement.announcement_mutes.find_by(account: user.account)).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,45 +12,48 @@ RSpec.describe Api::V1::BlocksController do
|
|||
before { allow(controller).to receive(:doorkeeper_token) { token } }
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'limits according to limit parameter' do
|
||||
it 'limits according to limit parameter', :aggregate_failures do
|
||||
Array.new(2) { Fabricate(:block, account: user.account) }
|
||||
get :index, params: { limit: 1 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
end
|
||||
|
||||
it 'queries blocks in range according to max_id' do
|
||||
it 'queries blocks in range according to max_id', :aggregate_failures do
|
||||
blocks = Array.new(2) { Fabricate(:block, account: user.account) }
|
||||
|
||||
get :index, params: { max_id: blocks[1] }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
expect(body_as_json[0][:id]).to eq blocks[0].target_account_id.to_s
|
||||
end
|
||||
|
||||
it 'queries blocks in range according to since_id' do
|
||||
it 'queries blocks in range according to since_id', :aggregate_failures do
|
||||
blocks = Array.new(2) { Fabricate(:block, account: user.account) }
|
||||
|
||||
get :index, params: { since_id: blocks[0] }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
expect(body_as_json[0][:id]).to eq blocks[1].target_account_id.to_s
|
||||
end
|
||||
|
||||
it 'sets pagination header for next path' do
|
||||
it 'sets pagination header for next path', :aggregate_failures do
|
||||
blocks = Array.new(2) { Fabricate(:block, account: user.account) }
|
||||
get :index, params: { limit: 1, since_id: blocks[0] }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq api_v1_blocks_url(limit: 1, max_id: blocks[1])
|
||||
end
|
||||
|
||||
it 'sets pagination header for previous path' do
|
||||
it 'sets pagination header for previous path', :aggregate_failures do
|
||||
block = Fabricate(:block, account: user.account)
|
||||
get :index
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq api_v1_blocks_url(since_id: block)
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq api_v1_blocks_url(since_id: block)
|
||||
end
|
||||
|
||||
context 'with wrong scopes' do
|
||||
|
|
|
@ -21,17 +21,14 @@ RSpec.describe Api::V1::ConversationsController do
|
|||
PostStatusService.new.call(user.account, text: 'Hey, nobody here', visibility: 'direct')
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns pagination headers' do
|
||||
it 'returns pagination headers', :aggregate_failures do
|
||||
get :index, params: { limit: 1 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
|
||||
it 'returns conversations' do
|
||||
it 'returns conversations', :aggregate_failures do
|
||||
get :index
|
||||
json = body_as_json
|
||||
expect(json.size).to eq 2
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::FavouritesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') }
|
||||
|
||||
describe 'GET #index' do
|
||||
context 'without token' do
|
||||
it 'returns http unauthorized' do
|
||||
get :index
|
||||
expect(response).to have_http_status 401
|
||||
end
|
||||
end
|
||||
|
||||
context 'with token' do
|
||||
context 'without read scope' do
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) do
|
||||
Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: '')
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns http forbidden' do
|
||||
get :index
|
||||
expect(response).to have_http_status 403
|
||||
end
|
||||
end
|
||||
|
||||
context 'without valid resource owner' do
|
||||
before do
|
||||
token = Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read')
|
||||
user.destroy!
|
||||
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
get :index
|
||||
expect(response).to have_http_status 422
|
||||
end
|
||||
end
|
||||
|
||||
context 'with read scope and valid resource owner' do
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) do
|
||||
Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:favourites')
|
||||
end
|
||||
end
|
||||
|
||||
it 'shows favourites owned by the user' do
|
||||
favourite_by_user = Fabricate(:favourite, account: user.account)
|
||||
favourite_by_others = Fabricate(:favourite)
|
||||
|
||||
get :index
|
||||
|
||||
expect(assigns(:statuses)).to contain_exactly(favourite_by_user.status)
|
||||
end
|
||||
|
||||
it 'adds pagination headers if necessary' do
|
||||
favourite = Fabricate(:favourite, account: user.account)
|
||||
|
||||
get :index, params: { limit: 1 }
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq "http://test.host/api/v1/favourites?limit=1&max_id=#{favourite.id}"
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq "http://test.host/api/v1/favourites?limit=1&min_id=#{favourite.id}"
|
||||
end
|
||||
|
||||
it 'does not add pagination headers if not necessary' do
|
||||
get :index
|
||||
|
||||
expect(response.headers['Link']).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -31,12 +31,10 @@ RSpec.describe Api::V1::FiltersController do
|
|||
post :create, params: { phrase: 'magic', context: %w(home), irreversible: irreversible, whole_word: whole_word }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a filter' do
|
||||
it 'creates a filter', :aggregate_failures do
|
||||
filter = user.account.custom_filters.first
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(filter).to_not be_nil
|
||||
expect(filter.keywords.pluck(:keyword, :whole_word)).to eq [['magic', whole_word]]
|
||||
expect(filter.context).to eq %w(home)
|
||||
|
@ -48,12 +46,10 @@ RSpec.describe Api::V1::FiltersController do
|
|||
let(:irreversible) { false }
|
||||
let(:whole_word) { true }
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a filter' do
|
||||
it 'creates a filter', :aggregate_failures do
|
||||
filter = user.account.custom_filters.first
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(filter).to_not be_nil
|
||||
expect(filter.keywords.pluck(:keyword, :whole_word)).to eq [['magic', whole_word]]
|
||||
expect(filter.context).to eq %w(home)
|
||||
|
@ -83,11 +79,8 @@ RSpec.describe Api::V1::FiltersController do
|
|||
put :update, params: { id: keyword.id, phrase: 'updated' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the filter' do
|
||||
expect(keyword.reload.phrase).to eq 'updated'
|
||||
end
|
||||
end
|
||||
|
@ -101,11 +94,8 @@ RSpec.describe Api::V1::FiltersController do
|
|||
delete :destroy, params: { id: keyword.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the filter' do
|
||||
expect { keyword.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::FollowedTagsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'read:follows' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
|
||||
before { allow(controller).to receive(:doorkeeper_token) { token } }
|
||||
|
||||
describe 'GET #index' do
|
||||
let!(:tag_follows) { Fabricate.times(5, :tag_follow, account: user.account) }
|
||||
|
||||
before do
|
||||
get :index, params: { limit: 1 }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,7 +5,7 @@ require 'rails_helper'
|
|||
describe Api::V1::Instances::TranslationLanguagesController do
|
||||
describe 'GET #show' do
|
||||
context 'when no translation service is configured' do
|
||||
it 'returns empty language matrix' do
|
||||
it 'returns empty language matrix', :aggregate_failures do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
|
@ -19,7 +19,7 @@ describe Api::V1::Instances::TranslationLanguagesController do
|
|||
allow(TranslationService).to receive_messages(configured?: true, configured: service)
|
||||
end
|
||||
|
||||
it 'returns language matrix' do
|
||||
it 'returns language matrix', :aggregate_failures do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
|
|
|
@ -35,11 +35,8 @@ describe Api::V1::Lists::AccountsController do
|
|||
post :create, params: { list_id: list.id, account_ids: [bob.id] }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'adds account to the list', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'adds account to the list' do
|
||||
expect(list.accounts.include?(bob)).to be true
|
||||
end
|
||||
end
|
||||
|
@ -50,11 +47,8 @@ describe Api::V1::Lists::AccountsController do
|
|||
post :create, params: { list_id: list.id, account_ids: [bob.id] }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'adds account to the list', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'adds account to the list' do
|
||||
expect(list.accounts.include?(bob)).to be true
|
||||
end
|
||||
end
|
||||
|
@ -64,11 +58,8 @@ describe Api::V1::Lists::AccountsController do
|
|||
post :create, params: { list_id: list.id, account_ids: [bob.id] }
|
||||
end
|
||||
|
||||
it 'returns http not found' do
|
||||
it 'does not add the account to the list', :aggregate_failures do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
||||
it 'does not add the account to the list' do
|
||||
expect(list.accounts.include?(bob)).to be false
|
||||
end
|
||||
end
|
||||
|
@ -81,11 +72,8 @@ describe Api::V1::Lists::AccountsController do
|
|||
delete :destroy, params: { list_id: list.id, account_ids: [list.accounts.first.id] }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes account from the list', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes account from the list' do
|
||||
expect(list.accounts.count).to eq 0
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,13 +18,10 @@ RSpec.describe Api::V1::MarkersController do
|
|||
get :index, params: { timeline: %w(home notifications) }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns markers' do
|
||||
it 'returns markers', :aggregate_failures do
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.key?(:home)).to be true
|
||||
expect(json[:home][:last_read_id]).to eq '123'
|
||||
expect(json.key?(:notifications)).to be true
|
||||
|
@ -38,11 +35,8 @@ RSpec.describe Api::V1::MarkersController do
|
|||
post :create, params: { home: { last_read_id: '69420' } }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a marker', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a marker' do
|
||||
expect(user.markers.first.timeline).to eq 'home'
|
||||
expect(user.markers.first.last_read_id).to eq 69_420
|
||||
end
|
||||
|
@ -54,11 +48,8 @@ RSpec.describe Api::V1::MarkersController do
|
|||
post :create, params: { home: { last_read_id: '70120' } }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates a marker', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates a marker' do
|
||||
expect(user.markers.first.timeline).to eq 'home'
|
||||
expect(user.markers.first.last_read_id).to eq 70_120
|
||||
end
|
||||
|
|
|
@ -38,19 +38,10 @@ RSpec.describe Api::V1::MediaController do
|
|||
post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a media attachment', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a media attachment' do
|
||||
expect(MediaAttachment.first).to_not be_nil
|
||||
end
|
||||
|
||||
it 'uploads a file' do
|
||||
expect(MediaAttachment.first).to have_attached_file(:file)
|
||||
end
|
||||
|
||||
it 'returns media ID in JSON' do
|
||||
expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s
|
||||
end
|
||||
end
|
||||
|
@ -60,19 +51,10 @@ RSpec.describe Api::V1::MediaController do
|
|||
post :create, params: { file: fixture_file_upload('attachment.gif', 'image/gif') }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a media attachment', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a media attachment' do
|
||||
expect(MediaAttachment.first).to_not be_nil
|
||||
end
|
||||
|
||||
it 'uploads a file' do
|
||||
expect(MediaAttachment.first).to have_attached_file(:file)
|
||||
end
|
||||
|
||||
it 'returns media ID in JSON' do
|
||||
expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s
|
||||
end
|
||||
end
|
||||
|
@ -82,17 +64,10 @@ RSpec.describe Api::V1::MediaController do
|
|||
post :create, params: { file: fixture_file_upload('attachment.webm', 'video/webm') }
|
||||
end
|
||||
|
||||
it do
|
||||
# returns http success
|
||||
it 'creates a media attachment', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
|
||||
# creates a media attachment
|
||||
expect(MediaAttachment.first).to_not be_nil
|
||||
|
||||
# uploads a file
|
||||
expect(MediaAttachment.first).to have_attached_file(:file)
|
||||
|
||||
# returns media ID in JSON
|
||||
expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,18 +18,13 @@ RSpec.describe Api::V1::Polls::VotesController do
|
|||
post :create, params: { poll_id: poll.id, choices: %w(1) }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a vote', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a vote' do
|
||||
vote = poll.votes.where(account: user.account).first
|
||||
|
||||
expect(vote).to_not be_nil
|
||||
expect(vote.choice).to eq 1
|
||||
end
|
||||
|
||||
it 'updates poll tallies' do
|
||||
expect(poll.reload.cached_tallies).to eq [0, 1]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::ReportsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
let(:scopes) { 'write:reports' }
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:target_account) { status.account }
|
||||
let(:category) { nil }
|
||||
let(:forward) { nil }
|
||||
let(:rule_ids) { nil }
|
||||
|
||||
before do
|
||||
post :create, params: { status_ids: [status.id], account_id: target_account.id, comment: 'reasons', category: category, rule_ids: rule_ids, forward: forward }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a report' do
|
||||
expect(target_account.targeted_reports).to_not be_empty
|
||||
end
|
||||
|
||||
it 'saves comment' do
|
||||
expect(target_account.targeted_reports.first.comment).to eq 'reasons'
|
||||
end
|
||||
|
||||
it 'sends e-mails to admins' do
|
||||
expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email])
|
||||
end
|
||||
|
||||
context 'when a status does not belong to the reported account' do
|
||||
let(:target_account) { Fabricate(:account) }
|
||||
|
||||
it 'returns http not found' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a category is chosen' do
|
||||
let(:category) { 'spam' }
|
||||
|
||||
it 'saves category' do
|
||||
expect(target_account.targeted_reports.first.spam?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when violated rules are chosen' do
|
||||
let(:rule) { Fabricate(:rule) }
|
||||
let(:category) { 'violation' }
|
||||
let(:rule_ids) { [rule.id] }
|
||||
|
||||
it 'saves category' do
|
||||
expect(target_account.targeted_reports.first.violation?).to be true
|
||||
end
|
||||
|
||||
it 'saves rule_ids' do
|
||||
expect(target_account.targeted_reports.first.rule_ids).to contain_exactly(rule.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21,11 +21,8 @@ describe Api::V1::Statuses::MutesController do
|
|||
post :create, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a conversation mute', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a conversation mute' do
|
||||
expect(ConversationMute.find_by(account: user.account, conversation_id: status.conversation_id)).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
@ -38,11 +35,8 @@ describe Api::V1::Statuses::MutesController do
|
|||
post :destroy, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the conversation mute', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'destroys the conversation mute' do
|
||||
expect(ConversationMute.find_by(account: user.account, conversation_id: status.conversation_id)).to be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,14 +24,12 @@ RSpec.describe Api::V1::Statuses::RebloggedByAccountsController do
|
|||
Fabricate(:status, account: bob, reblog_of_id: status.id)
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns accounts who reblogged the status', :aggregate_failures do
|
||||
get :index, params: { status_id: status.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
|
||||
it 'returns accounts who reblogged the status' do
|
||||
get :index, params: { status_id: status.id, limit: 2 }
|
||||
expect(body_as_json.size).to eq 2
|
||||
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
|
||||
end
|
||||
|
|
|
@ -28,19 +28,13 @@ describe Api::V1::Statuses::ReblogsController do
|
|||
end
|
||||
|
||||
context 'with public status' do
|
||||
it 'returns http success' do
|
||||
it 'reblogs the status', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the reblogs count' do
|
||||
expect(status.reblogs.count).to eq 1
|
||||
end
|
||||
|
||||
it 'updates the reblogged attribute' do
|
||||
expect(user.account.reblogged?(status)).to be true
|
||||
end
|
||||
|
||||
it 'returns json with updated attributes' do
|
||||
hash_body = body_as_json
|
||||
|
||||
expect(hash_body[:reblog][:id]).to eq status.id.to_s
|
||||
|
@ -67,19 +61,13 @@ describe Api::V1::Statuses::ReblogsController do
|
|||
post :destroy, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the reblog', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the reblogs count' do
|
||||
expect(status.reblogs.count).to eq 0
|
||||
end
|
||||
|
||||
it 'updates the reblogged attribute' do
|
||||
expect(user.account.reblogged?(status)).to be false
|
||||
end
|
||||
|
||||
it 'returns json with updated attributes' do
|
||||
hash_body = body_as_json
|
||||
|
||||
expect(hash_body[:id]).to eq status.id.to_s
|
||||
|
@ -97,19 +85,13 @@ describe Api::V1::Statuses::ReblogsController do
|
|||
post :destroy, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the reblog', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the reblogs count' do
|
||||
expect(status.reblogs.count).to eq 0
|
||||
end
|
||||
|
||||
it 'updates the reblogged attribute' do
|
||||
expect(user.account.reblogged?(status)).to be false
|
||||
end
|
||||
|
||||
it 'returns json with updated attributes' do
|
||||
hash_body = body_as_json
|
||||
|
||||
expect(hash_body[:id]).to eq status.id.to_s
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Statuses::SourcesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses', application: app) }
|
||||
|
||||
context 'with an oauth token' do
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
let(:status) { Fabricate(:status, account: user.account) }
|
||||
|
||||
before do
|
||||
get :show, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -30,14 +30,11 @@ RSpec.describe Api::V1::StatusesController do
|
|||
user.account.custom_filters.create!(phrase: 'filter1', context: %w(home), action: :hide, keywords_attributes: [{ keyword: 'banned' }, { keyword: 'irrelevant' }])
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :show, params: { id: status.id }
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns filter information' do
|
||||
it 'returns filter information', :aggregate_failures do
|
||||
get :show, params: { id: status.id }
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json[:filtered][0]).to include({
|
||||
filter: a_hash_including({
|
||||
id: user.account.custom_filters.first.id.to_s,
|
||||
|
@ -57,14 +54,11 @@ RSpec.describe Api::V1::StatusesController do
|
|||
filter.statuses.create!(status_id: status.id)
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :show, params: { id: status.id }
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns filter information' do
|
||||
it 'returns filter information', :aggregate_failures do
|
||||
get :show, params: { id: status.id }
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json[:filtered][0]).to include({
|
||||
filter: a_hash_including({
|
||||
id: user.account.custom_filters.first.id.to_s,
|
||||
|
@ -83,14 +77,11 @@ RSpec.describe Api::V1::StatusesController do
|
|||
user.account.custom_filters.create!(phrase: 'filter1', context: %w(home), action: :hide, keywords_attributes: [{ keyword: 'banned' }, { keyword: 'irrelevant' }])
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :show, params: { id: status.id }
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns filter information' do
|
||||
it 'returns filter information', :aggregate_failures do
|
||||
get :show, params: { id: status.id }
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json[:reblog][:filtered][0]).to include({
|
||||
filter: a_hash_including({
|
||||
id: user.account.custom_filters.first.id.to_s,
|
||||
|
@ -125,11 +116,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :create, params: { status: 'Hello world' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns rate limit headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns rate limit headers' do
|
||||
expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
|
||||
expect(response.headers['X-RateLimit-Remaining']).to eq (RateLimiter::FAMILIES[:statuses][:limit] - 1).to_s
|
||||
end
|
||||
|
@ -143,11 +131,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :create, params: { status: '@alice hm, @bob is really annoying lately', allowed_mentions: [alice.id] }
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
it 'returns serialized extra accounts in body', :aggregate_failures do
|
||||
expect(response).to have_http_status(422)
|
||||
end
|
||||
|
||||
it 'returns serialized extra accounts in body' do
|
||||
expect(body_as_json[:unexpected_accounts].map { |a| a.slice(:id, :acct) }).to eq [{ id: bob.id.to_s, acct: bob.acct }]
|
||||
end
|
||||
end
|
||||
|
@ -157,11 +142,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :create, params: {}
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
it 'returns rate limit headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(422)
|
||||
end
|
||||
|
||||
it 'returns rate limit headers' do
|
||||
expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
|
||||
end
|
||||
end
|
||||
|
@ -173,11 +155,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :create, params: { status: 'Hello world' }
|
||||
end
|
||||
|
||||
it 'returns http too many requests' do
|
||||
it 'returns rate limit headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(429)
|
||||
end
|
||||
|
||||
it 'returns rate limit headers' do
|
||||
expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
|
||||
expect(response.headers['X-RateLimit-Remaining']).to eq '0'
|
||||
end
|
||||
|
@ -192,11 +171,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :destroy, params: { id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the status', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the status' do
|
||||
expect(Status.find_by(id: status.id)).to be_nil
|
||||
end
|
||||
end
|
||||
|
@ -209,11 +185,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
put :update, params: { id: status.id, status: 'I am updated' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates the status', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the status' do
|
||||
expect(status.reload.text).to eq 'I am updated'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Timelines::TagController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
subject do
|
||||
get :show, params: { id: 'test' }
|
||||
end
|
||||
|
||||
before do
|
||||
PostStatusService.new.call(user.account, text: 'It is a #test')
|
||||
end
|
||||
|
||||
context 'when the instance allows public preview' do
|
||||
context 'when the user is not authenticated' do
|
||||
let(:token) { nil }
|
||||
|
||||
it 'returns http success', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is authenticated' do
|
||||
it 'returns http success', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the instance does not allow public preview' do
|
||||
before do
|
||||
Form::AdminSettings.new(timeline_preview: false).save
|
||||
end
|
||||
|
||||
context 'when the user is not authenticated' do
|
||||
let(:token) { nil }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is authenticated' do
|
||||
it 'returns http success', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -44,14 +44,14 @@ RSpec.describe Api::V2::Admin::AccountsController do
|
|||
context "when called with #{params.inspect}" do
|
||||
let(:params) { params }
|
||||
|
||||
it 'returns http success' do
|
||||
it "returns the correct accounts (#{expected_results.inspect})" do
|
||||
expect(response).to have_http_status(200)
|
||||
|
||||
expect(body_json_ids).to eq(expected_results.map { |symbol| send(symbol).id })
|
||||
end
|
||||
|
||||
it "returns the correct accounts (#{expected_results.inspect})" do
|
||||
json = body_as_json
|
||||
|
||||
expect(json.map { |a| a[:id].to_i }).to eq(expected_results.map { |symbol| send(symbol).id })
|
||||
def body_json_ids
|
||||
body_as_json.map { |a| a[:id].to_i }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,17 +40,13 @@ RSpec.describe Api::V2::Filters::KeywordsController do
|
|||
post :create, params: { filter_id: filter_id, keyword: 'magic', whole_word: false }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns a keyword' do
|
||||
json = body_as_json
|
||||
expect(json[:keyword]).to eq 'magic'
|
||||
expect(json[:whole_word]).to be false
|
||||
end
|
||||
|
||||
it 'creates a keyword' do
|
||||
filter = user.account.custom_filters.first
|
||||
expect(filter).to_not be_nil
|
||||
expect(filter.keywords.pluck(:keyword)).to eq ['magic']
|
||||
|
@ -73,11 +69,9 @@ RSpec.describe Api::V2::Filters::KeywordsController do
|
|||
get :show, params: { id: keyword.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'responds with the keyword', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns expected data' do
|
||||
json = body_as_json
|
||||
expect(json[:keyword]).to eq 'foo'
|
||||
expect(json[:whole_word]).to be false
|
||||
|
@ -100,11 +94,9 @@ RSpec.describe Api::V2::Filters::KeywordsController do
|
|||
get :update, params: { id: keyword.id, keyword: 'updated' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates the keyword', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the keyword' do
|
||||
expect(keyword.reload.keyword).to eq 'updated'
|
||||
end
|
||||
|
||||
|
@ -125,11 +117,9 @@ RSpec.describe Api::V2::Filters::KeywordsController do
|
|||
delete :destroy, params: { id: keyword.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the keyword', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the filter' do
|
||||
expect { keyword.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
|
|
|
@ -41,16 +41,12 @@ RSpec.describe Api::V2::Filters::StatusesController do
|
|||
post :create, params: { filter_id: filter_id, status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns a status filter' do
|
||||
json = body_as_json
|
||||
expect(json[:status_id]).to eq status.id.to_s
|
||||
end
|
||||
|
||||
it 'creates a status filter' do
|
||||
filter = user.account.custom_filters.first
|
||||
expect(filter).to_not be_nil
|
||||
expect(filter.statuses.pluck(:status_id)).to eq [status.id]
|
||||
|
@ -73,11 +69,9 @@ RSpec.describe Api::V2::Filters::StatusesController do
|
|||
get :show, params: { id: status_filter.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'responds with the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns expected data' do
|
||||
json = body_as_json
|
||||
expect(json[:status_id]).to eq status_filter.status_id.to_s
|
||||
end
|
||||
|
@ -99,11 +93,9 @@ RSpec.describe Api::V2::Filters::StatusesController do
|
|||
delete :destroy, params: { id: status_filter.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the filter' do
|
||||
expect { status_filter.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
|
|
81
spec/features/admin/accounts_spec.rb
Normal file
81
spec/features/admin/accounts_spec.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Accounts' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
let(:unapproved_user_account) { Fabricate(:account) }
|
||||
let(:approved_user_account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
unapproved_user_account.user.update(approved: false)
|
||||
approved_user_account.user.update(approved: true)
|
||||
|
||||
visit admin_accounts_path
|
||||
end
|
||||
|
||||
context 'without selecting any accounts' do
|
||||
it 'displays a notice about account selection' do
|
||||
click_on button_for_suspend
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with action of `suspend`' do
|
||||
it 'suspends the account' do
|
||||
batch_checkbox_for(approved_user_account).check
|
||||
|
||||
click_on button_for_suspend
|
||||
|
||||
expect(approved_user_account.reload).to be_suspended
|
||||
end
|
||||
end
|
||||
|
||||
context 'with action of `approve`' do
|
||||
it 'approves the account user' do
|
||||
batch_checkbox_for(unapproved_user_account).check
|
||||
|
||||
click_on button_for_approve
|
||||
|
||||
expect(unapproved_user_account.reload.user).to be_approved
|
||||
end
|
||||
end
|
||||
|
||||
context 'with action of `reject`' do
|
||||
it 'rejects and removes the account' do
|
||||
batch_checkbox_for(unapproved_user_account).check
|
||||
|
||||
click_on button_for_reject
|
||||
|
||||
expect { unapproved_user_account.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_suspend
|
||||
I18n.t('admin.accounts.perform_full_suspension')
|
||||
end
|
||||
|
||||
def button_for_approve
|
||||
I18n.t('admin.accounts.approve')
|
||||
end
|
||||
|
||||
def button_for_reject
|
||||
I18n.t('admin.accounts.reject')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.accounts.no_account_selected')
|
||||
end
|
||||
|
||||
def batch_checkbox_for(account)
|
||||
find("#form_account_batch_account_ids_#{account.id}")
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/custom_emojis_spec.rb
Normal file
33
spec/features/admin/custom_emojis_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::CustomEmojis' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_custom_emojis_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_enable
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_enable
|
||||
I18n.t('admin.custom_emojis.enable')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.custom_emojis.no_emoji_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/email_domain_blocks_spec.rb
Normal file
33
spec/features/admin/email_domain_blocks_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::EmailDomainBlocks' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_email_domain_blocks_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_delete
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_delete
|
||||
I18n.t('admin.email_domain_blocks.delete')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.email_domain_blocks.no_email_domain_block_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/ip_blocks_spec.rb
Normal file
33
spec/features/admin/ip_blocks_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::IpBlocks' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_ip_blocks_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_delete
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_delete
|
||||
I18n.t('admin.ip_blocks.delete')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.ip_blocks.no_ip_block_selected')
|
||||
end
|
||||
end
|
||||
end
|
34
spec/features/admin/statuses_spec.rb
Normal file
34
spec/features/admin/statuses_spec.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Statuses' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
_status = Fabricate(:status, account: current_user.account)
|
||||
visit admin_account_statuses_path(account_id: current_user.account_id)
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_report
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_report
|
||||
I18n.t('admin.statuses.batch.report')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.statuses.no_status_selected')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Trends::Links::PreviewCardProviders' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_trends_links_preview_card_providers_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_allow
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_allow
|
||||
I18n.t('admin.trends.allow')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.trends.links.publishers.no_publisher_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/trends/links_spec.rb
Normal file
33
spec/features/admin/trends/links_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Trends::Links' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_trends_links_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_allow
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_allow
|
||||
I18n.t('admin.trends.links.allow')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.trends.links.no_link_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/trends/statuses_spec.rb
Normal file
33
spec/features/admin/trends/statuses_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Trends::Statuses' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_trends_statuses_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_allow
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_allow
|
||||
I18n.t('admin.trends.statuses.allow')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.trends.statuses.no_status_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/trends/tags_spec.rb
Normal file
33
spec/features/admin/trends/tags_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Trends::Tags' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_trends_tags_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_allow
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_allow
|
||||
I18n.t('admin.trends.allow')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.trends.tags.no_tag_selected')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -562,6 +562,44 @@ RSpec.describe FeedManager do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#unmerge_tag_from_home' do
|
||||
let(:receiver) { Fabricate(:account) }
|
||||
let(:tag) { Fabricate(:tag) }
|
||||
|
||||
it 'leaves a tagged status' do
|
||||
status = Fabricate(:status)
|
||||
status.tags << tag
|
||||
described_class.instance.push_to_home(receiver, status)
|
||||
|
||||
described_class.instance.unmerge_tag_from_home(tag, receiver)
|
||||
|
||||
expect(redis.zrange("feed:home:#{receiver.id}", 0, -1)).to_not include(status.id.to_s)
|
||||
end
|
||||
|
||||
it 'remains a tagged status written by receiver\'s followee' do
|
||||
followee = Fabricate(:account)
|
||||
receiver.follow!(followee)
|
||||
|
||||
status = Fabricate(:status, account: followee)
|
||||
status.tags << tag
|
||||
described_class.instance.push_to_home(receiver, status)
|
||||
|
||||
described_class.instance.unmerge_tag_from_home(tag, receiver)
|
||||
|
||||
expect(redis.zrange("feed:home:#{receiver.id}", 0, -1)).to include(status.id.to_s)
|
||||
end
|
||||
|
||||
it 'remains a tagged status written by receiver' do
|
||||
status = Fabricate(:status, account: receiver)
|
||||
status.tags << tag
|
||||
described_class.instance.push_to_home(receiver, status)
|
||||
|
||||
described_class.instance.unmerge_tag_from_home(tag, receiver)
|
||||
|
||||
expect(redis.zrange("feed:home:#{receiver.id}", 0, -1)).to include(status.id.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#clear_from_home' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:followed_account) { Fabricate(:account) }
|
||||
|
|
|
@ -54,26 +54,6 @@ Devise::Test::ControllerHelpers.module_eval do
|
|||
end
|
||||
end
|
||||
|
||||
module SignedRequestHelpers
|
||||
def get(path, headers: nil, sign_with: nil, **args)
|
||||
return super path, headers: headers, **args if sign_with.nil?
|
||||
|
||||
headers ||= {}
|
||||
headers['Date'] = Time.now.utc.httpdate
|
||||
headers['Host'] = ENV.fetch('LOCAL_DOMAIN')
|
||||
signed_headers = headers.merge('(request-target)' => "get #{path}").slice('(request-target)', 'Host', 'Date')
|
||||
|
||||
key_id = ActivityPub::TagManager.instance.key_uri_for(sign_with)
|
||||
keypair = sign_with.keypair
|
||||
signed_string = signed_headers.map { |key, value| "#{key.downcase}: #{value}" }.join("\n")
|
||||
signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), signed_string))
|
||||
|
||||
headers['Signature'] = "keyId=\"#{key_id}\",algorithm=\"rsa-sha256\",headers=\"#{signed_headers.keys.join(' ').downcase}\",signature=\"#{signature}\""
|
||||
|
||||
super path, headers: headers, **args
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
# This is set before running spec:system, see lib/tasks/tests.rake
|
||||
config.filter_run_excluding type: lambda { |type|
|
||||
|
|
|
@ -51,14 +51,9 @@ RSpec.describe 'Account actions' do
|
|||
it_behaves_like 'a successful notification delivery'
|
||||
it_behaves_like 'a successful logged action', :disable, :user
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'disables the target account' do
|
||||
expect { subject }.to change { target_account.reload.user_disabled? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,14 +65,9 @@ RSpec.describe 'Account actions' do
|
|||
it_behaves_like 'a successful notification delivery'
|
||||
it_behaves_like 'a successful logged action', :sensitive, :account
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks the target account as sensitive' do
|
||||
expect { subject }.to change { target_account.reload.sensitized? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -89,14 +79,9 @@ RSpec.describe 'Account actions' do
|
|||
it_behaves_like 'a successful notification delivery'
|
||||
it_behaves_like 'a successful logged action', :silence, :account
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks the target account as silenced' do
|
||||
expect { subject }.to change { target_account.reload.silenced? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -108,14 +93,9 @@ RSpec.describe 'Account actions' do
|
|||
it_behaves_like 'a successful notification delivery'
|
||||
it_behaves_like 'a successful logged action', :suspend, :account
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks the target account as suspended' do
|
||||
expect { subject }.to change { target_account.reload.suspended? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -92,15 +92,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
context 'when the requested canonical email block exists' do
|
||||
it 'returns http success' do
|
||||
it 'returns the requested canonical email block data correctly', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the requested canonical email block data correctly' do
|
||||
subject
|
||||
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:id]).to eq(canonical_email_block.id.to_s)
|
||||
|
@ -142,29 +137,19 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
context 'when there is a matching canonical email block' do
|
||||
let!(:canonical_email_block) { CanonicalEmailBlock.create(params) }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected canonical email hash', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected canonical email hash' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[0][:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is no matching canonical email block' do
|
||||
it 'returns http success' do
|
||||
it 'returns an empty list', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns an empty list' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to be_empty
|
||||
end
|
||||
end
|
||||
|
@ -183,15 +168,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the canonical_email_hash correctly', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the canonical_email_hash correctly' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
|
||||
end
|
||||
|
||||
|
@ -208,15 +188,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
context 'when the canonical_email_hash param is provided instead of email' do
|
||||
let(:params) { { canonical_email_hash: 'dd501ce4e6b08698f19df96f2f15737e48a75660b1fa79b6ff58ea25ee4851a4' } }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct canonical_email_hash', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct canonical_email_hash' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:canonical_email_hash]).to eq(params[:canonical_email_hash])
|
||||
end
|
||||
end
|
||||
|
@ -224,15 +199,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
context 'when both email and canonical_email_hash params are provided' do
|
||||
let(:params) { { email: 'example@email.com', canonical_email_hash: 'dd501ce4e6b08698f19df96f2f15737e48a75660b1fa79b6ff58ea25ee4851a4' } }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'ignores the canonical_email_hash param', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'ignores the canonical_email_hash param' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
|
||||
end
|
||||
end
|
||||
|
@ -262,15 +232,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the canonical email block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the canonical email block' do
|
||||
subject
|
||||
|
||||
expect(CanonicalEmailBlock.find_by(id: canonical_email_block.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -75,15 +75,10 @@ RSpec.describe 'Domain Allows' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected allowed domain name', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected allowed domain name' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:domain]).to eq domain_allow.domain
|
||||
end
|
||||
|
||||
|
@ -108,21 +103,11 @@ RSpec.describe 'Domain Allows' do
|
|||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
context 'with a valid domain name' do
|
||||
it 'returns http success' do
|
||||
it 'returns the expected domain name', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected domain name' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:domain]).to eq 'foo.bar.com'
|
||||
end
|
||||
|
||||
it 'creates a domain allow' do
|
||||
subject
|
||||
|
||||
expect(DomainAllow.find_by(domain: 'foo.bar.com')).to be_present
|
||||
end
|
||||
end
|
||||
|
@ -171,15 +156,10 @@ RSpec.describe 'Domain Allows' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the allowed domain', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the allowed domain' do
|
||||
subject
|
||||
|
||||
expect(DomainAllow.find_by(id: domain_allow.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -143,16 +143,23 @@ RSpec.describe 'Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected domain block content', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected domain block content' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to eq(expected_response)
|
||||
expect(body_as_json).to eq(
|
||||
{
|
||||
id: domain_block.id.to_s,
|
||||
domain: domain_block.domain,
|
||||
created_at: domain_block.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
|
||||
severity: domain_block.severity.to_s,
|
||||
reject_media: domain_block.reject_media,
|
||||
reject_reports: domain_block.reject_reports,
|
||||
private_comment: domain_block.private_comment,
|
||||
public_comment: domain_block.public_comment,
|
||||
obfuscate: domain_block.obfuscate,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the requested domain block does not exist' do
|
||||
|
@ -175,27 +182,18 @@ RSpec.describe 'Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns expected domain name and severity' do
|
||||
it 'returns expected domain name and severity', :aggregate_failures do
|
||||
subject
|
||||
|
||||
body = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body).to match a_hash_including(
|
||||
{
|
||||
domain: 'foo.bar.com',
|
||||
severity: 'silence',
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it 'creates a domain block' do
|
||||
subject
|
||||
|
||||
expect(DomainBlock.find_by(domain: 'foo.bar.com')).to be_present
|
||||
end
|
||||
|
@ -205,15 +203,10 @@ RSpec.describe 'Domain Blocks' do
|
|||
Fabricate(:domain_block, domain: 'bar.com', severity: :suspend)
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
it 'returns existing domain block in error', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(422)
|
||||
end
|
||||
|
||||
it 'returns existing domain block in error' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:existing_domain_block][:domain]).to eq('bar.com')
|
||||
end
|
||||
end
|
||||
|
@ -241,15 +234,10 @@ RSpec.describe 'Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the updated domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the updated domain block' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match a_hash_including(
|
||||
{
|
||||
id: domain_block.id.to_s,
|
||||
|
@ -283,15 +271,10 @@ RSpec.describe 'Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the domain block' do
|
||||
subject
|
||||
|
||||
expect(DomainBlock.find_by(id: domain_block.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -93,15 +93,10 @@ RSpec.describe 'Email Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
context 'when email domain block exists' do
|
||||
it 'returns http success' do
|
||||
it 'returns the correct blocked domain', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct blocked domain' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:domain]).to eq(email_domain_block.domain)
|
||||
end
|
||||
end
|
||||
|
@ -126,15 +121,10 @@ RSpec.describe 'Email Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct blocked email domain', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct blocked email domain' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:domain]).to eq(params[:domain])
|
||||
end
|
||||
|
||||
|
@ -182,21 +172,11 @@ RSpec.describe 'Email Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes email domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns an empty body' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to be_empty
|
||||
end
|
||||
|
||||
it 'deletes email domain block' do
|
||||
subject
|
||||
|
||||
expect(EmailDomainBlock.find_by(id: email_domain_block.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -84,15 +84,10 @@ RSpec.describe 'IP Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct ip block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct ip block' do
|
||||
subject
|
||||
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:ip]).to eq("#{ip_block.ip}/#{ip_block.ip.prefix}")
|
||||
|
@ -119,15 +114,10 @@ RSpec.describe 'IP Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct ip block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct ip block' do
|
||||
subject
|
||||
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:ip]).to eq("#{params[:ip]}/32")
|
||||
|
@ -186,15 +176,10 @@ RSpec.describe 'IP Blocks' do
|
|||
let!(:ip_block) { IpBlock.create(ip: '185.200.13.3', severity: 'no_access', comment: 'Spam', expires_in: 48.hours) }
|
||||
let(:params) { { severity: 'sign_up_requires_approval', comment: 'Decreasing severity' } }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct ip block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct ip block' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(hash_including({
|
||||
ip: "#{ip_block.ip}/#{ip_block.ip.prefix}",
|
||||
severity: 'sign_up_requires_approval',
|
||||
|
@ -226,21 +211,11 @@ RSpec.describe 'IP Blocks' do
|
|||
|
||||
let!(:ip_block) { IpBlock.create(ip: '185.200.13.3', severity: 'no_access') }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the ip block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns an empty body' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to be_empty
|
||||
end
|
||||
|
||||
it 'deletes the ip block' do
|
||||
subject
|
||||
|
||||
expect(IpBlock.find_by(id: ip_block.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -122,15 +122,10 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the requested report content', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the requested report content' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to include(
|
||||
{
|
||||
id: report.id.to_s,
|
||||
|
@ -155,18 +150,10 @@ RSpec.describe 'Reports' do
|
|||
let!(:report) { Fabricate(:report, category: :other) }
|
||||
let(:params) { { category: 'spam' } }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
it 'updates the report category', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.category }.from('other').to('spam')
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the report category' do
|
||||
expect { subject }.to change { report.reload.category }.from('other').to('spam')
|
||||
end
|
||||
|
||||
it 'returns the updated report content' do
|
||||
subject
|
||||
|
||||
report.reload
|
||||
|
||||
|
@ -196,14 +183,9 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks report as resolved' do
|
||||
it 'marks report as resolved', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.unresolved? }.from(true).to(false)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -217,14 +199,9 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks report as unresolved' do
|
||||
it 'marks report as unresolved', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.unresolved? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -238,14 +215,9 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'assigns report to the requesting user' do
|
||||
it 'assigns report to the requesting user', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.assigned_account_id }.from(nil).to(user.account.id)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -259,14 +231,9 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'unassigns report from assignee' do
|
||||
it 'unassigns report from assignee', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.assigned_account_id }.from(user.account.id).to(nil)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
129
spec/requests/api/v1/admin/trends/links/links_spec.rb
Normal file
129
spec/requests/api/v1/admin/trends/links/links_spec.rb
Normal file
|
@ -0,0 +1,129 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Links' do
|
||||
let(:role) { UserRole.find_by(name: 'Admin') }
|
||||
let(:user) { Fabricate(:user, role: role) }
|
||||
let(:scopes) { 'admin:read admin:write' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/admin/trends/links' do
|
||||
subject do
|
||||
get '/api/v1/admin/trends/links', headers: headers
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/admin/trends/links/:id/approve' do
|
||||
subject do
|
||||
post "/api/v1/admin/trends/links/#{preview_card.id}/approve", headers: headers
|
||||
end
|
||||
|
||||
let(:preview_card) { Fabricate(:preview_card, trendable: false) }
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read write'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'sets the link as trendable' do
|
||||
expect { subject }.to change { preview_card.reload.trendable }.from(false).to(true)
|
||||
end
|
||||
|
||||
it 'returns the link data' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(
|
||||
a_hash_including(
|
||||
url: preview_card.url,
|
||||
title: preview_card.title,
|
||||
description: preview_card.description,
|
||||
type: 'link',
|
||||
requires_review: false
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the link does not exist' do
|
||||
it 'returns http not found' do
|
||||
post '/api/v1/admin/trends/links/-1/approve', headers: headers
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without an authorization header' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/admin/trends/links/:id/reject' do
|
||||
subject do
|
||||
post "/api/v1/admin/trends/links/#{preview_card.id}/reject", headers: headers
|
||||
end
|
||||
|
||||
let(:preview_card) { Fabricate(:preview_card, trendable: false) }
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read write'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'does not set the link as trendable' do
|
||||
expect { subject }.to_not(change { preview_card.reload.trendable })
|
||||
end
|
||||
|
||||
it 'returns the link data' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(
|
||||
a_hash_including(
|
||||
url: preview_card.url,
|
||||
title: preview_card.title,
|
||||
description: preview_card.description,
|
||||
type: 'link',
|
||||
requires_review: false
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the link does not exist' do
|
||||
it 'returns http not found' do
|
||||
post '/api/v1/admin/trends/links/-1/reject', headers: headers
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without an authorization header' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,14 +12,10 @@ describe 'Credentials' do
|
|||
let(:token) { Fabricate(:accessible_access_token, scopes: 'read', application: Fabricate(:application)) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the app information correctly', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the app information correctly' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(
|
||||
a_hash_including(
|
||||
|
|
|
@ -23,20 +23,11 @@ RSpec.describe 'Apps' do
|
|||
end
|
||||
|
||||
context 'with valid params' do
|
||||
it 'returns http success' do
|
||||
it 'creates an OAuth app', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates an OAuth app' do
|
||||
subject
|
||||
|
||||
expect(Doorkeeper::Application.find_by(name: client_name)).to be_present
|
||||
end
|
||||
|
||||
it 'returns client ID and client secret' do
|
||||
subject
|
||||
|
||||
body = body_as_json
|
||||
|
||||
|
@ -58,15 +49,10 @@ RSpec.describe 'Apps' do
|
|||
context 'with many duplicate scopes' do
|
||||
let(:scopes) { (%w(read) * 40).join(' ') }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'only saves the scope once', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'only saves the scope once' do
|
||||
subject
|
||||
|
||||
expect(Doorkeeper::Application.find_by(name: client_name).scopes.to_s).to eq 'read'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,15 +22,10 @@ RSpec.describe 'Domain blocks' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:blocks'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the domains blocked by the requesting user', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the domains blocked by the requesting user' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(blocked_domains)
|
||||
end
|
||||
|
||||
|
@ -54,15 +49,10 @@ RSpec.describe 'Domain blocks' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:blocks'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a domain block' do
|
||||
subject
|
||||
|
||||
expect(user.account.domain_blocking?(params[:domain])).to be(true)
|
||||
end
|
||||
|
||||
|
@ -100,15 +90,10 @@ RSpec.describe 'Domain blocks' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:blocks'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the specified domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the specified domain block' do
|
||||
subject
|
||||
|
||||
expect(user.account.domain_blocking?('example.com')).to be(false)
|
||||
end
|
||||
|
||||
|
|
71
spec/requests/api/v1/favourites_spec.rb
Normal file
71
spec/requests/api/v1/favourites_spec.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Favourites' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'read:favourites' }
|
||||
let(:headers) { { Authorization: "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/favourites' do
|
||||
subject do
|
||||
get '/api/v1/favourites', headers: headers, params: params
|
||||
end
|
||||
|
||||
let(:params) { {} }
|
||||
let!(:favourites) { Fabricate.times(3, :favourite, account: user.account) }
|
||||
|
||||
let(:expected_response) do
|
||||
favourites.map do |favourite|
|
||||
a_hash_including(id: favourite.status.id.to_s, account: a_hash_including(id: favourite.status.account.id.to_s))
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write'
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the favourites' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(expected_response)
|
||||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 2 } }
|
||||
|
||||
it 'returns only the requested number of favourites' do
|
||||
subject
|
||||
|
||||
expect(body_as_json.size).to eq(params[:limit])
|
||||
end
|
||||
|
||||
it 'sets the correct pagination header for the prev path' do
|
||||
subject
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq(api_v1_favourites_url(limit: params[:limit], min_id: favourites.last.id))
|
||||
end
|
||||
|
||||
it 'sets the correct pagination header for the next path' do
|
||||
subject
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq(api_v1_favourites_url(limit: params[:limit], max_id: favourites[1].id))
|
||||
end
|
||||
end
|
||||
|
||||
context 'without an authorization header' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -32,15 +32,10 @@ RSpec.describe 'Follow requests' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected content from accounts requesting to follow', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected content from accounts requesting to follow' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(expected_response)
|
||||
end
|
||||
|
||||
|
@ -68,19 +63,9 @@ RSpec.describe 'Follow requests' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'allows the requesting follower to follow' do
|
||||
it 'allows the requesting follower to follow', :aggregate_failures do
|
||||
expect { subject }.to change { follower.following?(user.account) }.from(false).to(true)
|
||||
end
|
||||
|
||||
it 'returns JSON with followed_by set to true' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json[:followed_by]).to be true
|
||||
end
|
||||
end
|
||||
|
@ -98,21 +83,11 @@ RSpec.describe 'Follow requests' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the follow request', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the follow request' do
|
||||
subject
|
||||
|
||||
expect(FollowRequest.where(target_account: user.account, account: follower)).to_not exist
|
||||
end
|
||||
|
||||
it 'returns JSON with followed_by set to false' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:followed_by]).to be false
|
||||
end
|
||||
end
|
||||
|
|
65
spec/requests/api/v1/followed_tags_spec.rb
Normal file
65
spec/requests/api/v1/followed_tags_spec.rb
Normal file
|
@ -0,0 +1,65 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Followed tags' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'read:follows' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/followed_tags' do
|
||||
subject do
|
||||
get '/api/v1/followed_tags', headers: headers, params: params
|
||||
end
|
||||
|
||||
let!(:tag_follows) { Fabricate.times(5, :tag_follow, account: user.account) }
|
||||
let(:params) { {} }
|
||||
|
||||
let(:expected_response) do
|
||||
tag_follows.map do |tag_follow|
|
||||
a_hash_including(name: tag_follow.tag.name, following: true)
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
Fabricate(:tag_follow)
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'returns the followed tags correctly' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(expected_response)
|
||||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 3 } }
|
||||
|
||||
it 'returns only the requested number of follow tags' do
|
||||
subject
|
||||
|
||||
expect(body_as_json.size).to eq(params[:limit])
|
||||
end
|
||||
|
||||
it 'sets the correct pagination header for the prev path' do
|
||||
subject
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq(api_v1_followed_tags_url(limit: params[:limit], since_id: tag_follows.last.id))
|
||||
end
|
||||
|
||||
it 'sets the correct pagination header for the next path' do
|
||||
subject
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq(api_v1_followed_tags_url(limit: params[:limit], max_id: tag_follows[2].id))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -51,16 +51,11 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected lists', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected lists' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(expected_response_with_antennas)
|
||||
expect(body_as_json).to match_array(expected_response)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -73,15 +68,10 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the requested list correctly', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the requested list correctly' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to eq({
|
||||
id: list.id.to_s,
|
||||
title: list.title,
|
||||
|
@ -119,21 +109,11 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the new list', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the new list' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(a_hash_including(title: 'my list', replies_policy: 'none', exclusive: true))
|
||||
end
|
||||
|
||||
it 'creates a list' do
|
||||
subject
|
||||
|
||||
expect(List.where(account: user.account).count).to eq(1)
|
||||
end
|
||||
|
||||
|
@ -168,15 +148,10 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the updated list', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the updated list' do
|
||||
subject
|
||||
|
||||
list.reload
|
||||
|
||||
expect(body_as_json).to eq({
|
||||
|
@ -228,15 +203,10 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the list', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the list' do
|
||||
subject
|
||||
|
||||
expect(List.where(id: list.id)).to_not exist
|
||||
end
|
||||
|
||||
|
|
89
spec/requests/api/v1/reports_spec.rb
Normal file
89
spec/requests/api/v1/reports_spec.rb
Normal file
|
@ -0,0 +1,89 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Reports' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'write:reports' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'POST /api/v1/reports' do
|
||||
subject do
|
||||
post '/api/v1/reports', headers: headers, params: params
|
||||
end
|
||||
|
||||
let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:target_account) { status.account }
|
||||
let(:category) { 'other' }
|
||||
let(:forward) { nil }
|
||||
let(:rule_ids) { nil }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
status_ids: [status.id],
|
||||
account_id: target_account.id,
|
||||
comment: 'reasons',
|
||||
category: category,
|
||||
rule_ids: rule_ids,
|
||||
forward: forward,
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:reports'
|
||||
|
||||
it 'creates a report', :aggregate_failures do
|
||||
perform_enqueued_jobs do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to match(
|
||||
a_hash_including(
|
||||
status_ids: [status.id.to_s],
|
||||
category: category,
|
||||
comment: 'reasons'
|
||||
)
|
||||
)
|
||||
|
||||
expect(target_account.targeted_reports).to_not be_empty
|
||||
expect(target_account.targeted_reports.first.comment).to eq 'reasons'
|
||||
|
||||
expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a status does not belong to the reported account' do
|
||||
let(:target_account) { Fabricate(:account) }
|
||||
|
||||
it 'returns http not found' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a category is chosen' do
|
||||
let(:category) { 'spam' }
|
||||
|
||||
it 'saves category' do
|
||||
subject
|
||||
|
||||
expect(target_account.targeted_reports.first.spam?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when violated rules are chosen' do
|
||||
let(:rule) { Fabricate(:rule) }
|
||||
let(:category) { 'violation' }
|
||||
let(:rule_ids) { [rule.id] }
|
||||
|
||||
it 'saves category and rule_ids' do
|
||||
subject
|
||||
|
||||
expect(target_account.targeted_reports.first.violation?).to be true
|
||||
expect(target_account.targeted_reports.first.rule_ids).to contain_exactly(rule.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
72
spec/requests/api/v1/statuses/sources_spec.rb
Normal file
72
spec/requests/api/v1/statuses/sources_spec.rb
Normal file
|
@ -0,0 +1,72 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Sources' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'read:statuses' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/statuses/:status_id/source' do
|
||||
subject do
|
||||
get "/api/v1/statuses/#{status.id}/source", headers: headers
|
||||
end
|
||||
|
||||
let(:status) { Fabricate(:status) }
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:statuses'
|
||||
|
||||
context 'with public status' do
|
||||
it 'returns the source properties of the status', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to eq({
|
||||
id: status.id.to_s,
|
||||
text: status.text,
|
||||
spoiler_text: status.spoiler_text,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
context 'with private status of non-followed account' do
|
||||
let(:status) { Fabricate(:status, visibility: :private) }
|
||||
|
||||
it 'returns http not found' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with private status of followed account' do
|
||||
let(:status) { Fabricate(:status, visibility: :private) }
|
||||
|
||||
before do
|
||||
user.account.follow!(status.account)
|
||||
end
|
||||
|
||||
it 'returns the source properties of the status', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to eq({
|
||||
id: status.id.to_s,
|
||||
text: status.text,
|
||||
spoiler_text: status.spoiler_text,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
context 'without an authorization header' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -17,15 +17,10 @@ RSpec.describe 'Tags' do
|
|||
let!(:tag) { Fabricate(:tag) }
|
||||
let(:name) { tag.name }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the tag', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the tag' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:name]).to eq(name)
|
||||
end
|
||||
end
|
||||
|
@ -62,15 +57,10 @@ RSpec.describe 'Tags' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
context 'when the tag exists' do
|
||||
it 'returns http success' do
|
||||
it 'creates follow', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'creates follow' do
|
||||
subject
|
||||
|
||||
expect(TagFollow.where(tag: tag, account: user.account)).to exist
|
||||
end
|
||||
end
|
||||
|
@ -78,21 +68,11 @@ RSpec.describe 'Tags' do
|
|||
context 'when the tag does not exist' do
|
||||
let(:name) { 'hoge' }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a new tag with the specified name', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a new tag with the specified name' do
|
||||
subject
|
||||
|
||||
expect(Tag.where(name: name)).to exist
|
||||
end
|
||||
|
||||
it 'creates follow' do
|
||||
subject
|
||||
|
||||
expect(TagFollow.where(tag: Tag.find_by(name: name), account: user.account)).to exist
|
||||
end
|
||||
end
|
||||
|
@ -133,15 +113,10 @@ RSpec.describe 'Tags' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the follow', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the follow' do
|
||||
subject
|
||||
|
||||
expect(TagFollow.where(tag: tag, account: user.account)).to_not exist
|
||||
end
|
||||
|
||||
|
|
112
spec/requests/api/v1/timelines/tag_spec.rb
Normal file
112
spec/requests/api/v1/timelines/tag_spec.rb
Normal file
|
@ -0,0 +1,112 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Tag' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'read:statuses' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
shared_examples 'a successful request to the tag timeline' do
|
||||
it 'returns the expected statuses', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.pluck(:id)).to match_array(expected_statuses.map { |status| status.id.to_s })
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/timelines/tag/:hashtag' do
|
||||
subject do
|
||||
get "/api/v1/timelines/tag/#{hashtag}", headers: headers, params: params
|
||||
end
|
||||
|
||||
let(:account) { Fabricate(:account) }
|
||||
let!(:private_status) { PostStatusService.new.call(account, visibility: :private, text: '#life could be a dream') } # rubocop:disable RSpec/LetSetup
|
||||
let!(:life_status) { PostStatusService.new.call(account, text: 'tell me what is my #life without your #love') }
|
||||
let!(:war_status) { PostStatusService.new.call(user.account, text: '#war, war never changes') }
|
||||
let!(:love_status) { PostStatusService.new.call(account, text: 'what is #love?') }
|
||||
let(:params) { {} }
|
||||
let(:hashtag) { 'life' }
|
||||
|
||||
context 'when given only one hashtag' do
|
||||
let(:expected_statuses) { [life_status] }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
|
||||
context 'with any param' do
|
||||
let(:expected_statuses) { [life_status, love_status] }
|
||||
let(:params) { { any: %(love) } }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
|
||||
context 'with all param' do
|
||||
let(:expected_statuses) { [life_status] }
|
||||
let(:params) { { all: %w(love) } }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
|
||||
context 'with none param' do
|
||||
let(:expected_statuses) { [war_status] }
|
||||
let(:hashtag) { 'war' }
|
||||
let(:params) { { none: %w(life love) } }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:hashtag) { 'love' }
|
||||
let(:params) { { limit: 1 } }
|
||||
|
||||
it 'returns only the requested number of statuses' do
|
||||
subject
|
||||
|
||||
expect(body_as_json.size).to eq(params[:limit])
|
||||
end
|
||||
|
||||
it 'sets the correct pagination headers', :aggregate_failures do
|
||||
subject
|
||||
|
||||
headers = response.headers['Link']
|
||||
|
||||
expect(headers.find_link(%w(rel prev)).href).to eq(api_v1_timelines_tag_url(limit: 1, min_id: love_status.id.to_s))
|
||||
expect(headers.find_link(%w(rel next)).href).to eq(api_v1_timelines_tag_url(limit: 1, max_id: love_status.id.to_s))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the instance allows public preview' do
|
||||
context 'when the user is not authenticated' do
|
||||
let(:headers) { {} }
|
||||
let(:expected_statuses) { [life_status] }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the instance does not allow public preview' do
|
||||
before do
|
||||
Form::AdminSettings.new(timeline_preview: false).save
|
||||
end
|
||||
|
||||
context 'when the user is not authenticated' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is authenticated' do
|
||||
let(:expected_statuses) { [life_status] }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
spec/support/signed_request_helpers.rb
Normal file
21
spec/support/signed_request_helpers.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module SignedRequestHelpers
|
||||
def get(path, headers: nil, sign_with: nil, **args)
|
||||
return super path, headers: headers, **args if sign_with.nil?
|
||||
|
||||
headers ||= {}
|
||||
headers['Date'] = Time.now.utc.httpdate
|
||||
headers['Host'] = ENV.fetch('LOCAL_DOMAIN')
|
||||
signed_headers = headers.merge('(request-target)' => "get #{path}").slice('(request-target)', 'Host', 'Date')
|
||||
|
||||
key_id = ActivityPub::TagManager.instance.key_uri_for(sign_with)
|
||||
keypair = sign_with.keypair
|
||||
signed_string = signed_headers.map { |key, value| "#{key.downcase}: #{value}" }.join("\n")
|
||||
signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), signed_string))
|
||||
|
||||
headers['Signature'] = "keyId=\"#{key_id}\",algorithm=\"rsa-sha256\",headers=\"#{signed_headers.keys.join(' ').downcase}\",signature=\"#{signature}\""
|
||||
|
||||
super path, headers: headers, **args
|
||||
end
|
||||
end
|
|
@ -67,39 +67,31 @@ describe MoveWorker do
|
|||
end
|
||||
|
||||
shared_examples 'block and mute handling' do
|
||||
it 'makes blocks carry over and add a note' do
|
||||
it 'makes blocks and mutes carry over and adds a note' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
|
||||
expect(block_service).to have_received(:call).with(blocking_account, target_account)
|
||||
expect(AccountNote.find_by(account: blocking_account, target_account: target_account).comment).to include(source_account.acct)
|
||||
end
|
||||
|
||||
it 'makes mutes carry over and add a note' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(muting_account.muting?(target_account)).to be true
|
||||
expect(AccountNote.find_by(account: muting_account, target_account: target_account).comment).to include(source_account.acct)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'followers count handling' do
|
||||
it 'updates the source account followers count' do
|
||||
it 'updates the source and target account followers counts' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(source_account.reload.followers_count).to eq(source_account.passive_relationships.count)
|
||||
end
|
||||
|
||||
it 'updates the target account followers count' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(source_account.reload.followers_count).to eq(source_account.passive_relationships.count)
|
||||
expect(target_account.reload.followers_count).to eq(target_account.passive_relationships.count)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'lists handling' do
|
||||
it 'puts the new account on the list' do
|
||||
it 'puts the new account on the list and makes valid lists', sidekiq: :inline do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(list.accounts.include?(target_account)).to be true
|
||||
end
|
||||
|
||||
it 'does not create invalid list memberships' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(list.accounts.include?(target_account)).to be true
|
||||
expect(ListAccount.all).to all be_valid
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue