You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

301 lines
8.0 KiB

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