Specs for API push controller, with refactor (#2926)
* Coverage for api push controller * Refactor the api/push controller
This commit is contained in:
		
							parent
							
								
									fed585e3f4
								
							
						
					
					
						commit
						04166c4a35
					
				
					 2 changed files with 100 additions and 25 deletions
				
			
		|  | @ -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'] | ||||
| 
 | ||||
|     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 | ||||
| 
 | ||||
|     response, status = process_push_request | ||||
|     render plain: response, status: status | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def topic_to_account(topic_url) | ||||
|     return if topic_url.blank? | ||||
|   def process_push_request | ||||
|     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 | ||||
|     params = Rails.application.routes.recognize_path(uri.path) | ||||
|     domain = uri.host + (uri.port ? ":#{uri.port}" : '') | ||||
|   def hub_mode | ||||
|     params['hub.mode'] | ||||
|   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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue