mirror of https://github.com/tootsuite/mastodon
Specs for API push controller, with refactor (#2926)
* Coverage for api push controller * Refactor the api/push controllerpull/2931/head
parent
fed585e3f4
commit
04166c4a35
|
@ -2,36 +2,66 @@
|
||||||
|
|
||||||
class Api::PushController < ApiController
|
class Api::PushController < ApiController
|
||||||
def update
|
def update
|
||||||
mode = params['hub.mode']
|
response, status = process_push_request
|
||||||
topic = params['hub.topic']
|
|
||||||
callback = params['hub.callback']
|
|
||||||
lease_seconds = params['hub.lease_seconds']
|
|
||||||
secret = params['hub.secret']
|
|
||||||
|
|
||||||
case mode
|
|
||||||
when 'subscribe'
|
|
||||||
response, status = Pubsubhubbub::SubscribeService.new.call(topic_to_account(topic), callback, secret, lease_seconds)
|
|
||||||
when 'unsubscribe'
|
|
||||||
response, status = Pubsubhubbub::UnsubscribeService.new.call(topic_to_account(topic), callback)
|
|
||||||
else
|
|
||||||
response = "Unknown mode: #{mode}"
|
|
||||||
status = 422
|
|
||||||
end
|
|
||||||
|
|
||||||
render plain: response, status: status
|
render plain: response, status: status
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def topic_to_account(topic_url)
|
def process_push_request
|
||||||
return if topic_url.blank?
|
case hub_mode
|
||||||
|
when 'subscribe'
|
||||||
|
Pubsubhubbub::SubscribeService.new.call(account_from_topic, hub_callback, hub_secret, hub_lease_seconds)
|
||||||
|
when 'unsubscribe'
|
||||||
|
Pubsubhubbub::UnsubscribeService.new.call(account_from_topic, hub_callback)
|
||||||
|
else
|
||||||
|
["Unknown mode: #{hub_mode}", 422]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
uri = Addressable::URI.parse(topic_url).normalize
|
def hub_mode
|
||||||
params = Rails.application.routes.recognize_path(uri.path)
|
params['hub.mode']
|
||||||
domain = uri.host + (uri.port ? ":#{uri.port}" : '')
|
end
|
||||||
|
|
||||||
return unless TagManager.instance.web_domain?(domain) && params[:controller] == 'accounts' && params[:action] == 'show' && params[:format] == 'atom'
|
def hub_topic
|
||||||
|
params['hub.topic']
|
||||||
|
end
|
||||||
|
|
||||||
Account.find_local(params[:username])
|
def hub_callback
|
||||||
|
params['hub.callback']
|
||||||
|
end
|
||||||
|
|
||||||
|
def hub_lease_seconds
|
||||||
|
params['hub.lease_seconds']
|
||||||
|
end
|
||||||
|
|
||||||
|
def hub_secret
|
||||||
|
params['hub.secret']
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_from_topic
|
||||||
|
if hub_topic.present? && local_domain? && account_feed_path?
|
||||||
|
Account.find_local(hub_topic_params[:username])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def hub_topic_params
|
||||||
|
@_hub_topic_params ||= Rails.application.routes.recognize_path(hub_topic_uri.path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def hub_topic_uri
|
||||||
|
@_hub_topic_uri ||= Addressable::URI.parse(hub_topic).normalize
|
||||||
|
end
|
||||||
|
|
||||||
|
def local_domain?
|
||||||
|
TagManager.instance.web_domain?(hub_topic_domain)
|
||||||
|
end
|
||||||
|
|
||||||
|
def hub_topic_domain
|
||||||
|
hub_topic_uri.host + (hub_topic_uri.port ? ":#{hub_topic_uri.port}" : '')
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_feed_path?
|
||||||
|
hub_topic_params[:controller] == 'accounts' && hub_topic_params[:action] == 'show' && hub_topic_params[:format] == 'atom'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,11 +3,56 @@ require 'rails_helper'
|
||||||
RSpec.describe Api::PushController, type: :controller do
|
RSpec.describe Api::PushController, type: :controller do
|
||||||
describe 'POST #update' do
|
describe 'POST #update' do
|
||||||
context 'with hub.mode=subscribe' do
|
context 'with hub.mode=subscribe' do
|
||||||
pending
|
it 'creates a subscription' do
|
||||||
|
service = double(call: ['', 202])
|
||||||
|
allow(Pubsubhubbub::SubscribeService).to receive(:new).and_return(service)
|
||||||
|
account = Fabricate(:account)
|
||||||
|
account_topic_url = "https://#{Rails.configuration.x.local_domain}/users/#{account.username}.atom"
|
||||||
|
post :update, params: {
|
||||||
|
'hub.mode' => 'subscribe',
|
||||||
|
'hub.topic' => account_topic_url,
|
||||||
|
'hub.callback' => 'https://callback.host/api',
|
||||||
|
'hub.lease_seconds' => '3600',
|
||||||
|
'hub.secret' => 'as1234df',
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(service).to have_received(:call).with(
|
||||||
|
account,
|
||||||
|
'https://callback.host/api',
|
||||||
|
'as1234df',
|
||||||
|
'3600',
|
||||||
|
)
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with hub.mode=unsubscribe' do
|
context 'with hub.mode=unsubscribe' do
|
||||||
pending
|
it 'unsubscribes the account' do
|
||||||
|
service = double(call: ['', 202])
|
||||||
|
allow(Pubsubhubbub::UnsubscribeService).to receive(:new).and_return(service)
|
||||||
|
account = Fabricate(:account)
|
||||||
|
account_topic_url = "https://#{Rails.configuration.x.local_domain}/users/#{account.username}.atom"
|
||||||
|
post :update, params: {
|
||||||
|
'hub.mode' => 'unsubscribe',
|
||||||
|
'hub.topic' => account_topic_url,
|
||||||
|
'hub.callback' => 'https://callback.host/api',
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(service).to have_received(:call).with(
|
||||||
|
account,
|
||||||
|
'https://callback.host/api',
|
||||||
|
)
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with unknown mode' do
|
||||||
|
it 'returns an unknown mode error' do
|
||||||
|
post :update, params: { 'hub.mode' => 'fake' }
|
||||||
|
|
||||||
|
expect(response).to have_http_status(422)
|
||||||
|
expect(response.body).to match(/Unknown mode/)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue