application_controller_spec.rb 7.6 KB

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