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.

603 lines
20 KiB

  1. require 'rails_helper'
  2. RSpec.describe AccountsController, type: :controller do
  3. render_views
  4. let(:account) { Fabricate(:user).account }
  5. shared_examples 'cachable response' do
  6. it 'does not set cookies' do
  7. expect(response.cookies).to be_empty
  8. expect(response.headers['Set-Cookies']).to be nil
  9. end
  10. it 'does not set sessions' do
  11. expect(session).to be_empty
  12. end
  13. it 'returns public Cache-Control header' do
  14. expect(response.headers['Cache-Control']).to include 'public'
  15. end
  16. end
  17. describe 'GET #show' do
  18. let(:format) { 'html' }
  19. let!(:status) { Fabricate(:status, account: account) }
  20. let!(:status_reply) { Fabricate(:status, account: account, thread: Fabricate(:status)) }
  21. let!(:status_self_reply) { Fabricate(:status, account: account, thread: status) }
  22. let!(:status_media) { Fabricate(:status, account: account) }
  23. let!(:status_pinned) { Fabricate(:status, account: account) }
  24. let!(:status_private) { Fabricate(:status, account: account, visibility: :private) }
  25. let!(:status_direct) { Fabricate(:status, account: account, visibility: :direct) }
  26. let!(:status_reblog) { Fabricate(:status, account: account, reblog: Fabricate(:status)) }
  27. before do
  28. status_media.media_attachments << Fabricate(:media_attachment, account: account, type: :image)
  29. account.pinned_statuses << status_pinned
  30. end
  31. shared_examples 'preliminary checks' do
  32. context 'when account is not approved' do
  33. before do
  34. account.user.update(approved: false)
  35. end
  36. it 'returns http not found' do
  37. get :show, params: { username: account.username, format: format }
  38. expect(response).to have_http_status(404)
  39. end
  40. end
  41. context 'when account is suspended' do
  42. before do
  43. account.suspend!
  44. end
  45. it 'returns http gone' do
  46. get :show, params: { username: account.username, format: format }
  47. expect(response).to have_http_status(410)
  48. end
  49. end
  50. end
  51. context 'as HTML' do
  52. let(:format) { 'html' }
  53. it_behaves_like 'preliminary checks'
  54. shared_examples 'common response characteristics' do
  55. it 'returns http success' do
  56. expect(response).to have_http_status(200)
  57. end
  58. it 'returns Link header' do
  59. expect(response.headers['Link'].to_s).to include ActivityPub::TagManager.instance.uri_for(account)
  60. end
  61. it 'renders show template' do
  62. expect(response).to render_template(:show)
  63. end
  64. end
  65. context do
  66. before do
  67. get :show, params: { username: account.username, format: format }
  68. end
  69. it_behaves_like 'common response characteristics'
  70. it 'renders public status' do
  71. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status))
  72. end
  73. it 'renders self-reply' do
  74. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  75. end
  76. it 'renders status with media' do
  77. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_media))
  78. end
  79. it 'renders reblog' do
  80. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  81. end
  82. it 'renders pinned status' do
  83. expect(response.body).to include(I18n.t('stream_entries.pinned'))
  84. end
  85. it 'does not render private status' do
  86. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  87. end
  88. it 'does not render direct status' do
  89. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  90. end
  91. it 'does not render reply to someone else' do
  92. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  93. end
  94. end
  95. context 'when signed-in' do
  96. let(:user) { Fabricate(:user) }
  97. before do
  98. sign_in(user)
  99. end
  100. context 'when user follows account' do
  101. before do
  102. user.account.follow!(account)
  103. get :show, params: { username: account.username, format: format }
  104. end
  105. it 'does not render private status' do
  106. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  107. end
  108. end
  109. context 'when user is blocked' do
  110. before do
  111. account.block!(user.account)
  112. get :show, params: { username: account.username, format: format }
  113. end
  114. it 'renders unavailable message' do
  115. expect(response.body).to include(I18n.t('accounts.unavailable'))
  116. end
  117. it 'does not render public status' do
  118. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status))
  119. end
  120. it 'does not render self-reply' do
  121. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  122. end
  123. it 'does not render status with media' do
  124. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_media))
  125. end
  126. it 'does not render reblog' do
  127. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  128. end
  129. it 'does not render pinned status' do
  130. expect(response.body).to_not include(I18n.t('stream_entries.pinned'))
  131. end
  132. it 'does not render private status' do
  133. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  134. end
  135. it 'does not render direct status' do
  136. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  137. end
  138. it 'does not render reply to someone else' do
  139. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  140. end
  141. end
  142. end
  143. context 'with replies' do
  144. before do
  145. allow(controller).to receive(:replies_requested?).and_return(true)
  146. get :show, params: { username: account.username, format: format }
  147. end
  148. it_behaves_like 'common response characteristics'
  149. it 'renders public status' do
  150. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status))
  151. end
  152. it 'renders self-reply' do
  153. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  154. end
  155. it 'renders status with media' do
  156. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_media))
  157. end
  158. it 'renders reblog' do
  159. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  160. end
  161. it 'does not render pinned status' do
  162. expect(response.body).to_not include(I18n.t('stream_entries.pinned'))
  163. end
  164. it 'does not render private status' do
  165. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  166. end
  167. it 'does not render direct status' do
  168. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  169. end
  170. it 'renders reply to someone else' do
  171. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_reply))
  172. end
  173. end
  174. context 'with media' do
  175. before do
  176. allow(controller).to receive(:media_requested?).and_return(true)
  177. get :show, params: { username: account.username, format: format }
  178. end
  179. it_behaves_like 'common response characteristics'
  180. it 'does not render public status' do
  181. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status))
  182. end
  183. it 'does not render self-reply' do
  184. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  185. end
  186. it 'renders status with media' do
  187. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_media))
  188. end
  189. it 'does not render reblog' do
  190. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  191. end
  192. it 'does not render pinned status' do
  193. expect(response.body).to_not include(I18n.t('stream_entries.pinned'))
  194. end
  195. it 'does not render private status' do
  196. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  197. end
  198. it 'does not render direct status' do
  199. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  200. end
  201. it 'does not render reply to someone else' do
  202. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  203. end
  204. end
  205. context 'with tag' do
  206. let(:tag) { Fabricate(:tag) }
  207. let!(:status_tag) { Fabricate(:status, account: account) }
  208. before do
  209. allow(controller).to receive(:tag_requested?).and_return(true)
  210. status_tag.tags << tag
  211. get :show, params: { username: account.username, format: format, tag: tag.to_param }
  212. end
  213. it_behaves_like 'common response characteristics'
  214. it 'does not render public status' do
  215. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status))
  216. end
  217. it 'does not render self-reply' do
  218. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  219. end
  220. it 'does not render status with media' do
  221. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_media))
  222. end
  223. it 'does not render reblog' do
  224. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  225. end
  226. it 'does not render pinned status' do
  227. expect(response.body).to_not include(I18n.t('stream_entries.pinned'))
  228. end
  229. it 'does not render private status' do
  230. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  231. end
  232. it 'does not render direct status' do
  233. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  234. end
  235. it 'does not render reply to someone else' do
  236. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  237. end
  238. it 'renders status with tag' do
  239. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_tag))
  240. end
  241. end
  242. end
  243. context 'as JSON' do
  244. let(:authorized_fetch_mode) { false }
  245. let(:format) { 'json' }
  246. before do
  247. allow(controller).to receive(:authorized_fetch_mode?).and_return(authorized_fetch_mode)
  248. end
  249. it_behaves_like 'preliminary checks'
  250. context do
  251. before do
  252. get :show, params: { username: account.username, format: format }
  253. end
  254. it 'returns http success' do
  255. expect(response).to have_http_status(200)
  256. end
  257. it 'returns application/activity+json' do
  258. expect(response.content_type).to eq 'application/activity+json'
  259. end
  260. it_behaves_like 'cachable response'
  261. it 'renders account' do
  262. json = body_as_json
  263. expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
  264. end
  265. context 'in authorized fetch mode' do
  266. let(:authorized_fetch_mode) { true }
  267. it 'returns http unauthorized' do
  268. expect(response).to have_http_status(401)
  269. end
  270. end
  271. end
  272. context 'when signed in' do
  273. let(:user) { Fabricate(:user) }
  274. before do
  275. sign_in(user)
  276. get :show, params: { username: account.username, format: format }
  277. end
  278. it 'returns http success' do
  279. expect(response).to have_http_status(200)
  280. end
  281. it 'returns application/activity+json' do
  282. expect(response.content_type).to eq 'application/activity+json'
  283. end
  284. it 'returns public Cache-Control header' do
  285. expect(response.headers['Cache-Control']).to include 'public'
  286. end
  287. it 'renders account' do
  288. json = body_as_json
  289. expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
  290. end
  291. end
  292. context 'with signature' do
  293. let(:remote_account) { Fabricate(:account, domain: 'example.com') }
  294. before do
  295. allow(controller).to receive(:signed_request_account).and_return(remote_account)
  296. get :show, params: { username: account.username, format: format }
  297. end
  298. it 'returns http success' do
  299. expect(response).to have_http_status(200)
  300. end
  301. it 'returns application/activity+json' do
  302. expect(response.content_type).to eq 'application/activity+json'
  303. end
  304. it_behaves_like 'cachable response'
  305. it 'renders account' do
  306. json = body_as_json
  307. expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
  308. end
  309. context 'in authorized fetch mode' do
  310. let(:authorized_fetch_mode) { true }
  311. it 'returns http success' do
  312. expect(response).to have_http_status(200)
  313. end
  314. it 'returns application/activity+json' do
  315. expect(response.content_type).to eq 'application/activity+json'
  316. end
  317. it 'returns private Cache-Control header' do
  318. expect(response.headers['Cache-Control']).to include 'private'
  319. end
  320. it 'returns Vary header with Signature' do
  321. expect(response.headers['Vary']).to include 'Signature'
  322. end
  323. it 'renders account' do
  324. json = body_as_json
  325. expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
  326. end
  327. end
  328. end
  329. end
  330. context 'as RSS' do
  331. let(:format) { 'rss' }
  332. it_behaves_like 'preliminary checks'
  333. shared_examples 'common response characteristics' do
  334. it 'returns http success' do
  335. expect(response).to have_http_status(200)
  336. end
  337. it_behaves_like 'cachable response'
  338. end
  339. context do
  340. before do
  341. get :show, params: { username: account.username, format: format }
  342. end
  343. it_behaves_like 'common response characteristics'
  344. it 'renders public status' do
  345. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status))
  346. end
  347. it 'renders self-reply' do
  348. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  349. end
  350. it 'renders status with media' do
  351. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_media))
  352. end
  353. it 'does not render reblog' do
  354. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  355. end
  356. it 'does not render private status' do
  357. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  358. end
  359. it 'does not render direct status' do
  360. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  361. end
  362. it 'does not render reply to someone else' do
  363. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  364. end
  365. end
  366. context 'with replies' do
  367. before do
  368. allow(controller).to receive(:replies_requested?).and_return(true)
  369. get :show, params: { username: account.username, format: format }
  370. end
  371. it_behaves_like 'common response characteristics'
  372. it 'renders public status' do
  373. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status))
  374. end
  375. it 'renders self-reply' do
  376. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  377. end
  378. it 'renders status with media' do
  379. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_media))
  380. end
  381. it 'does not render reblog' do
  382. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  383. end
  384. it 'does not render private status' do
  385. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  386. end
  387. it 'does not render direct status' do
  388. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  389. end
  390. it 'renders reply to someone else' do
  391. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_reply))
  392. end
  393. end
  394. context 'with media' do
  395. before do
  396. allow(controller).to receive(:media_requested?).and_return(true)
  397. get :show, params: { username: account.username, format: format }
  398. end
  399. it_behaves_like 'common response characteristics'
  400. it 'does not render public status' do
  401. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status))
  402. end
  403. it 'does not render self-reply' do
  404. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  405. end
  406. it 'renders status with media' do
  407. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_media))
  408. end
  409. it 'does not render reblog' do
  410. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  411. end
  412. it 'does not render private status' do
  413. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  414. end
  415. it 'does not render direct status' do
  416. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  417. end
  418. it 'does not render reply to someone else' do
  419. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  420. end
  421. end
  422. context 'with tag' do
  423. let(:tag) { Fabricate(:tag) }
  424. let!(:status_tag) { Fabricate(:status, account: account) }
  425. before do
  426. allow(controller).to receive(:tag_requested?).and_return(true)
  427. status_tag.tags << tag
  428. get :show, params: { username: account.username, format: format, tag: tag.to_param }
  429. end
  430. it_behaves_like 'common response characteristics'
  431. it 'does not render public status' do
  432. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status))
  433. end
  434. it 'does not render self-reply' do
  435. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  436. end
  437. it 'does not render status with media' do
  438. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_media))
  439. end
  440. it 'does not render reblog' do
  441. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  442. end
  443. it 'does not render private status' do
  444. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  445. end
  446. it 'does not render direct status' do
  447. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  448. end
  449. it 'does not render reply to someone else' do
  450. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  451. end
  452. it 'renders status with tag' do
  453. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_tag))
  454. end
  455. end
  456. end
  457. end
  458. end