commit: 04166c4a35c97f5540252617c7858bf20d315a7e
parent: fed585e3f42578f133da66497c1720f9d47833d1
Author: Matt Jankowski <mjankowski@thoughtbot.com>
Date: Mon, 8 May 2017 18:44:30 -0400
Specs for API push controller, with refactor (#2926)
* Coverage for api push controller
* Refactor the api/push controller
Diffstat:
2 files changed, 96 insertions(+), 21 deletions(-)
diff --git a/app/controllers/api/push_controller.rb b/app/controllers/api/push_controller.rb
@@ -2,36 +2,66 @@
class Api::PushController < ApiController
def update
- mode = params['hub.mode']
- topic = params['hub.topic']
- callback = params['hub.callback']
- lease_seconds = params['hub.lease_seconds']
- secret = params['hub.secret']
+ response, status = process_push_request
+ render plain: response, status: status
+ end
+
+ private
- case mode
+ def process_push_request
+ case hub_mode
when 'subscribe'
- response, status = Pubsubhubbub::SubscribeService.new.call(topic_to_account(topic), callback, secret, lease_seconds)
+ Pubsubhubbub::SubscribeService.new.call(account_from_topic, hub_callback, hub_secret, hub_lease_seconds)
when 'unsubscribe'
- response, status = Pubsubhubbub::UnsubscribeService.new.call(topic_to_account(topic), callback)
+ Pubsubhubbub::UnsubscribeService.new.call(account_from_topic, hub_callback)
else
- response = "Unknown mode: #{mode}"
- status = 422
+ ["Unknown mode: #{hub_mode}", 422]
end
+ end
- render plain: response, status: status
+ def hub_mode
+ params['hub.mode']
end
- private
+ def hub_topic
+ params['hub.topic']
+ end
+
+ def hub_callback
+ params['hub.callback']
+ end
+
+ def hub_lease_seconds
+ params['hub.lease_seconds']
+ end
+
+ def hub_secret
+ params['hub.secret']
+ end
- def topic_to_account(topic_url)
- return if topic_url.blank?
+ def account_from_topic
+ if hub_topic.present? && local_domain? && account_feed_path?
+ Account.find_local(hub_topic_params[:username])
+ end
+ end
- uri = Addressable::URI.parse(topic_url).normalize
- params = Rails.application.routes.recognize_path(uri.path)
- domain = uri.host + (uri.port ? ":#{uri.port}" : '')
+ def hub_topic_params
+ @_hub_topic_params ||= Rails.application.routes.recognize_path(hub_topic_uri.path)
+ end
- return unless TagManager.instance.web_domain?(domain) && params[:controller] == 'accounts' && params[:action] == 'show' && params[:format] == 'atom'
+ 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
- Account.find_local(params[:username])
+ def account_feed_path?
+ hub_topic_params[:controller] == 'accounts' && hub_topic_params[:action] == 'show' && hub_topic_params[:format] == 'atom'
end
end
diff --git a/spec/controllers/api/push_controller_spec.rb b/spec/controllers/api/push_controller_spec.rb
@@ -3,11 +3,56 @@ require 'rails_helper'
RSpec.describe Api::PushController, type: :controller do
describe 'POST #update' 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
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