Convert more API specs from controller->request style (#29004)
This commit is contained in:
parent
a25014de8f
commit
18945f62e0
10 changed files with 159 additions and 156 deletions
149
spec/requests/api/v1/accounts/statuses_spec.rb
Normal file
149
spec/requests/api/v1/accounts/statuses_spec.rb
Normal file
|
@ -0,0 +1,149 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'API V1 Accounts Statuses' 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/accounts/:account_id/statuses' do
|
||||
it 'returns expected headers', :aggregate_failures do
|
||||
Fabricate(:status, account: user.account)
|
||||
get "/api/v1/accounts/#{user.account.id}/statuses", params: { limit: 1 }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(links_from_header.size)
|
||||
.to eq(2)
|
||||
end
|
||||
|
||||
context 'with only media' do
|
||||
it 'returns http success' do
|
||||
get "/api/v1/accounts/#{user.account.id}/statuses", params: { only_media: true }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with exclude replies' do
|
||||
let!(:status) { Fabricate(:status, account: user.account) }
|
||||
let!(:status_self_reply) { Fabricate(:status, account: user.account, thread: status) }
|
||||
|
||||
before do
|
||||
Fabricate(:status, account: user.account, thread: Fabricate(:status)) # Reply to another user
|
||||
get "/api/v1/accounts/#{user.account.id}/statuses", params: { exclude_replies: true }, headers: headers
|
||||
end
|
||||
|
||||
it 'returns posts along with self replies', :aggregate_failures do
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
expect(body_as_json)
|
||||
.to have_attributes(size: 2)
|
||||
.and contain_exactly(
|
||||
include(id: status.id.to_s),
|
||||
include(id: status_self_reply.id.to_s)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with only own pinned' do
|
||||
before do
|
||||
Fabricate(:status_pin, account: user.account, status: Fabricate(:status, account: user.account))
|
||||
end
|
||||
|
||||
it 'returns http success and includes a header link' do
|
||||
get "/api/v1/accounts/#{user.account.id}/statuses", params: { pinned: true }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(links_from_header.size)
|
||||
.to eq(1)
|
||||
expect(links_from_header)
|
||||
.to contain_exactly(
|
||||
have_attributes(
|
||||
href: /pinned=true/,
|
||||
attr_pairs: contain_exactly(['rel', 'prev'])
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with enough pinned statuses to paginate' do
|
||||
before do
|
||||
stub_const 'Api::BaseController::DEFAULT_STATUSES_LIMIT', 1
|
||||
2.times { Fabricate(:status_pin, account: user.account) }
|
||||
end
|
||||
|
||||
it 'returns http success and header pagination links to prev and next' do
|
||||
get "/api/v1/accounts/#{user.account.id}/statuses", params: { pinned: true }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(links_from_header.size)
|
||||
.to eq(2)
|
||||
expect(links_from_header)
|
||||
.to contain_exactly(
|
||||
have_attributes(
|
||||
href: /pinned=true/,
|
||||
attr_pairs: contain_exactly(['rel', 'next'])
|
||||
),
|
||||
have_attributes(
|
||||
href: /pinned=true/,
|
||||
attr_pairs: contain_exactly(['rel', 'prev'])
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "with someone else's pinned statuses" do
|
||||
let(:account) { Fabricate(:account, username: 'bob', domain: 'example.com') }
|
||||
let(:status) { Fabricate(:status, account: account) }
|
||||
let(:private_status) { Fabricate(:status, account: account, visibility: :private) }
|
||||
|
||||
before do
|
||||
Fabricate(:status_pin, account: account, status: status)
|
||||
Fabricate(:status_pin, account: account, status: private_status)
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get "/api/v1/accounts/#{account.id}/statuses", params: { pinned: true }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
context 'when user does not follow account' do
|
||||
it 'lists the public status only' do
|
||||
get "/api/v1/accounts/#{account.id}/statuses", params: { pinned: true }, headers: headers
|
||||
|
||||
expect(body_as_json)
|
||||
.to contain_exactly(
|
||||
a_hash_including(id: status.id.to_s)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user follows account' do
|
||||
before do
|
||||
user.account.follow!(account)
|
||||
end
|
||||
|
||||
it 'lists both the public and the private statuses' do
|
||||
get "/api/v1/accounts/#{account.id}/statuses", params: { pinned: true }, headers: headers
|
||||
|
||||
expect(body_as_json)
|
||||
.to contain_exactly(
|
||||
a_hash_including(id: status.id.to_s),
|
||||
a_hash_including(id: private_status.id.to_s)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def links_from_header
|
||||
response
|
||||
.headers['Link']
|
||||
.links
|
||||
end
|
||||
end
|
47
spec/requests/api/v1/admin/trends/statuses_spec.rb
Normal file
47
spec/requests/api/v1/admin/trends/statuses_spec.rb
Normal file
|
@ -0,0 +1,47 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'API V1 Admin Trends Statuses' 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(:account) { Fabricate(:account) }
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/admin/trends/statuses' do
|
||||
it 'returns http success' do
|
||||
get '/api/v1/admin/trends/statuses', params: { account_id: account.id, limit: 2 }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/admin/trends/statuses/:id/approve' do
|
||||
before do
|
||||
post "/api/v1/admin/trends/statuses/#{status.id}/approve", headers: headers
|
||||
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 /api/v1/admin/trends/statuses/:id/unapprove' do
|
||||
before do
|
||||
post "/api/v1/admin/trends/statuses/#{status.id}/reject", headers: headers
|
||||
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
|
47
spec/requests/api/v1/admin/trends/tags_spec.rb
Normal file
47
spec/requests/api/v1/admin/trends/tags_spec.rb
Normal file
|
@ -0,0 +1,47 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'API V1 Admin Trends Tags' 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(:account) { Fabricate(:account) }
|
||||
let(:tag) { Fabricate(:tag) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/admin/trends/tags' do
|
||||
it 'returns http success' do
|
||||
get '/api/v1/admin/trends/tags', params: { account_id: account.id, limit: 2 }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/admin/trends/tags/:id/approve' do
|
||||
before do
|
||||
post "/api/v1/admin/trends/tags/#{tag.id}/approve", headers: headers
|
||||
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 /api/v1/admin/trends/tags/:id/reject' do
|
||||
before do
|
||||
post "/api/v1/admin/trends/tags/#{tag.id}/reject", headers: headers
|
||||
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
|
61
spec/requests/api/v1/announcements/reactions_spec.rb
Normal file
61
spec/requests/api/v1/announcements/reactions_spec.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'API V1 Announcements Reactions' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'write:favourites' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
let!(:announcement) { Fabricate(:announcement) }
|
||||
|
||||
describe 'PUT /api/v1/announcements/:announcement_id/reactions/:id' do
|
||||
context 'without token' do
|
||||
it 'returns http unauthorized' do
|
||||
put "/api/v1/announcements/#{announcement.id}/reactions/#{escaped_emoji}"
|
||||
|
||||
expect(response).to have_http_status 401
|
||||
end
|
||||
end
|
||||
|
||||
context 'with token' do
|
||||
before do
|
||||
put "/api/v1/announcements/#{announcement.id}/reactions/#{escaped_emoji}", headers: headers
|
||||
end
|
||||
|
||||
it 'creates reaction', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(announcement.announcement_reactions.find_by(name: '😂', account: user.account)).to_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE /api/v1/announcements/:announcement_id/reactions/:id' do
|
||||
before do
|
||||
announcement.announcement_reactions.create!(account: user.account, name: '😂')
|
||||
end
|
||||
|
||||
context 'without token' do
|
||||
it 'returns http unauthorized' do
|
||||
delete "/api/v1/announcements/#{announcement.id}/reactions/#{escaped_emoji}"
|
||||
expect(response).to have_http_status 401
|
||||
end
|
||||
end
|
||||
|
||||
context 'with token' do
|
||||
before do
|
||||
delete "/api/v1/announcements/#{announcement.id}/reactions/#{escaped_emoji}", headers: headers
|
||||
end
|
||||
|
||||
it 'creates reaction', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(announcement.announcement_reactions.find_by(name: '😂', account: user.account)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def escaped_emoji
|
||||
CGI.escape('😂')
|
||||
end
|
||||
end
|
55
spec/requests/api/v1/announcements_spec.rb
Normal file
55
spec/requests/api/v1/announcements_spec.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'API V1 Announcements' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'read' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
let!(:announcement) { Fabricate(:announcement) }
|
||||
|
||||
describe 'GET /api/v1/announcements' do
|
||||
context 'without token' do
|
||||
it 'returns http unprocessable entity' do
|
||||
get '/api/v1/announcements'
|
||||
|
||||
expect(response).to have_http_status 422
|
||||
end
|
||||
end
|
||||
|
||||
context 'with token' do
|
||||
before do
|
||||
get '/api/v1/announcements', headers: headers
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/announcements/:id/dismiss' do
|
||||
context 'without token' do
|
||||
it 'returns http unauthorized' do
|
||||
post "/api/v1/announcements/#{announcement.id}/dismiss"
|
||||
|
||||
expect(response).to have_http_status 401
|
||||
end
|
||||
end
|
||||
|
||||
context 'with token' do
|
||||
let(:scopes) { 'write:accounts' }
|
||||
|
||||
before do
|
||||
post "/api/v1/announcements/#{announcement.id}/dismiss", headers: headers
|
||||
end
|
||||
|
||||
it 'dismisses announcement', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(announcement.announcement_mutes.find_by(account: user.account)).to_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
51
spec/requests/api/v1/conversations_spec.rb
Normal file
51
spec/requests/api/v1/conversations_spec.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'API V1 Conversations' do
|
||||
let!(:user) { Fabricate(:user, account_attributes: { username: 'alice' }) }
|
||||
let(:scopes) { 'read:statuses' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
let(:other) { Fabricate(:user) }
|
||||
|
||||
describe 'GET /api/v1/conversations', :sidekiq_inline do
|
||||
before do
|
||||
PostStatusService.new.call(other.account, text: 'Hey @alice', visibility: 'direct')
|
||||
PostStatusService.new.call(user.account, text: 'Hey, nobody here', visibility: 'direct')
|
||||
end
|
||||
|
||||
it 'returns pagination headers', :aggregate_failures do
|
||||
get '/api/v1/conversations', params: { limit: 1 }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
|
||||
it 'returns conversations', :aggregate_failures do
|
||||
get '/api/v1/conversations', headers: headers
|
||||
|
||||
expect(body_as_json.size).to eq 2
|
||||
expect(body_as_json[0][:accounts].size).to eq 1
|
||||
end
|
||||
|
||||
context 'with since_id' do
|
||||
context 'when requesting old posts' do
|
||||
it 'returns conversations' do
|
||||
get '/api/v1/conversations', params: { since_id: Mastodon::Snowflake.id_at(1.hour.ago, with_random: false) }, headers: headers
|
||||
|
||||
expect(body_as_json.size).to eq 2
|
||||
end
|
||||
end
|
||||
|
||||
context 'when requesting posts in the future' do
|
||||
it 'returns no conversation' do
|
||||
get '/api/v1/conversations', params: { since_id: Mastodon::Snowflake.id_at(1.hour.from_now, with_random: false) }, headers: headers
|
||||
|
||||
expect(body_as_json.size).to eq 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
103
spec/requests/api/v1/filters_spec.rb
Normal file
103
spec/requests/api/v1/filters_spec.rb
Normal file
|
@ -0,0 +1,103 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'API V1 Filters' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/filters' do
|
||||
let(:scopes) { 'read:filters' }
|
||||
let!(:filter) { Fabricate(:custom_filter, account: user.account) }
|
||||
let!(:custom_filter_keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) }
|
||||
|
||||
it 'returns http success' do
|
||||
get '/api/v1/filters', headers: headers
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json)
|
||||
.to contain_exactly(
|
||||
include(id: custom_filter_keyword.id.to_s)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/filters' do
|
||||
let(:scopes) { 'write:filters' }
|
||||
let(:irreversible) { true }
|
||||
let(:whole_word) { false }
|
||||
|
||||
before do
|
||||
post '/api/v1/filters', params: { phrase: 'magic', context: %w(home), irreversible: irreversible, whole_word: whole_word }, headers: headers
|
||||
end
|
||||
|
||||
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)
|
||||
expect(filter.irreversible?).to be irreversible
|
||||
expect(filter.expires_at).to be_nil
|
||||
end
|
||||
|
||||
context 'with different parameters' do
|
||||
let(:irreversible) { false }
|
||||
let(:whole_word) { true }
|
||||
|
||||
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)
|
||||
expect(filter.irreversible?).to be irreversible
|
||||
expect(filter.expires_at).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/filters/:id' do
|
||||
let(:scopes) { 'read:filters' }
|
||||
let(:filter) { Fabricate(:custom_filter, account: user.account) }
|
||||
let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) }
|
||||
|
||||
it 'returns http success' do
|
||||
get "/api/v1/filters/#{keyword.id}", headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT /api/v1/filters/:id' do
|
||||
let(:scopes) { 'write:filters' }
|
||||
let(:filter) { Fabricate(:custom_filter, account: user.account) }
|
||||
let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) }
|
||||
|
||||
before do
|
||||
put "/api/v1/filters/#{keyword.id}", headers: headers, params: { phrase: 'updated' }
|
||||
end
|
||||
|
||||
it 'updates the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(keyword.reload.phrase).to eq 'updated'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE /api/v1/filters/:id' do
|
||||
let(:scopes) { 'write:filters' }
|
||||
let(:filter) { Fabricate(:custom_filter, account: user.account) }
|
||||
let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) }
|
||||
|
||||
before do
|
||||
delete "/api/v1/filters/#{keyword.id}", headers: headers
|
||||
end
|
||||
|
||||
it 'removes the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect { keyword.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
end
|
33
spec/requests/api/v1/polls/votes_spec.rb
Normal file
33
spec/requests/api/v1/polls/votes_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'API V1 Polls Votes' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'write:statuses' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'POST /api/v1/polls/:poll_id/votes' do
|
||||
let(:poll) { Fabricate(:poll) }
|
||||
|
||||
before do
|
||||
post "/api/v1/polls/#{poll.id}/votes", params: { choices: %w(1) }, headers: headers
|
||||
end
|
||||
|
||||
it 'creates a vote', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
|
||||
expect(vote).to_not be_nil
|
||||
expect(vote.choice).to eq 1
|
||||
|
||||
expect(poll.reload.cached_tallies).to eq [0, 1]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def vote
|
||||
poll.votes.where(account: user.account).first
|
||||
end
|
||||
end
|
||||
end
|
102
spec/requests/api/v1/push/subscriptions_spec.rb
Normal file
102
spec/requests/api/v1/push/subscriptions_spec.rb
Normal file
|
@ -0,0 +1,102 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'API V1 Push Subscriptions' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:create_payload) do
|
||||
{
|
||||
subscription: {
|
||||
endpoint: 'https://fcm.googleapis.com/fcm/send/fiuH06a27qE:APA91bHnSiGcLwdaxdyqVXNDR9w1NlztsHb6lyt5WDKOC_Z_Q8BlFxQoR8tWFSXUIDdkyw0EdvxTu63iqamSaqVSevW5LfoFwojws8XYDXv_NRRLH6vo2CdgiN4jgHv5VLt2A8ah6lUX',
|
||||
keys: {
|
||||
p256dh: 'BEm_a0bdPDhf0SOsrnB2-ategf1hHoCnpXgQsFj5JCkcoMrMt2WHoPfEYOYPzOIs9mZE8ZUaD7VA5vouy0kEkr8=',
|
||||
auth: 'eH_C8rq2raXqlcBVDa1gLg==',
|
||||
},
|
||||
},
|
||||
}.with_indifferent_access
|
||||
end
|
||||
let(:alerts_payload) do
|
||||
{
|
||||
data: {
|
||||
policy: 'all',
|
||||
|
||||
alerts: {
|
||||
follow: true,
|
||||
follow_request: true,
|
||||
favourite: false,
|
||||
reblog: true,
|
||||
mention: false,
|
||||
poll: true,
|
||||
status: false,
|
||||
},
|
||||
},
|
||||
}.with_indifferent_access
|
||||
end
|
||||
let(:scopes) { 'push' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'POST /api/v1/push/subscription' do
|
||||
before do
|
||||
post '/api/v1/push/subscription', params: create_payload, headers: headers
|
||||
end
|
||||
|
||||
it 'saves push subscriptions' do
|
||||
push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint])
|
||||
|
||||
expect(push_subscription.endpoint).to eq(create_payload[:subscription][:endpoint])
|
||||
expect(push_subscription.key_p256dh).to eq(create_payload[:subscription][:keys][:p256dh])
|
||||
expect(push_subscription.key_auth).to eq(create_payload[:subscription][:keys][:auth])
|
||||
expect(push_subscription.user_id).to eq user.id
|
||||
expect(push_subscription.access_token_id).to eq token.id
|
||||
end
|
||||
|
||||
it 'replaces old subscription on repeat calls' do
|
||||
post '/api/v1/push/subscription', params: create_payload, headers: headers
|
||||
|
||||
expect(Web::PushSubscription.where(endpoint: create_payload[:subscription][:endpoint]).count).to eq 1
|
||||
end
|
||||
|
||||
it 'returns the expected JSON' do
|
||||
expect(body_as_json.with_indifferent_access)
|
||||
.to include(
|
||||
{ endpoint: create_payload[:subscription][:endpoint], alerts: {}, policy: 'all' }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT /api/v1/push/subscription' do
|
||||
before do
|
||||
post '/api/v1/push/subscription', params: create_payload, headers: headers
|
||||
put '/api/v1/push/subscription', params: alerts_payload, headers: headers
|
||||
end
|
||||
|
||||
it 'changes alert settings' do
|
||||
push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint])
|
||||
|
||||
expect(push_subscription.data['policy']).to eq(alerts_payload[:data][:policy])
|
||||
|
||||
%w(follow follow_request favourite reblog mention poll status).each do |type|
|
||||
expect(push_subscription.data['alerts'][type]).to eq(alerts_payload[:data][:alerts][type.to_sym].to_s)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the expected JSON' do
|
||||
expect(body_as_json.with_indifferent_access)
|
||||
.to include(
|
||||
{ endpoint: create_payload[:subscription][:endpoint], alerts: alerts_payload[:data][:alerts], policy: alerts_payload[:data][:policy] }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE /api/v1/push/subscription' do
|
||||
before do
|
||||
post '/api/v1/push/subscription', params: create_payload, headers: headers
|
||||
delete '/api/v1/push/subscription', headers: headers
|
||||
end
|
||||
|
||||
it 'removes the subscription' do
|
||||
expect(Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint])).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
62
spec/requests/api/v1/streaming_spec.rb
Normal file
62
spec/requests/api/v1/streaming_spec.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'API V1 Streaming' do
|
||||
around do |example|
|
||||
before = Rails.configuration.x.streaming_api_base_url
|
||||
Rails.configuration.x.streaming_api_base_url = "wss://#{Rails.configuration.x.web_domain}"
|
||||
example.run
|
||||
Rails.configuration.x.streaming_api_base_url = before
|
||||
end
|
||||
|
||||
let(:headers) { { 'Host' => Rails.configuration.x.web_domain } }
|
||||
|
||||
context 'with streaming api on same host' do
|
||||
describe 'GET /api/v1/streaming' do
|
||||
it 'raises ActiveRecord::RecordNotFound' do
|
||||
get '/api/v1/streaming', headers: headers
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with streaming api on different host' do
|
||||
before do
|
||||
Rails.configuration.x.streaming_api_base_url = "wss://streaming-#{Rails.configuration.x.web_domain}"
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/streaming' do
|
||||
it 'redirects to streaming host' do
|
||||
get '/api/v1/streaming', headers: headers, params: { access_token: 'deadbeef', stream: 'public' }
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(301)
|
||||
|
||||
expect(redirect_to_uri)
|
||||
.to have_attributes(
|
||||
fragment: request_uri.fragment,
|
||||
host: eq(streaming_host),
|
||||
path: request_uri.path,
|
||||
query: request_uri.query,
|
||||
scheme: request_uri.scheme
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def request_uri
|
||||
URI.parse(request.url)
|
||||
end
|
||||
|
||||
def redirect_to_uri
|
||||
URI.parse(response.location)
|
||||
end
|
||||
|
||||
def streaming_host
|
||||
URI.parse(Rails.configuration.x.streaming_api_base_url).host
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue