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.

619 lines
21 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 success' do
  268. expect(response).to have_http_status(200)
  269. end
  270. it 'returns application/activity+json' do
  271. expect(response.content_type).to eq 'application/activity+json'
  272. end
  273. it_behaves_like 'cachable response'
  274. it 'returns Vary header with Signature' do
  275. expect(response.headers['Vary']).to include 'Signature'
  276. end
  277. it 'renders bare minimum account' do
  278. json = body_as_json
  279. expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey)
  280. expect(json).to_not include(:name, :summary)
  281. end
  282. end
  283. end
  284. context 'when signed in' do
  285. let(:user) { Fabricate(:user) }
  286. before do
  287. sign_in(user)
  288. get :show, params: { username: account.username, format: format }
  289. end
  290. it 'returns http success' do
  291. expect(response).to have_http_status(200)
  292. end
  293. it 'returns application/activity+json' do
  294. expect(response.content_type).to eq 'application/activity+json'
  295. end
  296. it 'returns public Cache-Control header' do
  297. expect(response.headers['Cache-Control']).to include 'public'
  298. end
  299. it 'renders account' do
  300. json = body_as_json
  301. expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
  302. end
  303. end
  304. context 'with signature' do
  305. let(:remote_account) { Fabricate(:account, domain: 'example.com') }
  306. before do
  307. allow(controller).to receive(:signed_request_account).and_return(remote_account)
  308. get :show, params: { username: account.username, format: format }
  309. end
  310. it 'returns http success' do
  311. expect(response).to have_http_status(200)
  312. end
  313. it 'returns application/activity+json' do
  314. expect(response.content_type).to eq 'application/activity+json'
  315. end
  316. it_behaves_like 'cachable response'
  317. it 'renders account' do
  318. json = body_as_json
  319. expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
  320. end
  321. context 'in authorized fetch mode' do
  322. let(:authorized_fetch_mode) { true }
  323. it 'returns http success' do
  324. expect(response).to have_http_status(200)
  325. end
  326. it 'returns application/activity+json' do
  327. expect(response.content_type).to eq 'application/activity+json'
  328. end
  329. it 'returns private Cache-Control header' do
  330. expect(response.headers['Cache-Control']).to include 'private'
  331. end
  332. it 'returns Vary header with Signature' do
  333. expect(response.headers['Vary']).to include 'Signature'
  334. end
  335. it 'renders account' do
  336. json = body_as_json
  337. expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
  338. end
  339. end
  340. end
  341. end
  342. context 'as RSS' do
  343. let(:format) { 'rss' }
  344. it_behaves_like 'preliminary checks'
  345. shared_examples 'common response characteristics' do
  346. it 'returns http success' do
  347. expect(response).to have_http_status(200)
  348. end
  349. it_behaves_like 'cachable response'
  350. end
  351. context do
  352. before do
  353. get :show, params: { username: account.username, format: format }
  354. end
  355. it_behaves_like 'common response characteristics'
  356. it 'renders public status' do
  357. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status))
  358. end
  359. it 'renders self-reply' do
  360. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  361. end
  362. it 'renders status with media' do
  363. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_media))
  364. end
  365. it 'does not render reblog' do
  366. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  367. end
  368. it 'does not render private status' do
  369. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  370. end
  371. it 'does not render direct status' do
  372. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  373. end
  374. it 'does not render reply to someone else' do
  375. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  376. end
  377. end
  378. context 'with replies' do
  379. before do
  380. allow(controller).to receive(:replies_requested?).and_return(true)
  381. get :show, params: { username: account.username, format: format }
  382. end
  383. it_behaves_like 'common response characteristics'
  384. it 'renders public status' do
  385. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status))
  386. end
  387. it 'renders self-reply' do
  388. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  389. end
  390. it 'renders status with media' do
  391. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_media))
  392. end
  393. it 'does not render reblog' do
  394. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  395. end
  396. it 'does not render private status' do
  397. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  398. end
  399. it 'does not render direct status' do
  400. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  401. end
  402. it 'renders reply to someone else' do
  403. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_reply))
  404. end
  405. end
  406. context 'with media' do
  407. before do
  408. allow(controller).to receive(:media_requested?).and_return(true)
  409. get :show, params: { username: account.username, format: format }
  410. end
  411. it_behaves_like 'common response characteristics'
  412. it 'does not render public status' do
  413. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status))
  414. end
  415. it 'does not render self-reply' do
  416. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  417. end
  418. it 'renders status with media' do
  419. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_media))
  420. end
  421. it 'does not render reblog' do
  422. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  423. end
  424. it 'does not render private status' do
  425. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  426. end
  427. it 'does not render direct status' do
  428. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  429. end
  430. it 'does not render reply to someone else' do
  431. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  432. end
  433. end
  434. context 'with tag' do
  435. let(:tag) { Fabricate(:tag) }
  436. let!(:status_tag) { Fabricate(:status, account: account) }
  437. before do
  438. allow(controller).to receive(:tag_requested?).and_return(true)
  439. status_tag.tags << tag
  440. get :show, params: { username: account.username, format: format, tag: tag.to_param }
  441. end
  442. it_behaves_like 'common response characteristics'
  443. it 'does not render public status' do
  444. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status))
  445. end
  446. it 'does not render self-reply' do
  447. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_self_reply))
  448. end
  449. it 'does not render status with media' do
  450. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_media))
  451. end
  452. it 'does not render reblog' do
  453. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reblog.reblog))
  454. end
  455. it 'does not render private status' do
  456. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_private))
  457. end
  458. it 'does not render direct status' do
  459. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_direct))
  460. end
  461. it 'does not render reply to someone else' do
  462. expect(response.body).to_not include(ActivityPub::TagManager.instance.url_for(status_reply))
  463. end
  464. it 'renders status with tag' do
  465. expect(response.body).to include(ActivityPub::TagManager.instance.url_for(status_tag))
  466. end
  467. end
  468. end
  469. end
  470. end