rack_attack_spec.rb 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. require 'rails_helper'
  2. describe Rack::Attack do
  3. include Rack::Test::Methods
  4. def app
  5. Rails.application
  6. end
  7. shared_examples 'throttled endpoint' do
  8. context 'when the number of requests is lower than the limit' do
  9. it 'does not change the request status' do
  10. limit.times do
  11. request.call
  12. expect(last_response.status).to_not eq(429)
  13. end
  14. end
  15. end
  16. context 'when the number of requests is higher than the limit' do
  17. it 'returns http too many requests' do
  18. (limit * 2).times do |i|
  19. request.call
  20. expect(last_response.status).to eq(429) if i > limit
  21. end
  22. end
  23. end
  24. end
  25. let(:remote_ip) { '1.2.3.5' }
  26. describe 'throttle excessive sign-up requests by IP address' do
  27. context 'through the website' do
  28. let(:limit) { 25 }
  29. let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } }
  30. context 'for exact path' do
  31. let(:path) { '/auth' }
  32. it_behaves_like 'throttled endpoint'
  33. end
  34. context 'for path with format' do
  35. let(:path) { '/auth.html' }
  36. it_behaves_like 'throttled endpoint'
  37. end
  38. end
  39. context 'through the API' do
  40. let(:limit) { 5 }
  41. let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } }
  42. context 'for exact path' do
  43. let(:path) { '/api/v1/accounts' }
  44. it_behaves_like 'throttled endpoint'
  45. end
  46. context 'for path with format' do
  47. let(:path) { '/api/v1/accounts.json' }
  48. it 'returns http not found' do
  49. request.call
  50. expect(last_response.status).to eq(404)
  51. end
  52. end
  53. end
  54. end
  55. describe 'throttle excessive sign-in requests by IP address' do
  56. let(:limit) { 25 }
  57. let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } }
  58. context 'for exact path' do
  59. let(:path) { '/auth/sign_in' }
  60. it_behaves_like 'throttled endpoint'
  61. end
  62. context 'for path with format' do
  63. let(:path) { '/auth/sign_in.html' }
  64. it_behaves_like 'throttled endpoint'
  65. end
  66. end
  67. end