catstodon/spec/controllers/statuses_controller_spec.rb
Josh Soref b5329e0035
Spelling (#17705)
* spelling: account

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: affiliated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: appearance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: autosuggest

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: cacheable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: component

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conversations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: domain.example

Clarify what's distinct and use RFC friendly domain space.

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: environment

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: exceeds

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: functional

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inefficiency

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: not

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: notifications

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: occurring

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: position

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: progress

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: promotable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: reblogging

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: repetitive

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: resolve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: saturated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: similar

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: strategies

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: success

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: targeting

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: thumbnails

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unauthorized

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unsensitizes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: validations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: various

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-03-06 22:51:40 +01:00

863 lines
24 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
describe StatusesController do
render_views
shared_examples 'cacheable response' do
it 'does not set cookies' do
expect(response.cookies).to be_empty
expect(response.headers['Set-Cookies']).to be nil
end
it 'does not set sessions' do
expect(session).to be_empty
end
it 'returns public Cache-Control header' do
expect(response.headers['Cache-Control']).to include 'public'
end
end
describe 'GET #show' do
let(:account) { Fabricate(:account) }
let(:status) { Fabricate(:status, account: account) }
context 'when account is permanently suspended' do
before do
account.suspend!
account.deletion_request.destroy
get :show, params: { account_username: account.username, id: status.id }
end
it 'returns http gone' do
expect(response).to have_http_status(410)
end
end
context 'when account is temporarily suspended' do
before do
account.suspend!
get :show, params: { account_username: account.username, id: status.id }
end
it 'returns http forbidden' do
expect(response).to have_http_status(403)
end
end
context 'when status is a reblog' do
let(:original_account) { Fabricate(:account, domain: 'example.com') }
let(:original_status) { Fabricate(:status, account: original_account, url: 'https://example.com/123') }
let(:status) { Fabricate(:status, account: account, reblog: original_status) }
before do
get :show, params: { account_username: status.account.username, id: status.id }
end
it 'redirects to the original status' do
expect(response).to redirect_to(original_status.url)
end
end
context 'when status is public' do
before do
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns public Cache-Control header' do
expect(response.headers['Cache-Control']).to include 'public'
end
it 'renders status' do
expect(response).to render_template(:show)
expect(response.body).to include status.text
end
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it_behaves_like 'cacheable response'
it 'returns Content-Type header' do
expect(response.headers['Content-Type']).to include 'application/activity+json'
end
it 'renders ActivityPub Note object' do
json = body_as_json
expect(json[:content]).to include status.text
end
end
end
context 'when status is private' do
let(:status) { Fabricate(:status, account: account, visibility: :private) }
before do
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
end
context 'when status is direct' do
let(:status) { Fabricate(:status, account: account, visibility: :direct) }
before do
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
end
context 'when signed-in' do
let(:user) { Fabricate(:user) }
before do
sign_in(user)
end
context 'when account blocks user' do
before do
account.block!(user.account)
get :show, params: { account_username: status.account.username, id: status.id }
end
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'when status is public' do
before do
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns no Cache-Control header' do
expect(response.headers).to_not include 'Cache-Control'
end
it 'renders status' do
expect(response).to render_template(:show)
expect(response.body).to include status.text
end
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns public Cache-Control header' do
expect(response.headers['Cache-Control']).to include 'public'
end
it 'returns Content-Type header' do
expect(response.headers['Content-Type']).to include 'application/activity+json'
end
it 'renders ActivityPub Note object' do
json = body_as_json
expect(json[:content]).to include status.text
end
end
end
context 'when status is private' do
let(:status) { Fabricate(:status, account: account, visibility: :private) }
context 'when user is authorized to see it' do
before do
user.account.follow!(account)
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns no Cache-Control header' do
expect(response.headers).to_not include 'Cache-Control'
end
it 'renders status' do
expect(response).to render_template(:show)
expect(response.body).to include status.text
end
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns private Cache-Control header' do
expect(response.headers['Cache-Control']).to include 'private'
end
it 'returns Content-Type header' do
expect(response.headers['Content-Type']).to include 'application/activity+json'
end
it 'renders ActivityPub Note object' do
json = body_as_json
expect(json[:content]).to include status.text
end
end
end
context 'when user is not authorized to see it' do
before do
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
end
end
context 'when status is direct' do
let(:status) { Fabricate(:status, account: account, visibility: :direct) }
context 'when user is authorized to see it' do
before do
Fabricate(:mention, account: user.account, status: status)
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns no Cache-Control header' do
expect(response.headers).to_not include 'Cache-Control'
end
it 'renders status' do
expect(response).to render_template(:show)
expect(response.body).to include status.text
end
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns private Cache-Control header' do
expect(response.headers['Cache-Control']).to include 'private'
end
it 'returns Content-Type header' do
expect(response.headers['Content-Type']).to include 'application/activity+json'
end
it 'renders ActivityPub Note object' do
json = body_as_json
expect(json[:content]).to include status.text
end
end
end
context 'when user is not authorized to see it' do
before do
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
end
end
end
context 'with signature' do
let(:remote_account) { Fabricate(:account, domain: 'example.com') }
before do
allow(controller).to receive(:signed_request_account).and_return(remote_account)
end
context 'when account blocks account' do
before do
account.block!(remote_account)
get :show, params: { account_username: status.account.username, id: status.id }
end
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'when account domain blocks account' do
before do
account.block_domain!(remote_account.domain)
get :show, params: { account_username: status.account.username, id: status.id }
end
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'when status is public' do
before do
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns no Cache-Control header' do
expect(response.headers).to_not include 'Cache-Control'
end
it 'renders status' do
expect(response).to render_template(:show)
expect(response.body).to include status.text
end
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it_behaves_like 'cacheable response'
it 'returns Content-Type header' do
expect(response.headers['Content-Type']).to include 'application/activity+json'
end
it 'renders ActivityPub Note object' do
json = body_as_json
expect(json[:content]).to include status.text
end
end
end
context 'when status is private' do
let(:status) { Fabricate(:status, account: account, visibility: :private) }
context 'when user is authorized to see it' do
before do
remote_account.follow!(account)
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns no Cache-Control header' do
expect(response.headers).to_not include 'Cache-Control'
end
it 'renders status' do
expect(response).to render_template(:show)
expect(response.body).to include status.text
end
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns private Cache-Control header' do
expect(response.headers['Cache-Control']).to include 'private'
end
it 'returns Content-Type header' do
expect(response.headers['Content-Type']).to include 'application/activity+json'
end
it 'renders ActivityPub Note object' do
json = body_as_json
expect(json[:content]).to include status.text
end
end
end
context 'when user is not authorized to see it' do
before do
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
end
end
context 'when status is direct' do
let(:status) { Fabricate(:status, account: account, visibility: :direct) }
context 'when user is authorized to see it' do
before do
Fabricate(:mention, account: remote_account, status: status)
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns no Cache-Control header' do
expect(response.headers).to_not include 'Cache-Control'
end
it 'renders status' do
expect(response).to render_template(:show)
expect(response.body).to include status.text
end
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns private Cache-Control header' do
expect(response.headers['Cache-Control']).to include 'private'
end
it 'returns Content-Type header' do
expect(response.headers['Content-Type']).to include 'application/activity+json'
end
it 'renders ActivityPub Note object' do
json = body_as_json
expect(json[:content]).to include status.text
end
end
end
context 'when user is not authorized to see it' do
before do
get :show, params: { account_username: status.account.username, id: status.id, format: format }
end
context 'as JSON' do
let(:format) { 'json' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'as HTML' do
let(:format) { 'html' }
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
end
end
end
end
describe 'GET #activity' do
let(:account) { Fabricate(:account) }
let(:status) { Fabricate(:status, account: account) }
context 'when account is permanently suspended' do
before do
account.suspend!
account.deletion_request.destroy
get :activity, params: { account_username: account.username, id: status.id }
end
it 'returns http gone' do
expect(response).to have_http_status(410)
end
end
context 'when account is temporarily suspended' do
before do
account.suspend!
get :activity, params: { account_username: account.username, id: status.id }
end
it 'returns http forbidden' do
expect(response).to have_http_status(403)
end
end
context 'when status is public' do
pending
end
context 'when status is private' do
pending
end
context 'when status is direct' do
pending
end
context 'when signed-in' do
context 'when status is public' do
pending
end
context 'when status is private' do
context 'when user is authorized to see it' do
pending
end
context 'when user is not authorized to see it' do
pending
end
end
context 'when status is direct' do
context 'when user is authorized to see it' do
pending
end
context 'when user is not authorized to see it' do
pending
end
end
end
context 'with signature' do
context 'when status is public' do
pending
end
context 'when status is private' do
context 'when user is authorized to see it' do
pending
end
context 'when user is not authorized to see it' do
pending
end
end
context 'when status is direct' do
context 'when user is authorized to see it' do
pending
end
context 'when user is not authorized to see it' do
pending
end
end
end
end
describe 'GET #embed' do
let(:account) { Fabricate(:account) }
let(:status) { Fabricate(:status, account: account) }
context 'when account is suspended' do
let(:account) { Fabricate(:account, suspended: true) }
before do
get :embed, params: { account_username: account.username, id: status.id }
end
it 'returns http gone' do
expect(response).to have_http_status(410)
end
end
context 'when status is a reblog' do
let(:original_account) { Fabricate(:account, domain: 'example.com') }
let(:original_status) { Fabricate(:status, account: original_account, url: 'https://example.com/123') }
let(:status) { Fabricate(:status, account: account, reblog: original_status) }
before do
get :embed, params: { account_username: status.account.username, id: status.id }
end
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'when status is public' do
before do
get :embed, params: { account_username: status.account.username, id: status.id }
end
it 'returns http success' do
expect(response).to have_http_status(200)
end
it 'returns Link header' do
expect(response.headers['Link'].to_s).to include 'activity+json'
end
it 'returns Vary header' do
expect(response.headers['Vary']).to eq 'Accept'
end
it 'returns public Cache-Control header' do
expect(response.headers['Cache-Control']).to include 'public'
end
it 'renders status' do
expect(response).to render_template(:embed)
expect(response.body).to include status.text
end
end
context 'when status is private' do
let(:status) { Fabricate(:status, account: account, visibility: :private) }
before do
get :embed, params: { account_username: status.account.username, id: status.id }
end
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
context 'when status is direct' do
let(:status) { Fabricate(:status, account: account, visibility: :direct) }
before do
get :embed, params: { account_username: status.account.username, id: status.id }
end
it 'returns http not found' do
expect(response).to have_http_status(404)
end
end
end
end