statuses_controller_spec.rb 24 KB

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