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.

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