statuses_controller_spec.rb 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. describe StatusesController do
  4. render_views
  5. describe 'GET #show' do
  6. let(:account) { Fabricate(:account) }
  7. let(:status) { Fabricate(:status, account: account) }
  8. context 'when account is permanently suspended' do
  9. before do
  10. account.suspend!
  11. account.deletion_request.destroy
  12. get :show, params: { account_username: account.username, id: status.id }
  13. end
  14. it 'returns http gone' do
  15. expect(response).to have_http_status(410)
  16. end
  17. end
  18. context 'when account is temporarily suspended' do
  19. before do
  20. account.suspend!
  21. get :show, params: { account_username: account.username, id: status.id }
  22. end
  23. it 'returns http forbidden' do
  24. expect(response).to have_http_status(403)
  25. end
  26. end
  27. context 'when status is a reblog' do
  28. let(:original_account) { Fabricate(:account, domain: 'example.com') }
  29. let(:original_status) { Fabricate(:status, account: original_account, url: 'https://example.com/123') }
  30. let(:status) { Fabricate(:status, account: account, reblog: original_status) }
  31. before do
  32. get :show, params: { account_username: status.account.username, id: status.id }
  33. end
  34. it 'redirects to the original status' do
  35. expect(response).to redirect_to(original_status.url)
  36. end
  37. end
  38. context 'when status is public' do
  39. before do
  40. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  41. end
  42. context 'with HTML' do
  43. let(:format) { 'html' }
  44. it 'renders status successfully', :aggregate_failures do
  45. expect(response).to have_http_status(200)
  46. expect(response.headers['Link'].to_s).to include 'activity+json'
  47. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  48. expect(response.headers['Cache-Control']).to include 'public'
  49. expect(response).to render_template(:show)
  50. expect(response.body).to include status.text
  51. end
  52. end
  53. context 'with JSON' do
  54. let(:format) { 'json' }
  55. it_behaves_like 'cacheable response', expects_vary: 'Accept, Accept-Language, Cookie'
  56. it 'renders ActivityPub Note object successfully', :aggregate_failures do
  57. expect(response).to have_http_status(200)
  58. expect(response.headers['Link'].to_s).to include 'activity+json'
  59. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  60. expect(response.headers['Content-Type']).to include 'application/activity+json'
  61. json = body_as_json
  62. expect(json[:content]).to include status.text
  63. end
  64. end
  65. end
  66. context 'when status is private' do
  67. let(:status) { Fabricate(:status, account: account, visibility: :private) }
  68. before do
  69. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  70. end
  71. context 'with JSON' do
  72. let(:format) { 'json' }
  73. it 'returns http not found' do
  74. expect(response).to have_http_status(404)
  75. end
  76. end
  77. context 'with HTML' do
  78. let(:format) { 'html' }
  79. it 'returns http not found' do
  80. expect(response).to have_http_status(404)
  81. end
  82. end
  83. end
  84. context 'when status is direct' do
  85. let(:status) { Fabricate(:status, account: account, visibility: :direct) }
  86. before do
  87. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  88. end
  89. context 'with JSON' do
  90. let(:format) { 'json' }
  91. it 'returns http not found' do
  92. expect(response).to have_http_status(404)
  93. end
  94. end
  95. context 'with HTML' do
  96. let(:format) { 'html' }
  97. it 'returns http not found' do
  98. expect(response).to have_http_status(404)
  99. end
  100. end
  101. end
  102. context 'when signed-in' do
  103. let(:user) { Fabricate(:user) }
  104. before do
  105. sign_in(user)
  106. end
  107. context 'when account blocks user' do
  108. before do
  109. account.block!(user.account)
  110. get :show, params: { account_username: status.account.username, id: status.id }
  111. end
  112. it 'returns http not found' do
  113. expect(response).to have_http_status(404)
  114. end
  115. end
  116. context 'when status is public' do
  117. before do
  118. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  119. end
  120. context 'with HTML' do
  121. let(:format) { 'html' }
  122. it 'renders status successfully', :aggregate_failures do
  123. expect(response).to have_http_status(200)
  124. expect(response.headers['Link'].to_s).to include 'activity+json'
  125. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  126. expect(response.headers['Cache-Control']).to include 'private'
  127. expect(response).to render_template(:show)
  128. expect(response.body).to include status.text
  129. end
  130. end
  131. context 'with JSON' do
  132. let(:format) { 'json' }
  133. it 'renders ActivityPub Note object successfully', :aggregate_failures do
  134. expect(response).to have_http_status(200)
  135. expect(response.headers['Link'].to_s).to include 'activity+json'
  136. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  137. expect(response.headers['Cache-Control']).to include 'private'
  138. expect(response.headers['Content-Type']).to include 'application/activity+json'
  139. json = body_as_json
  140. expect(json[:content]).to include status.text
  141. end
  142. end
  143. end
  144. context 'when status is private' do
  145. let(:status) { Fabricate(:status, account: account, visibility: :private) }
  146. context 'when user is authorized to see it' do
  147. before do
  148. user.account.follow!(account)
  149. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  150. end
  151. context 'with HTML' do
  152. let(:format) { 'html' }
  153. it 'renders status successfully', :aggregate_failures do
  154. expect(response).to have_http_status(200)
  155. expect(response.headers['Link'].to_s).to include 'activity+json'
  156. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  157. expect(response.headers['Cache-Control']).to include 'private'
  158. expect(response).to render_template(:show)
  159. expect(response.body).to include status.text
  160. end
  161. end
  162. context 'with JSON' do
  163. let(:format) { 'json' }
  164. it 'renders ActivityPub Note object successfully', :aggregate_failures do
  165. expect(response).to have_http_status(200)
  166. expect(response.headers['Link'].to_s).to include 'activity+json'
  167. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  168. expect(response.headers['Cache-Control']).to include 'private'
  169. expect(response.headers['Content-Type']).to include 'application/activity+json'
  170. json = body_as_json
  171. expect(json[:content]).to include status.text
  172. end
  173. end
  174. end
  175. context 'when user is not authorized to see it' do
  176. before do
  177. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  178. end
  179. context 'with JSON' do
  180. let(:format) { 'json' }
  181. it 'returns http not found' do
  182. expect(response).to have_http_status(404)
  183. end
  184. end
  185. context 'with HTML' do
  186. let(:format) { 'html' }
  187. it 'returns http not found' do
  188. expect(response).to have_http_status(404)
  189. end
  190. end
  191. end
  192. end
  193. context 'when status is direct' do
  194. let(:status) { Fabricate(:status, account: account, visibility: :direct) }
  195. context 'when user is authorized to see it' do
  196. before do
  197. Fabricate(:mention, account: user.account, status: status)
  198. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  199. end
  200. context 'with HTML' do
  201. let(:format) { 'html' }
  202. it 'renders status successfully', :aggregate_failures do
  203. expect(response).to have_http_status(200)
  204. expect(response.headers['Link'].to_s).to include 'activity+json'
  205. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  206. expect(response.headers['Cache-Control']).to include 'private'
  207. expect(response).to render_template(:show)
  208. expect(response.body).to include status.text
  209. end
  210. end
  211. context 'with JSON' do
  212. let(:format) { 'json' }
  213. it 'renders ActivityPub Note object successfully' do
  214. expect(response).to have_http_status(200)
  215. expect(response.headers['Link'].to_s).to include 'activity+json'
  216. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  217. expect(response.headers['Cache-Control']).to include 'private'
  218. expect(response.headers['Content-Type']).to include 'application/activity+json'
  219. json = body_as_json
  220. expect(json[:content]).to include status.text
  221. end
  222. end
  223. end
  224. context 'when user is not authorized to see it' do
  225. before do
  226. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  227. end
  228. context 'with JSON' do
  229. let(:format) { 'json' }
  230. it 'returns http not found' do
  231. expect(response).to have_http_status(404)
  232. end
  233. end
  234. context 'with HTML' do
  235. let(:format) { 'html' }
  236. it 'returns http not found' do
  237. expect(response).to have_http_status(404)
  238. end
  239. end
  240. end
  241. end
  242. end
  243. context 'with signature' do
  244. let(:remote_account) { Fabricate(:account, domain: 'example.com') }
  245. before do
  246. allow(controller).to receive(:signed_request_actor).and_return(remote_account)
  247. end
  248. context 'when account blocks account' do
  249. before do
  250. account.block!(remote_account)
  251. get :show, params: { account_username: status.account.username, id: status.id }
  252. end
  253. it 'returns http not found' do
  254. expect(response).to have_http_status(404)
  255. end
  256. end
  257. context 'when account domain blocks account' do
  258. before do
  259. account.block_domain!(remote_account.domain)
  260. get :show, params: { account_username: status.account.username, id: status.id }
  261. end
  262. it 'returns http not found' do
  263. expect(response).to have_http_status(404)
  264. end
  265. end
  266. context 'when status is public' do
  267. before do
  268. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  269. end
  270. context 'with HTML' do
  271. let(:format) { 'html' }
  272. it 'renders status successfully', :aggregate_failures do
  273. expect(response).to have_http_status(200)
  274. expect(response.headers['Link'].to_s).to include 'activity+json'
  275. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  276. expect(response.headers['Cache-Control']).to include 'private'
  277. expect(response).to render_template(:show)
  278. expect(response.body).to include status.text
  279. end
  280. end
  281. context 'with JSON' do
  282. let(:format) { 'json' }
  283. it_behaves_like 'cacheable response', expects_vary: 'Accept, Accept-Language, Cookie'
  284. it 'renders ActivityPub Note object successfully', :aggregate_failures do
  285. expect(response).to have_http_status(200)
  286. expect(response.headers['Link'].to_s).to include 'activity+json'
  287. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  288. expect(response.headers['Content-Type']).to include 'application/activity+json'
  289. json = body_as_json
  290. expect(json[:content]).to include status.text
  291. end
  292. end
  293. end
  294. context 'when status is private' do
  295. let(:status) { Fabricate(:status, account: account, visibility: :private) }
  296. context 'when user is authorized to see it' do
  297. before do
  298. remote_account.follow!(account)
  299. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  300. end
  301. context 'with HTML' do
  302. let(:format) { 'html' }
  303. it 'renders status successfully', :aggregate_failures do
  304. expect(response).to have_http_status(200)
  305. expect(response.headers['Link'].to_s).to include 'activity+json'
  306. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  307. expect(response.headers['Cache-Control']).to include 'private'
  308. expect(response).to render_template(:show)
  309. expect(response.body).to include status.text
  310. end
  311. end
  312. context 'with JSON' do
  313. let(:format) { 'json' }
  314. it 'renders ActivityPub Note object successfully' do
  315. expect(response).to have_http_status(200)
  316. expect(response.headers['Link'].to_s).to include 'activity+json'
  317. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  318. expect(response.headers['Cache-Control']).to include 'private'
  319. expect(response.headers['Content-Type']).to include 'application/activity+json'
  320. json = body_as_json
  321. expect(json[:content]).to include status.text
  322. end
  323. end
  324. end
  325. context 'when user is not authorized to see it' do
  326. before do
  327. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  328. end
  329. context 'with JSON' do
  330. let(:format) { 'json' }
  331. it 'returns http not found' do
  332. expect(response).to have_http_status(404)
  333. end
  334. end
  335. context 'with HTML' do
  336. let(:format) { 'html' }
  337. it 'returns http not found' do
  338. expect(response).to have_http_status(404)
  339. end
  340. end
  341. end
  342. end
  343. context 'when status is direct' do
  344. let(:status) { Fabricate(:status, account: account, visibility: :direct) }
  345. context 'when user is authorized to see it' do
  346. before do
  347. Fabricate(:mention, account: remote_account, status: status)
  348. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  349. end
  350. context 'with HTML' do
  351. let(:format) { 'html' }
  352. it 'renders status successfully', :aggregate_failures do
  353. expect(response).to have_http_status(200)
  354. expect(response.headers['Link'].to_s).to include 'activity+json'
  355. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  356. expect(response.headers['Cache-Control']).to include 'private'
  357. expect(response).to render_template(:show)
  358. expect(response.body).to include status.text
  359. end
  360. end
  361. context 'with JSON' do
  362. let(:format) { 'json' }
  363. it 'renders ActivityPub Note object', :aggregate_failures do
  364. expect(response).to have_http_status(200)
  365. expect(response.headers['Link'].to_s).to include 'activity+json'
  366. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  367. expect(response.headers['Cache-Control']).to include 'private'
  368. expect(response.headers['Content-Type']).to include 'application/activity+json'
  369. json = body_as_json
  370. expect(json[:content]).to include status.text
  371. end
  372. end
  373. end
  374. context 'when user is not authorized to see it' do
  375. before do
  376. get :show, params: { account_username: status.account.username, id: status.id, format: format }
  377. end
  378. context 'with JSON' do
  379. let(:format) { 'json' }
  380. it 'returns http not found' do
  381. expect(response).to have_http_status(404)
  382. end
  383. end
  384. context 'with HTML' do
  385. let(:format) { 'html' }
  386. it 'returns http not found' do
  387. expect(response).to have_http_status(404)
  388. end
  389. end
  390. end
  391. end
  392. end
  393. end
  394. describe 'GET #activity' do
  395. let(:account) { Fabricate(:account) }
  396. let(:status) { Fabricate(:status, account: account) }
  397. context 'when account is permanently suspended' do
  398. before do
  399. account.suspend!
  400. account.deletion_request.destroy
  401. get :activity, params: { account_username: account.username, id: status.id }
  402. end
  403. it 'returns http gone' do
  404. expect(response).to have_http_status(410)
  405. end
  406. end
  407. context 'when account is temporarily suspended' do
  408. before do
  409. account.suspend!
  410. get :activity, params: { account_username: account.username, id: status.id }
  411. end
  412. it 'returns http forbidden' do
  413. expect(response).to have_http_status(403)
  414. end
  415. end
  416. context 'when status is public' do
  417. before do
  418. status.update(visibility: :public)
  419. get :activity, params: { account_username: account.username, id: status.id }
  420. end
  421. it 'returns http success' do
  422. expect(response).to have_http_status(:success)
  423. end
  424. end
  425. context 'when status is private' do
  426. before do
  427. status.update(visibility: :private)
  428. get :activity, params: { account_username: account.username, id: status.id }
  429. end
  430. it 'returns http not_found' do
  431. expect(response).to have_http_status(404)
  432. end
  433. end
  434. context 'when status is direct' do
  435. before do
  436. status.update(visibility: :direct)
  437. get :activity, params: { account_username: account.username, id: status.id }
  438. end
  439. it 'returns http not_found' do
  440. expect(response).to have_http_status(404)
  441. end
  442. end
  443. context 'when signed-in' do
  444. let(:user) { Fabricate(:user) }
  445. before do
  446. sign_in(user)
  447. end
  448. context 'when status is public' do
  449. before do
  450. status.update(visibility: :public)
  451. get :activity, params: { account_username: account.username, id: status.id }
  452. end
  453. it 'returns http success' do
  454. expect(response).to have_http_status(:success)
  455. end
  456. end
  457. context 'when status is private' do
  458. before do
  459. status.update(visibility: :private)
  460. end
  461. context 'when user is authorized to see it' do
  462. before do
  463. user.account.follow!(account)
  464. get :activity, params: { account_username: account.username, id: status.id }
  465. end
  466. it 'returns http success' do
  467. expect(response).to have_http_status(200)
  468. end
  469. end
  470. context 'when user is not authorized to see it' do
  471. before do
  472. get :activity, params: { account_username: account.username, id: status.id }
  473. end
  474. it 'returns http not_found' do
  475. expect(response).to have_http_status(404)
  476. end
  477. end
  478. end
  479. context 'when status is direct' do
  480. before do
  481. status.update(visibility: :direct)
  482. end
  483. context 'when user is authorized to see it' do
  484. before do
  485. Fabricate(:mention, account: user.account, status: status)
  486. get :activity, params: { account_username: account.username, id: status.id }
  487. end
  488. it 'returns http success' do
  489. expect(response).to have_http_status(200)
  490. end
  491. end
  492. context 'when user is not authorized to see it' do
  493. before do
  494. get :activity, params: { account_username: account.username, id: status.id }
  495. end
  496. it 'returns http not_found' do
  497. expect(response).to have_http_status(404)
  498. end
  499. end
  500. end
  501. end
  502. context 'with signature' do
  503. let(:remote_account) { Fabricate(:account, domain: 'example.com') }
  504. before do
  505. allow(controller).to receive(:signed_request_actor).and_return(remote_account)
  506. end
  507. context 'when status is public' do
  508. before do
  509. status.update(visibility: :public)
  510. get :activity, params: { account_username: account.username, id: status.id }
  511. end
  512. it 'returns http success' do
  513. expect(response).to have_http_status(:success)
  514. end
  515. end
  516. context 'when status is private' do
  517. before do
  518. status.update(visibility: :private)
  519. end
  520. context 'when user is authorized to see it' do
  521. before do
  522. remote_account.follow!(account)
  523. get :activity, params: { account_username: account.username, id: status.id }
  524. end
  525. it 'returns http success' do
  526. expect(response).to have_http_status(200)
  527. end
  528. end
  529. context 'when user is not authorized to see it' do
  530. before do
  531. get :activity, params: { account_username: account.username, id: status.id }
  532. end
  533. it 'returns http not_found' do
  534. expect(response).to have_http_status(404)
  535. end
  536. end
  537. end
  538. context 'when status is direct' do
  539. before do
  540. status.update(visibility: :direct)
  541. end
  542. context 'when user is authorized to see it' do
  543. before do
  544. Fabricate(:mention, account: remote_account, status: status)
  545. get :activity, params: { account_username: account.username, id: status.id }
  546. end
  547. it 'returns http success' do
  548. expect(response).to have_http_status(200)
  549. end
  550. end
  551. context 'when user is not authorized to see it' do
  552. before do
  553. get :activity, params: { account_username: account.username, id: status.id }
  554. end
  555. it 'returns http not_found' do
  556. expect(response).to have_http_status(404)
  557. end
  558. end
  559. end
  560. end
  561. end
  562. describe 'GET #embed' do
  563. let(:account) { Fabricate(:account) }
  564. let(:status) { Fabricate(:status, account: account) }
  565. context 'when account is suspended' do
  566. let(:account) { Fabricate(:account, suspended: true) }
  567. before do
  568. get :embed, params: { account_username: account.username, id: status.id }
  569. end
  570. it 'returns http gone' do
  571. expect(response).to have_http_status(410)
  572. end
  573. end
  574. context 'when status is a reblog' do
  575. let(:original_account) { Fabricate(:account, domain: 'example.com') }
  576. let(:original_status) { Fabricate(:status, account: original_account, url: 'https://example.com/123') }
  577. let(:status) { Fabricate(:status, account: account, reblog: original_status) }
  578. before do
  579. get :embed, params: { account_username: status.account.username, id: status.id }
  580. end
  581. it 'returns http not found' do
  582. expect(response).to have_http_status(404)
  583. end
  584. end
  585. context 'when status is public' do
  586. before do
  587. get :embed, params: { account_username: status.account.username, id: status.id }
  588. end
  589. it 'renders status successfully', :aggregate_failures do
  590. expect(response).to have_http_status(200)
  591. expect(response.headers['Link'].to_s).to include 'activity+json'
  592. expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie'
  593. expect(response.headers['Cache-Control']).to include 'public'
  594. expect(response).to render_template(:embed)
  595. expect(response.body).to include status.text
  596. end
  597. end
  598. context 'when status is private' do
  599. let(:status) { Fabricate(:status, account: account, visibility: :private) }
  600. before do
  601. get :embed, params: { account_username: status.account.username, id: status.id }
  602. end
  603. it 'returns http not found' do
  604. expect(response).to have_http_status(404)
  605. end
  606. end
  607. context 'when status is direct' do
  608. let(:status) { Fabricate(:status, account: account, visibility: :direct) }
  609. before do
  610. get :embed, params: { account_username: status.account.username, id: status.id }
  611. end
  612. it 'returns http not found' do
  613. expect(response).to have_http_status(404)
  614. end
  615. end
  616. end
  617. end