Specs for API push controller, with refactor (#2926)

* Coverage for api push controller

* Refactor the api/push controller
pull/2931/head
Matt Jankowski 2017-05-08 18:44:30 -04:00 committed by Eugen Rochko
parent fed585e3f4
commit 04166c4a35
2 changed files with 100 additions and 25 deletions

View File

@ -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

View File

@ -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