application_controller_spec.rb 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. describe ApplicationController do
  4. controller do
  5. def success
  6. head 200
  7. end
  8. def routing_error
  9. raise ActionController::RoutingError, ''
  10. end
  11. def record_not_found
  12. raise ActiveRecord::RecordNotFound, ''
  13. end
  14. def invalid_authenticity_token
  15. raise ActionController::InvalidAuthenticityToken, ''
  16. end
  17. end
  18. shared_examples 'respond_with_error' do |code|
  19. it "returns http #{code} for http and renders template" do
  20. expect(subject).to render_template("errors/#{code}", layout: 'error')
  21. expect(response).to have_http_status(code)
  22. end
  23. end
  24. context 'with a forgery' do
  25. subject do
  26. ActionController::Base.allow_forgery_protection = true
  27. routes.draw { post 'success' => 'anonymous#success' }
  28. post 'success'
  29. end
  30. include_examples 'respond_with_error', 422
  31. end
  32. describe 'helper_method :current_account' do
  33. it 'returns nil if not signed in' do
  34. expect(controller.view_context.current_account).to be_nil
  35. end
  36. it 'returns account if signed in' do
  37. account = Fabricate(:account)
  38. sign_in(account.user)
  39. expect(controller.view_context.current_account).to eq account
  40. end
  41. end
  42. describe 'helper_method :single_user_mode?' do
  43. it 'returns false if it is in single_user_mode but there is no account' do
  44. allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true)
  45. expect(controller.view_context.single_user_mode?).to be false
  46. end
  47. it 'returns false if there is an account but it is not in single_user_mode' do
  48. allow(Rails.configuration.x).to receive(:single_user_mode).and_return(false)
  49. Fabricate(:account)
  50. expect(controller.view_context.single_user_mode?).to be false
  51. end
  52. it 'returns true if it is in single_user_mode and there is an account' do
  53. allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true)
  54. Fabricate(:account)
  55. expect(controller.view_context.single_user_mode?).to be true
  56. end
  57. end
  58. describe 'helper_method :current_theme' do
  59. it 'returns "default" when theme wasn\'t changed in admin settings' do
  60. allow(Setting).to receive(:default_settings).and_return({ 'theme' => 'default' })
  61. expect(controller.view_context.current_theme).to eq 'default'
  62. end
  63. it 'returns instances\'s theme when user is not signed in' do
  64. allow(Setting).to receive(:[]).with('theme').and_return 'contrast'
  65. expect(controller.view_context.current_theme).to eq 'contrast'
  66. end
  67. it 'returns instances\'s default theme when user didn\'t set theme' do
  68. current_user = Fabricate(:user)
  69. current_user.settings.update(theme: 'contrast', noindex: false)
  70. current_user.save
  71. sign_in current_user
  72. expect(controller.view_context.current_theme).to eq 'contrast'
  73. end
  74. it 'returns user\'s theme when it is set' do
  75. current_user = Fabricate(:user)
  76. current_user.settings.update(theme: 'mastodon-light')
  77. current_user.save
  78. sign_in current_user
  79. expect(controller.view_context.current_theme).to eq 'mastodon-light'
  80. end
  81. end
  82. context 'with ActionController::RoutingError' do
  83. subject do
  84. routes.draw { get 'routing_error' => 'anonymous#routing_error' }
  85. get 'routing_error'
  86. end
  87. include_examples 'respond_with_error', 404
  88. end
  89. context 'with ActiveRecord::RecordNotFound' do
  90. subject do
  91. routes.draw { get 'record_not_found' => 'anonymous#record_not_found' }
  92. get 'record_not_found'
  93. end
  94. include_examples 'respond_with_error', 404
  95. end
  96. context 'with ActionController::InvalidAuthenticityToken' do
  97. subject do
  98. routes.draw { get 'invalid_authenticity_token' => 'anonymous#invalid_authenticity_token' }
  99. get 'invalid_authenticity_token'
  100. end
  101. include_examples 'respond_with_error', 422
  102. end
  103. describe 'before_action :check_suspension' do
  104. before do
  105. routes.draw { get 'success' => 'anonymous#success' }
  106. end
  107. it 'does nothing if not signed in' do
  108. get 'success'
  109. expect(response).to have_http_status(200)
  110. end
  111. it 'does nothing if user who signed in is not suspended' do
  112. sign_in(Fabricate(:account, suspended: false).user)
  113. get 'success'
  114. expect(response).to have_http_status(200)
  115. end
  116. it 'redirects to account status page' do
  117. sign_in(Fabricate(:account, suspended: true).user)
  118. get 'success'
  119. expect(response).to redirect_to(edit_user_registration_path)
  120. end
  121. end
  122. describe 'raise_not_found' do
  123. it 'raises error' do
  124. controller.params[:unmatched_route] = 'unmatched'
  125. expect { controller.raise_not_found }.to raise_error(ActionController::RoutingError, 'No route matches unmatched')
  126. end
  127. end
  128. describe 'forbidden' do
  129. controller do
  130. def route_forbidden
  131. forbidden
  132. end
  133. end
  134. subject do
  135. routes.draw { get 'route_forbidden' => 'anonymous#route_forbidden' }
  136. get 'route_forbidden'
  137. end
  138. include_examples 'respond_with_error', 403
  139. end
  140. describe 'not_found' do
  141. controller do
  142. def route_not_found
  143. not_found
  144. end
  145. end
  146. subject do
  147. routes.draw { get 'route_not_found' => 'anonymous#route_not_found' }
  148. get 'route_not_found'
  149. end
  150. include_examples 'respond_with_error', 404
  151. end
  152. describe 'gone' do
  153. controller do
  154. def route_gone
  155. gone
  156. end
  157. end
  158. subject do
  159. routes.draw { get 'route_gone' => 'anonymous#route_gone' }
  160. get 'route_gone'
  161. end
  162. include_examples 'respond_with_error', 410
  163. end
  164. describe 'unprocessable_entity' do
  165. controller do
  166. def route_unprocessable_entity
  167. unprocessable_entity
  168. end
  169. end
  170. subject do
  171. routes.draw { get 'route_unprocessable_entity' => 'anonymous#route_unprocessable_entity' }
  172. get 'route_unprocessable_entity'
  173. end
  174. include_examples 'respond_with_error', 422
  175. end
  176. describe 'cache_collection' do
  177. subject do
  178. Class.new(ApplicationController) do
  179. public :cache_collection
  180. end
  181. end
  182. shared_examples 'receives :with_includes' do |fabricator, klass|
  183. it 'uses raw if it is not an ActiveRecord::Relation' do
  184. record = Fabricate(fabricator)
  185. expect(subject.new.cache_collection([record], klass)).to eq [record]
  186. end
  187. end
  188. shared_examples 'cacheable' do |fabricator, klass|
  189. include_examples 'receives :with_includes', fabricator, klass
  190. it 'calls cache_ids of raw if it is an ActiveRecord::Relation' do
  191. record = Fabricate(fabricator)
  192. relation = klass.none
  193. allow(relation).to receive(:cache_ids).and_return([record])
  194. expect(subject.new.cache_collection(relation, klass)).to eq [record]
  195. end
  196. end
  197. it 'returns raw unless class responds to :with_includes' do
  198. raw = Object.new
  199. expect(subject.new.cache_collection(raw, Object)).to eq raw
  200. end
  201. context 'with a Status' do
  202. include_examples 'cacheable', :status, Status
  203. end
  204. end
  205. end