Services specs for subscribe and unsubscribe (#2928)
* Add specs for unsubscribe service * Fix non existent methods in unsubscribe service * Clean up status handling in subscribe service
This commit is contained in:
		
							parent
							
								
									04166c4a35
								
							
						
					
					
						commit
						5bea42412e
					
				
					 4 changed files with 52 additions and 10 deletions
				
			
		|  | @ -8,28 +8,28 @@ class SubscribeService < BaseService | ||||||
|     response     = subscription.subscribe |     response     = subscription.subscribe | ||||||
| 
 | 
 | ||||||
|     if response_failed_permanently?(response) |     if response_failed_permanently?(response) | ||||||
|       # An error in the 4xx range (except for 429, which is rate limiting) |       # We're not allowed to subscribe. Fail and move on. | ||||||
|       # means we're not allowed to subscribe. Fail and move on |  | ||||||
|       account.secret = '' |       account.secret = '' | ||||||
|       account.save! |       account.save! | ||||||
|     elsif response_successful?(response) |     elsif response_successful?(response) | ||||||
|       # Anything in the 2xx range means the subscription will be confirmed |       # The subscription will be confirmed asynchronously. | ||||||
|       # asynchronously, we've done what we needed to do |  | ||||||
|       account.save! |       account.save! | ||||||
|     else |     else | ||||||
|       # What's left is the 5xx range and 429, which means we need to retry |       # The response was either a 429 rate limit, or a 5xx error. | ||||||
|       # at a later time. Fail loudly! |       # We need to retry at a later time. Fail loudly! | ||||||
|       raise "Subscription attempt failed for #{account.acct} (#{account.hub_url}): HTTP #{response.code}" |       raise "Subscription attempt failed for #{account.acct} (#{account.hub_url}): HTTP #{response.code}" | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   private |   private | ||||||
| 
 | 
 | ||||||
|  |   # Any response in the 3xx or 4xx range, except for 429 (rate limit) | ||||||
|   def response_failed_permanently?(response) |   def response_failed_permanently?(response) | ||||||
|     response.code > 299 && response.code < 500 && response.code != 429 |     (response.status.redirect? || response.status.client_error?) && !response.status.too_many_requests? | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   # Any response in the 2xx range | ||||||
|   def response_successful?(response) |   def response_successful?(response) | ||||||
|     response.code > 199 && response.code < 300 |     response.status.success? | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -5,8 +5,8 @@ class UnsubscribeService < BaseService | ||||||
|     subscription = account.subscription(api_subscription_url(account.id)) |     subscription = account.subscription(api_subscription_url(account.id)) | ||||||
|     response = subscription.unsubscribe |     response = subscription.unsubscribe | ||||||
| 
 | 
 | ||||||
|     unless response.successful? |     unless response.status.success? | ||||||
|       Rails.logger.debug "PuSH unsubscribe for #{account.acct} failed: #{response.message}" |       Rails.logger.debug "PuSH unsubscribe for #{account.acct} failed: #{response.status}" | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     account.secret = '' |     account.secret = '' | ||||||
|  |  | ||||||
|  | @ -35,4 +35,9 @@ RSpec.describe SubscribeService do | ||||||
|     stub_request(:post, 'http://hub.example.com/').to_return(status: 503) |     stub_request(:post, 'http://hub.example.com/').to_return(status: 503) | ||||||
|     expect { subject.call(account) }.to raise_error(/Subscription attempt failed/) |     expect { subject.call(account) }.to raise_error(/Subscription attempt failed/) | ||||||
|   end |   end | ||||||
|  | 
 | ||||||
|  |   it 'fails loudly if rate limited' do | ||||||
|  |     stub_request(:post, 'http://hub.example.com/').to_return(status: 429) | ||||||
|  |     expect { subject.call(account) }.to raise_error(/Subscription attempt failed/) | ||||||
|  |   end | ||||||
| end | end | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								spec/services/unsubscribe_service_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								spec/services/unsubscribe_service_spec.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | require 'rails_helper' | ||||||
|  | 
 | ||||||
|  | RSpec.describe UnsubscribeService do | ||||||
|  |   let(:account) { Fabricate(:account, username: 'bob', domain: 'example.com', hub_url: 'http://hub.example.com') } | ||||||
|  |   subject { UnsubscribeService.new } | ||||||
|  | 
 | ||||||
|  |   it 'removes the secret and resets expiration on account' do | ||||||
|  |     stub_request(:post, 'http://hub.example.com/').to_return(status: 204) | ||||||
|  |     subject.call(account) | ||||||
|  |     account.reload | ||||||
|  | 
 | ||||||
|  |     expect(account.secret).to be_blank | ||||||
|  |     expect(account.subscription_expires_at).to be_blank | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   it 'logs error on subscription failure' do | ||||||
|  |     logger = stub_logger | ||||||
|  |     stub_request(:post, 'http://hub.example.com/').to_return(status: 404) | ||||||
|  |     subject.call(account) | ||||||
|  | 
 | ||||||
|  |     expect(logger).to have_received(:debug).with(/unsubscribe for bob@example.com failed/) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   it 'logs error on connection failure' do | ||||||
|  |     logger = stub_logger | ||||||
|  |     stub_request(:post, 'http://hub.example.com/').to_raise(HTTP::Error) | ||||||
|  |     subject.call(account) | ||||||
|  | 
 | ||||||
|  |     expect(logger).to have_received(:debug).with(/PuSH subscription request for bob@example.com could not be made due to HTTP or SSL error/) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def stub_logger | ||||||
|  |     double(debug: nil).tap do |logger| | ||||||
|  |       allow(Rails).to receive(:logger).and_return(logger) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
		Loading…
	
		Reference in a new issue