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.

372 lines
10 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 Rails.env.production? is not 'true'" do
  40. routes.draw { get 'success' => 'anonymous#success' }
  41. allow(Rails.env).to receive(:production?).and_return(false)
  42. get 'success'
  43. expect(response).to have_http_status(200)
  44. end
  45. it "forces ssl if Rails.env.production? is 'true'" do
  46. routes.draw { get 'success' => 'anonymous#success' }
  47. allow(Rails.env).to receive(:production?).and_return(true)
  48. get 'success'
  49. expect(response).to redirect_to('https://test.host/success')
  50. end
  51. describe 'helper_method :current_account' do
  52. it 'returns nil if not signed in' do
  53. expect(controller.view_context.current_account).to be_nil
  54. end
  55. it 'returns account if signed in' do
  56. account = Fabricate(:account)
  57. sign_in(Fabricate(:user, account: account))
  58. expect(controller.view_context.current_account).to eq account
  59. end
  60. end
  61. describe 'helper_method :single_user_mode?' do
  62. it 'returns false if it is in single_user_mode but there is no account' do
  63. allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true)
  64. expect(controller.view_context.single_user_mode?).to eq false
  65. end
  66. it 'returns false if there is an account but it is not in single_user_mode' do
  67. allow(Rails.configuration.x).to receive(:single_user_mode).and_return(false)
  68. Fabricate(:account)
  69. expect(controller.view_context.single_user_mode?).to eq false
  70. end
  71. it 'returns true if it is in single_user_mode and there is an account' do
  72. allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true)
  73. Fabricate(:account)
  74. expect(controller.view_context.single_user_mode?).to eq true
  75. end
  76. end
  77. describe 'helper_method :current_flavour' do
  78. it 'returns "glitch" when theme wasn\'t changed in admin settings' do
  79. allow(Setting).to receive(:default_settings).and_return({'skin' => 'default'})
  80. allow(Setting).to receive(:default_settings).and_return({'flavour' => 'glitch'})
  81. expect(controller.view_context.current_flavour).to eq 'glitch'
  82. end
  83. it 'returns instances\'s flavour when user is not signed in' do
  84. allow(Setting).to receive(:[]).with('skin').and_return 'default'
  85. allow(Setting).to receive(:[]).with('flavour').and_return 'vanilla'
  86. expect(controller.view_context.current_flavour).to eq 'vanilla'
  87. end
  88. it 'returns instances\'s default flavour when user didn\'t set theme' do
  89. current_user = Fabricate(:user)
  90. sign_in current_user
  91. allow(Setting).to receive(:[]).with('skin').and_return 'default'
  92. allow(Setting).to receive(:[]).with('flavour').and_return 'vanilla'
  93. expect(controller.view_context.current_flavour).to eq 'vanilla'
  94. end
  95. it 'returns user\'s flavour when it is set' do
  96. current_user = Fabricate(:user)
  97. current_user.settings['flavour'] = 'glitch'
  98. sign_in current_user
  99. allow(Setting).to receive(:[]).with('skin').and_return 'default'
  100. allow(Setting).to receive(:[]).with('flavour').and_return 'vanilla'
  101. expect(controller.view_context.current_flavour).to eq 'glitch'
  102. end
  103. end
  104. context 'ActionController::RoutingError' do
  105. subject do
  106. routes.draw { get 'routing_error' => 'anonymous#routing_error' }
  107. get 'routing_error'
  108. end
  109. include_examples 'respond_with_error', 404
  110. end
  111. context 'ActiveRecord::RecordNotFound' do
  112. subject do
  113. routes.draw { get 'record_not_found' => 'anonymous#record_not_found' }
  114. get 'record_not_found'
  115. end
  116. include_examples 'respond_with_error', 404
  117. end
  118. context 'ActionController::InvalidAuthenticityToken' do
  119. subject do
  120. routes.draw { get 'invalid_authenticity_token' => 'anonymous#invalid_authenticity_token' }
  121. get 'invalid_authenticity_token'
  122. end
  123. include_examples 'respond_with_error', 422
  124. end
  125. describe 'before_action :store_current_location' do
  126. it 'stores location for user if it is not devise controller' do
  127. routes.draw { get 'success' => 'anonymous#success' }
  128. get 'success'
  129. expect(controller.stored_location_for(:user)).to eq '/success'
  130. end
  131. context do
  132. controller Devise::SessionsController do
  133. end
  134. it 'does not store location for user if it is devise controller' do
  135. @request.env["devise.mapping"] = Devise.mappings[:user]
  136. get 'create'
  137. expect(controller.stored_location_for(:user)).to be_nil
  138. end
  139. end
  140. end
  141. describe 'before_action :check_suspension' do
  142. before do
  143. routes.draw { get 'success' => 'anonymous#success' }
  144. end
  145. it 'does nothing if not signed in' do
  146. get 'success'
  147. expect(response).to have_http_status(200)
  148. end
  149. it 'does nothing if user who signed in is not suspended' do
  150. sign_in(Fabricate(:user, account: Fabricate(:account, suspended: false)))
  151. get 'success'
  152. expect(response).to have_http_status(200)
  153. end
  154. it 'returns http 403 if user who signed in is suspended' do
  155. sign_in(Fabricate(:user, account: Fabricate(:account, suspended: true)))
  156. get 'success'
  157. expect(response).to have_http_status(403)
  158. end
  159. end
  160. describe 'raise_not_found' do
  161. it 'raises error' do
  162. controller.params[:unmatched_route] = 'unmatched'
  163. expect { controller.raise_not_found }.to raise_error(ActionController::RoutingError, 'No route matches unmatched')
  164. end
  165. end
  166. describe 'require_admin!' do
  167. controller do
  168. before_action :require_admin!
  169. def sucesss
  170. head 200
  171. end
  172. end
  173. before do
  174. routes.draw { get 'sucesss' => 'anonymous#sucesss' }
  175. end
  176. it 'returns a 403 if current user is not admin' do
  177. sign_in(Fabricate(:user, admin: false))
  178. get 'sucesss'
  179. expect(response).to have_http_status(403)
  180. end
  181. it 'returns a 403 if current user is only a moderator' do
  182. sign_in(Fabricate(:user, moderator: true))
  183. get 'sucesss'
  184. expect(response).to have_http_status(403)
  185. end
  186. it 'does nothing if current user is admin' do
  187. sign_in(Fabricate(:user, admin: true))
  188. get 'sucesss'
  189. expect(response).to have_http_status(200)
  190. end
  191. end
  192. describe 'require_staff!' do
  193. controller do
  194. before_action :require_staff!
  195. def sucesss
  196. head 200
  197. end
  198. end
  199. before do
  200. routes.draw { get 'sucesss' => 'anonymous#sucesss' }
  201. end
  202. it 'returns a 403 if current user is not admin or moderator' do
  203. sign_in(Fabricate(:user, admin: false, moderator: false))
  204. get 'sucesss'
  205. expect(response).to have_http_status(403)
  206. end
  207. it 'does nothing if current user is moderator' do
  208. sign_in(Fabricate(:user, moderator: true))
  209. get 'sucesss'
  210. expect(response).to have_http_status(200)
  211. end
  212. it 'does nothing if current user is admin' do
  213. sign_in(Fabricate(:user, admin: true))
  214. get 'sucesss'
  215. expect(response).to have_http_status(200)
  216. end
  217. end
  218. describe 'forbidden' do
  219. controller do
  220. def route_forbidden
  221. forbidden
  222. end
  223. end
  224. subject do
  225. routes.draw { get 'route_forbidden' => 'anonymous#route_forbidden' }
  226. get 'route_forbidden'
  227. end
  228. include_examples 'respond_with_error', 403
  229. end
  230. describe 'not_found' do
  231. controller do
  232. def route_not_found
  233. not_found
  234. end
  235. end
  236. subject do
  237. routes.draw { get 'route_not_found' => 'anonymous#route_not_found' }
  238. get 'route_not_found'
  239. end
  240. include_examples 'respond_with_error', 404
  241. end
  242. describe 'gone' do
  243. controller do
  244. def route_gone
  245. gone
  246. end
  247. end
  248. subject do
  249. routes.draw { get 'route_gone' => 'anonymous#route_gone' }
  250. get 'route_gone'
  251. end
  252. include_examples 'respond_with_error', 410
  253. end
  254. describe 'unprocessable_entity' do
  255. controller do
  256. def route_unprocessable_entity
  257. unprocessable_entity
  258. end
  259. end
  260. subject do
  261. routes.draw { get 'route_unprocessable_entity' => 'anonymous#route_unprocessable_entity' }
  262. get 'route_unprocessable_entity'
  263. end
  264. include_examples 'respond_with_error', 422
  265. end
  266. describe 'cache_collection' do
  267. class C < ApplicationController
  268. public :cache_collection
  269. end
  270. shared_examples 'receives :with_includes' do |fabricator, klass|
  271. it 'uses raw if it is not an ActiveRecord::Relation' do
  272. record = Fabricate(fabricator)
  273. expect(C.new.cache_collection([record], klass)).to eq [record]
  274. end
  275. end
  276. shared_examples 'cacheable' do |fabricator, klass|
  277. include_examples 'receives :with_includes', fabricator, klass
  278. it 'calls cache_ids of raw if it is an ActiveRecord::Relation' do
  279. record = Fabricate(fabricator)
  280. relation = klass.none
  281. allow(relation).to receive(:cache_ids).and_return([record])
  282. expect(C.new.cache_collection(relation, klass)).to eq [record]
  283. end
  284. end
  285. it 'returns raw unless class responds to :with_includes' do
  286. raw = Object.new
  287. expect(C.new.cache_collection(raw, Object)).to eq raw
  288. end
  289. context 'Notification' do
  290. include_examples 'cacheable', :notification, Notification
  291. end
  292. context 'Status' do
  293. include_examples 'cacheable', :status, Status
  294. end
  295. context 'StreamEntry' do
  296. include_examples 'receives :with_includes', :stream_entry, StreamEntry
  297. end
  298. end
  299. end