Rewrite /api/v1/accounts tests as request specs (#27888)

This commit is contained in:
Claire 2023-11-17 12:34:49 +01:00 committed by GitHub
parent 0e9801443f
commit 9257737675
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 136 additions and 106 deletions

View file

@ -1,53 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
describe 'GET /api/v1/accounts/{account_id}' do
it 'returns account entity as 200 OK' do
account = Fabricate(:account)
get "/api/v1/accounts/#{account.id}"
aggregate_failures do
expect(response).to have_http_status(200)
expect(body_as_json[:id]).to eq(account.id.to_s)
end
end
it 'returns 404 if account not found' do
get '/api/v1/accounts/1'
aggregate_failures do
expect(response).to have_http_status(404)
expect(body_as_json[:error]).to eq('Record not found')
end
end
context 'when with token' do
it 'returns account entity as 200 OK if token is valid' do
account = Fabricate(:account)
user = Fabricate(:user, account: account)
token = Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts').token
get "/api/v1/accounts/#{account.id}", headers: { Authorization: "Bearer #{token}" }
aggregate_failures do
expect(response).to have_http_status(200)
expect(body_as_json[:id]).to eq(account.id.to_s)
end
end
it 'returns 403 if scope of token is invalid' do
account = Fabricate(:account)
user = Fabricate(:user, account: account)
token = Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:statuses').token
get "/api/v1/accounts/#{account.id}", headers: { Authorization: "Bearer #{token}" }
aggregate_failures do
expect(response).to have_http_status(403)
expect(body_as_json[:error]).to eq('This action is outside the authorized scopes')
end
end
end
end

View file

@ -2,59 +2,100 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Api::V1::AccountsController do describe '/api/v1/accounts' do
render_views
let(:user) { Fabricate(:user) } let(:user) { Fabricate(:user) }
let(:scopes) { '' } let(:scopes) { '' }
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
before do describe 'GET /api/v1/accounts/:id' do
allow(controller).to receive(:doorkeeper_token) { token } context 'when logged out' do
let(:account) { Fabricate(:account) }
it 'returns account entity as 200 OK', :aggregate_failures do
get "/api/v1/accounts/#{account.id}"
expect(response).to have_http_status(200)
expect(body_as_json[:id]).to eq(account.id.to_s)
end
end end
describe 'POST #create' do context 'when the account does not exist' do
let(:app) { Fabricate(:application) } it 'returns http not found' do
let(:token) { Doorkeeper::AccessToken.find_or_create_for(application: app, resource_owner: nil, scopes: 'read write', use_refresh_token: false) } get '/api/v1/accounts/1'
expect(response).to have_http_status(404)
expect(body_as_json[:error]).to eq('Record not found')
end
end
context 'when logged in' do
subject do
get "/api/v1/accounts/#{account.id}", headers: headers
end
let(:account) { Fabricate(:account) }
let(:scopes) { 'read:accounts' }
it 'returns account entity as 200 OK', :aggregate_failures do
subject
expect(response).to have_http_status(200)
expect(body_as_json[:id]).to eq(account.id.to_s)
end
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
end
end
describe 'POST /api/v1/accounts' do
subject do
post '/api/v1/accounts', headers: headers, params: { username: 'test', password: '12345678', email: 'hello@world.tld', agreement: agreement }
end
let(:client_app) { Fabricate(:application) }
let(:token) { Doorkeeper::AccessToken.find_or_create_for(application: client_app, resource_owner: nil, scopes: 'read write', use_refresh_token: false) }
let(:agreement) { nil } let(:agreement) { nil }
before do
post :create, params: { username: 'test', password: '12345678', email: 'hello@world.tld', agreement: agreement }
end
context 'when given truthy agreement' do context 'when given truthy agreement' do
let(:agreement) { 'true' } let(:agreement) { 'true' }
it 'creates a user', :aggregate_failures do it 'creates a user', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:access_token]).to_not be_blank expect(body_as_json[:access_token]).to_not be_blank
user = User.find_by(email: 'hello@world.tld') user = User.find_by(email: 'hello@world.tld')
expect(user).to_not be_nil expect(user).to_not be_nil
expect(user.created_by_application_id).to eq app.id expect(user.created_by_application_id).to eq client_app.id
end end
end end
context 'when given no agreement' do context 'when given no agreement' do
it 'returns http unprocessable entity' do it 'returns http unprocessable entity' do
subject
expect(response).to have_http_status(422) expect(response).to have_http_status(422)
end end
end end
end end
describe 'POST #follow' do describe 'POST /api/v1/accounts/:id/follow' do
let(:scopes) { 'write:follows' } let(:scopes) { 'write:follows' }
let(:other_account) { Fabricate(:account, username: 'bob', locked: locked) } let(:other_account) { Fabricate(:account, username: 'bob', locked: locked) }
context 'when posting to an other account' do context 'when posting to an other account' do
before do subject do
post :follow, params: { id: other_account.id } post "/api/v1/accounts/#{other_account.id}/follow", headers: headers
end end
context 'with unlocked account' do context 'with unlocked account' do
let(:locked) { false } let(:locked) { false }
it 'creates a following relation between user and target user', :aggregate_failures do it 'creates a following relation between user and target user', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
json = body_as_json json = body_as_json
@ -72,6 +113,8 @@ RSpec.describe Api::V1::AccountsController do
let(:locked) { true } let(:locked) { true }
it 'creates a follow request relation between user and target user', :aggregate_failures do it 'creates a follow request relation between user and target user', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
json = body_as_json json = body_as_json
@ -94,48 +137,53 @@ RSpec.describe Api::V1::AccountsController do
end end
it 'changes reblogs option' do it 'changes reblogs option' do
post :follow, params: { id: other_account.id, reblogs: true } post "/api/v1/accounts/#{other_account.id}/follow", headers: headers, params: { reblogs: true }
json = body_as_json expect(body_as_json).to include({
following: true,
expect(json[:following]).to be true showing_reblogs: true,
expect(json[:showing_reblogs]).to be true notifying: false,
expect(json[:notifying]).to be false })
end end
it 'changes notify option' do it 'changes notify option' do
post :follow, params: { id: other_account.id, notify: true } post "/api/v1/accounts/#{other_account.id}/follow", headers: headers, params: { notify: true }
json = body_as_json expect(body_as_json).to include({
following: true,
expect(json[:following]).to be true showing_reblogs: false,
expect(json[:showing_reblogs]).to be false notifying: true,
expect(json[:notifying]).to be true })
end end
it 'changes languages option' do it 'changes languages option' do
post :follow, params: { id: other_account.id, languages: %w(en es) } post "/api/v1/accounts/#{other_account.id}/follow", headers: headers, params: { languages: %w(en es) }
json = body_as_json expect(body_as_json).to include({
following: true,
expect(json[:following]).to be true showing_reblogs: false,
expect(json[:showing_reblogs]).to be false notifying: false,
expect(json[:notifying]).to be false languages: match_array(%w(en es)),
expect(json[:languages]).to match_array %w(en es) })
end end
end end
end end
describe 'POST #unfollow' do describe 'POST /api/v1/accounts/:id/unfollow' do
subject do
post "/api/v1/accounts/#{other_account.id}/unfollow", headers: headers
end
let(:scopes) { 'write:follows' } let(:scopes) { 'write:follows' }
let(:other_account) { Fabricate(:account, username: 'bob') } let(:other_account) { Fabricate(:account, username: 'bob') }
before do before do
user.account.follow!(other_account) user.account.follow!(other_account)
post :unfollow, params: { id: other_account.id }
end end
it 'removes the following relation between user and target user', :aggregate_failures do it 'removes the following relation between user and target user', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(user.account.following?(other_account)).to be false expect(user.account.following?(other_account)).to be false
end end
@ -143,16 +191,21 @@ RSpec.describe Api::V1::AccountsController do
it_behaves_like 'forbidden for wrong scope', 'read:accounts' it_behaves_like 'forbidden for wrong scope', 'read:accounts'
end end
describe 'POST #remove_from_followers' do describe 'POST /api/v1/accounts/:id/remove_from_followers' do
subject do
post "/api/v1/accounts/#{other_account.id}/remove_from_followers", headers: headers
end
let(:scopes) { 'write:follows' } let(:scopes) { 'write:follows' }
let(:other_account) { Fabricate(:account, username: 'bob') } let(:other_account) { Fabricate(:account, username: 'bob') }
before do before do
other_account.follow!(user.account) other_account.follow!(user.account)
post :remove_from_followers, params: { id: other_account.id }
end end
it 'removes the followed relation between user and target user', :aggregate_failures do it 'removes the followed relation between user and target user', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(user.account.followed_by?(other_account)).to be false expect(user.account.followed_by?(other_account)).to be false
end end
@ -160,16 +213,21 @@ RSpec.describe Api::V1::AccountsController do
it_behaves_like 'forbidden for wrong scope', 'read:accounts' it_behaves_like 'forbidden for wrong scope', 'read:accounts'
end end
describe 'POST #block' do describe 'POST /api/v1/accounts/:id/block' do
subject do
post "/api/v1/accounts/#{other_account.id}/block", headers: headers
end
let(:scopes) { 'write:blocks' } let(:scopes) { 'write:blocks' }
let(:other_account) { Fabricate(:account, username: 'bob') } let(:other_account) { Fabricate(:account, username: 'bob') }
before do before do
user.account.follow!(other_account) user.account.follow!(other_account)
post :block, params: { id: other_account.id }
end end
it 'creates a blocking relation', :aggregate_failures do it 'creates a blocking relation', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(user.account.following?(other_account)).to be false expect(user.account.following?(other_account)).to be false
expect(user.account.blocking?(other_account)).to be true expect(user.account.blocking?(other_account)).to be true
@ -178,16 +236,21 @@ RSpec.describe Api::V1::AccountsController do
it_behaves_like 'forbidden for wrong scope', 'read:accounts' it_behaves_like 'forbidden for wrong scope', 'read:accounts'
end end
describe 'POST #unblock' do describe 'POST /api/v1/accounts/:id/unblock' do
subject do
post "/api/v1/accounts/#{other_account.id}/unblock", headers: headers
end
let(:scopes) { 'write:blocks' } let(:scopes) { 'write:blocks' }
let(:other_account) { Fabricate(:account, username: 'bob') } let(:other_account) { Fabricate(:account, username: 'bob') }
before do before do
user.account.block!(other_account) user.account.block!(other_account)
post :unblock, params: { id: other_account.id }
end end
it 'removes the blocking relation between user and target user', :aggregate_failures do it 'removes the blocking relation between user and target user', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(user.account.blocking?(other_account)).to be false expect(user.account.blocking?(other_account)).to be false
end end
@ -195,16 +258,21 @@ RSpec.describe Api::V1::AccountsController do
it_behaves_like 'forbidden for wrong scope', 'read:accounts' it_behaves_like 'forbidden for wrong scope', 'read:accounts'
end end
describe 'POST #mute' do describe 'POST /api/v1/accounts/:id/mute' do
subject do
post "/api/v1/accounts/#{other_account.id}/mute", headers: headers
end
let(:scopes) { 'write:mutes' } let(:scopes) { 'write:mutes' }
let(:other_account) { Fabricate(:account, username: 'bob') } let(:other_account) { Fabricate(:account, username: 'bob') }
before do before do
user.account.follow!(other_account) user.account.follow!(other_account)
post :mute, params: { id: other_account.id }
end end
it 'mutes notifications', :aggregate_failures do it 'mutes notifications', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(user.account.following?(other_account)).to be true expect(user.account.following?(other_account)).to be true
expect(user.account.muting?(other_account)).to be true expect(user.account.muting?(other_account)).to be true
@ -214,16 +282,21 @@ RSpec.describe Api::V1::AccountsController do
it_behaves_like 'forbidden for wrong scope', 'read:accounts' it_behaves_like 'forbidden for wrong scope', 'read:accounts'
end end
describe 'POST #mute with notifications set to false' do describe 'POST /api/v1/accounts/:id/mute with notifications set to false' do
subject do
post "/api/v1/accounts/#{other_account.id}/mute", headers: headers, params: { notifications: false }
end
let(:scopes) { 'write:mutes' } let(:scopes) { 'write:mutes' }
let(:other_account) { Fabricate(:account, username: 'bob') } let(:other_account) { Fabricate(:account, username: 'bob') }
before do before do
user.account.follow!(other_account) user.account.follow!(other_account)
post :mute, params: { id: other_account.id, notifications: false }
end end
it 'does not mute notifications', :aggregate_failures do it 'does not mute notifications', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(user.account.following?(other_account)).to be true expect(user.account.following?(other_account)).to be true
expect(user.account.muting?(other_account)).to be true expect(user.account.muting?(other_account)).to be true
@ -233,16 +306,21 @@ RSpec.describe Api::V1::AccountsController do
it_behaves_like 'forbidden for wrong scope', 'read:accounts' it_behaves_like 'forbidden for wrong scope', 'read:accounts'
end end
describe 'POST #mute with nonzero duration set' do describe 'POST /api/v1/accounts/:id/mute with nonzero duration set' do
subject do
post "/api/v1/accounts/#{other_account.id}/mute", headers: headers, params: { duration: 300 }
end
let(:scopes) { 'write:mutes' } let(:scopes) { 'write:mutes' }
let(:other_account) { Fabricate(:account, username: 'bob') } let(:other_account) { Fabricate(:account, username: 'bob') }
before do before do
user.account.follow!(other_account) user.account.follow!(other_account)
post :mute, params: { id: other_account.id, duration: 300 }
end end
it 'mutes notifications', :aggregate_failures do it 'mutes notifications', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(user.account.following?(other_account)).to be true expect(user.account.following?(other_account)).to be true
expect(user.account.muting?(other_account)).to be true expect(user.account.muting?(other_account)).to be true
@ -252,16 +330,21 @@ RSpec.describe Api::V1::AccountsController do
it_behaves_like 'forbidden for wrong scope', 'read:accounts' it_behaves_like 'forbidden for wrong scope', 'read:accounts'
end end
describe 'POST #unmute' do describe 'POST /api/v1/accounts/:id/unmute' do
subject do
post "/api/v1/accounts/#{other_account.id}/unmute", headers: headers
end
let(:scopes) { 'write:mutes' } let(:scopes) { 'write:mutes' }
let(:other_account) { Fabricate(:account, username: 'bob') } let(:other_account) { Fabricate(:account, username: 'bob') }
before do before do
user.account.mute!(other_account) user.account.mute!(other_account)
post :unmute, params: { id: other_account.id }
end end
it 'removes the muting relation between user and target user', :aggregate_failures do it 'removes the muting relation between user and target user', :aggregate_failures do
subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(user.account.muting?(other_account)).to be false expect(user.account.muting?(other_account)).to be false
end end