diff options
Diffstat (limited to 'spec/controllers')
28 files changed, 664 insertions, 99 deletions
diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb index d61c8c9bd..92f888590 100644 --- a/spec/controllers/accounts_controller_spec.rb +++ b/spec/controllers/accounts_controller_spec.rb @@ -10,6 +10,13 @@ RSpec.describe AccountsController, type: :controller do let!(:status2) { Status.create!(account: alice, text: 'Boop', thread: status1) } let!(:status3) { Status.create!(account: alice, text: 'Picture!') } let!(:status4) { Status.create!(account: alice, text: 'Mentioning @alice') } + let!(:status5) { Status.create!(account: alice, text: 'Kitsune') } + let!(:status6) { Status.create!(account: alice, text: 'Neko') } + let!(:status7) { Status.create!(account: alice, text: 'Tanuki') } + + let!(:status_pin1) { StatusPin.create!(account: alice, status: status5, created_at: 5.days.ago) } + let!(:status_pin2) { StatusPin.create!(account: alice, status: status6, created_at: 2.years.ago) } + let!(:status_pin3) { StatusPin.create!(account: alice, status: status7, created_at: 10.minutes.ago) } before do status3.media_attachments.create!(account: alice, file: fixture_file_upload('files/attachment.jpg', 'image/jpeg')) @@ -48,9 +55,35 @@ RSpec.describe AccountsController, type: :controller do it 'returns http success with Activity Streams 2.0' do expect(response).to have_http_status(:success) end + + it 'returns application/activity+json' do + expect(response.content_type).to eq 'application/activity+json' + end end - context 'html' do + context 'html without since_id nor max_id' do + before do + get :show, params: { username: alice.username } + end + + it 'assigns @account' do + expect(assigns(:account)).to eq alice + end + + it 'assigns @pinned_statuses' do + pinned_statuses = assigns(:pinned_statuses).to_a + expect(pinned_statuses.size).to eq 3 + expect(pinned_statuses[0]).to eq status7 + expect(pinned_statuses[1]).to eq status5 + expect(pinned_statuses[2]).to eq status6 + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + end + + context 'html with since_id and max_id' do before do get :show, params: { username: alice.username, max_id: status4.id, since_id: status1.id } end @@ -66,6 +99,11 @@ RSpec.describe AccountsController, type: :controller do expect(statuses[1]).to eq status2 end + it 'assigns an empty array to @pinned_statuses' do + pinned_statuses = assigns(:pinned_statuses).to_a + expect(pinned_statuses.size).to eq 0 + end + it 'returns http success' do expect(response).to have_http_status(:success) end diff --git a/spec/controllers/activitypub/inboxes_controller_spec.rb b/spec/controllers/activitypub/inboxes_controller_spec.rb new file mode 100644 index 000000000..5c12fea7d --- /dev/null +++ b/spec/controllers/activitypub/inboxes_controller_spec.rb @@ -0,0 +1,7 @@ +require 'rails_helper' + +RSpec.describe ActivityPub::InboxesController, type: :controller do + describe 'POST #create' do + pending + end +end diff --git a/spec/controllers/activitypub/outboxes_controller_spec.rb b/spec/controllers/activitypub/outboxes_controller_spec.rb new file mode 100644 index 000000000..a25998021 --- /dev/null +++ b/spec/controllers/activitypub/outboxes_controller_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +RSpec.describe ActivityPub::OutboxesController, type: :controller do + let!(:account) { Fabricate(:account) } + + before do + Fabricate(:status, account: account) + end + + describe 'GET #show' do + before do + get :show, params: { account_username: account.username } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'returns application/activity+json' do + expect(response.content_type).to eq 'application/activity+json' + end + end +end diff --git a/spec/controllers/api/oembed_controller_spec.rb b/spec/controllers/api/oembed_controller_spec.rb index 43631a7e5..7af4a6a5b 100644 --- a/spec/controllers/api/oembed_controller_spec.rb +++ b/spec/controllers/api/oembed_controller_spec.rb @@ -8,6 +8,7 @@ RSpec.describe Api::OEmbedController, type: :controller do describe 'GET #show' do before do + request.host = Rails.configuration.x.local_domain get :show, params: { url: account_stream_entry_url(alice, status.stream_entry) }, format: :json end diff --git a/spec/controllers/api/subscriptions_controller_spec.rb b/spec/controllers/api/subscriptions_controller_spec.rb index 76f9740ca..d90da9e32 100644 --- a/spec/controllers/api/subscriptions_controller_spec.rb +++ b/spec/controllers/api/subscriptions_controller_spec.rb @@ -38,19 +38,19 @@ RSpec.describe Api::SubscriptionsController, type: :controller do before do stub_request(:post, "https://quitter.no/main/push/hub").to_return(:status => 200, :body => "", :headers => {}) stub_request(:get, "https://quitter.no/avatar/7477-300-20160211190340.png").to_return(request_fixture('avatar.txt')) - stub_request(:head, "https://quitter.no/notice/1269244").to_return(status: 404) - stub_request(:head, "https://quitter.no/notice/1265331").to_return(status: 404) - stub_request(:head, "https://community.highlandarrow.com/notice/54411").to_return(status: 404) - stub_request(:head, "https://community.highlandarrow.com/notice/53857").to_return(status: 404) - stub_request(:head, "https://community.highlandarrow.com/notice/51852").to_return(status: 404) - stub_request(:head, "https://social.umeahackerspace.se/notice/424348").to_return(status: 404) - stub_request(:head, "https://community.highlandarrow.com/notice/50467").to_return(status: 404) - stub_request(:head, "https://quitter.no/notice/1243309").to_return(status: 404) - stub_request(:head, "https://quitter.no/user/7477").to_return(status: 404) - stub_request(:head, "https://community.highlandarrow.com/user/1").to_return(status: 404) - stub_request(:head, "https://social.umeahackerspace.se/user/2").to_return(status: 404) - stub_request(:head, "https://gs.kawa-kun.com/user/2").to_return(status: 404) - stub_request(:head, "https://mastodon.social/users/Gargron").to_return(status: 404) + stub_request(:get, "https://quitter.no/notice/1269244").to_return(status: 404) + stub_request(:get, "https://quitter.no/notice/1265331").to_return(status: 404) + stub_request(:get, "https://community.highlandarrow.com/notice/54411").to_return(status: 404) + stub_request(:get, "https://community.highlandarrow.com/notice/53857").to_return(status: 404) + stub_request(:get, "https://community.highlandarrow.com/notice/51852").to_return(status: 404) + stub_request(:get, "https://social.umeahackerspace.se/notice/424348").to_return(status: 404) + stub_request(:get, "https://community.highlandarrow.com/notice/50467").to_return(status: 404) + stub_request(:get, "https://quitter.no/notice/1243309").to_return(status: 404) + stub_request(:get, "https://quitter.no/user/7477").to_return(status: 404) + stub_request(:any, "https://community.highlandarrow.com/user/1").to_return(status: 404) + stub_request(:any, "https://social.umeahackerspace.se/user/2").to_return(status: 404) + stub_request(:any, "https://gs.kawa-kun.com/user/2").to_return(status: 404) + stub_request(:any, "https://mastodon.social/users/Gargron").to_return(status: 404) request.env['HTTP_X_HUB_SIGNATURE'] = "sha1=#{OpenSSL::HMAC.hexdigest('sha1', 'abc', feed)}" request.env['RAW_POST_DATA'] = feed diff --git a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb index 3f655c7b2..247420d08 100644 --- a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb @@ -4,52 +4,81 @@ describe Api::V1::Accounts::CredentialsController do render_views let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write') } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read write') } - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #show' do - it 'returns http success' do - get :show - expect(response).to have_http_status(:success) + context 'with an oauth token' do + before do + allow(controller).to receive(:doorkeeper_token) { token } end - end - - describe 'PATCH #update' do - describe 'with valid data' do - before do - patch :update, params: { - display_name: "Alice Isn't Dead", - note: "Hi!\n\nToot toot!", - avatar: fixture_file_upload('files/avatar.gif', 'image/gif'), - header: fixture_file_upload('files/attachment.jpg', 'image/jpeg'), - } - end + describe 'GET #show' do it 'returns http success' do + get :show expect(response).to have_http_status(:success) end + end + + describe 'PATCH #update' do + describe 'with valid data' do + before do + allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async) + + patch :update, params: { + display_name: "Alice Isn't Dead", + note: "Hi!\n\nToot toot!", + avatar: fixture_file_upload('files/avatar.gif', 'image/gif'), + header: fixture_file_upload('files/attachment.jpg', 'image/jpeg'), + } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end - it 'updates account info' do - user.account.reload + it 'updates account info' do + user.account.reload - expect(user.account.display_name).to eq("Alice Isn't Dead") - expect(user.account.note).to eq("Hi!\n\nToot toot!") - expect(user.account.avatar).to exist - expect(user.account.header).to exist + expect(user.account.display_name).to eq("Alice Isn't Dead") + expect(user.account.note).to eq("Hi!\n\nToot toot!") + expect(user.account.avatar).to exist + expect(user.account.header).to exist + end + + it 'queues up an account update distribution' do + expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(user.account_id) + end + end + + describe 'with invalid data' do + before do + note = 'This is too long. ' + note = note + 'a' * (Account::MAX_NOTE_LENGTH - note.length + 1) + patch :update, params: { note: note } + end + + it 'returns http unprocessable entity' do + expect(response).to have_http_status(:unprocessable_entity) + end end end + end + + context 'without an oauth token' do + before do + allow(controller).to receive(:doorkeeper_token) { nil } + end - describe 'with invalid data' do - before do - # note length limit is 501, presently hardcoded, so give it 510 to fail - patch :update, params: { note: '1234567890' * 51 } + describe 'GET #show' do + it 'returns http unauthorized' do + get :show + expect(response).to have_http_status(:unauthorized) end + end - it 'returns http unprocessable entity' do - expect(response).to have_http_status(:unprocessable_entity) + describe 'PATCH #update' do + it 'returns http unauthorized' do + patch :update, params: { note: 'Foo' } + expect(response).to have_http_status(:unauthorized) end end end diff --git a/spec/controllers/api/v1/accounts/relationships_controller_spec.rb b/spec/controllers/api/v1/accounts/relationships_controller_spec.rb index 3a9607317..431fc2194 100644 --- a/spec/controllers/api/v1/accounts/relationships_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/relationships_controller_spec.rb @@ -50,14 +50,14 @@ describe Api::V1::Accounts::RelationshipsController do json = body_as_json expect(json).to be_a Enumerable - expect(json.first[:id]).to be simon.id + expect(json.first[:id]).to eq simon.id.to_s expect(json.first[:following]).to be true expect(json.first[:followed_by]).to be false expect(json.first[:muting]).to be false expect(json.first[:requested]).to be false expect(json.first[:domain_blocking]).to be false - expect(json.second[:id]).to be lewis.id + expect(json.second[:id]).to eq lewis.id.to_s expect(json.second[:following]).to be false expect(json.second[:followed_by]).to be true expect(json.second[:muting]).to be false diff --git a/spec/controllers/api/v1/accounts/statuses_controller_spec.rb b/spec/controllers/api/v1/accounts/statuses_controller_spec.rb index 8b4fd6a5b..c49a77ac3 100644 --- a/spec/controllers/api/v1/accounts/statuses_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/statuses_controller_spec.rb @@ -18,21 +18,37 @@ describe Api::V1::Accounts::StatusesController do expect(response).to have_http_status(:success) expect(response.headers['Link'].links.size).to eq(2) end - end - describe 'GET #index with only media' do - it 'returns http success' do - get :index, params: { account_id: user.account.id, only_media: true } + context 'with only media' do + it 'returns http success' do + get :index, params: { account_id: user.account.id, only_media: true } - expect(response).to have_http_status(:success) + expect(response).to have_http_status(:success) + end end - end - describe 'GET #index with exclude replies' do - it 'returns http success' do - get :index, params: { account_id: user.account.id, exclude_replies: true } + context 'with exclude replies' do + before do + Fabricate(:status, account: user.account, thread: Fabricate(:status)) + end - expect(response).to have_http_status(:success) + it 'returns http success' do + get :index, params: { account_id: user.account.id, exclude_replies: true } + + expect(response).to have_http_status(:success) + end + end + + context 'with only pinned' do + before do + Fabricate(:status_pin, account: user.account, status: Fabricate(:status, account: user.account)) + end + + it 'returns http success' do + get :index, params: { account_id: user.account.id, pinned: true } + + expect(response).to have_http_status(:success) + end end end end diff --git a/spec/controllers/api/v1/accounts_controller_spec.rb b/spec/controllers/api/v1/accounts_controller_spec.rb index c13509e7b..053c53e5a 100644 --- a/spec/controllers/api/v1/accounts_controller_spec.rb +++ b/spec/controllers/api/v1/accounts_controller_spec.rb @@ -18,18 +18,48 @@ RSpec.describe Api::V1::AccountsController, type: :controller do end describe 'POST #follow' do - let(:other_account) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } + let(:other_account) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', locked: locked)).account } before do post :follow, params: { id: other_account.id } end - it 'returns http success' do - expect(response).to have_http_status(:success) + context 'with unlocked account' do + let(:locked) { false } + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'returns JSON with following=true and requested=false' do + json = body_as_json + + expect(json[:following]).to be true + expect(json[:requested]).to be false + end + + it 'creates a following relation between user and target user' do + expect(user.account.following?(other_account)).to be true + end end - it 'creates a following relation between user and target user' do - expect(user.account.following?(other_account)).to be true + context 'with locked account' do + let(:locked) { true } + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'returns JSON with following=false and requested=true' do + json = body_as_json + + expect(json[:following]).to be false + expect(json[:requested]).to be true + end + + it 'creates a follow request relation between user and target user' do + expect(user.account.requested?(other_account)).to be true + end end end @@ -107,6 +137,35 @@ RSpec.describe Api::V1::AccountsController, type: :controller do it 'creates a muting relation' do expect(user.account.muting?(other_account)).to be true end + + it 'mutes notifications' do + expect(user.account.muting_notifications?(other_account)).to be true + end + end + + describe 'POST #mute with notifications set to false' do + let(:other_account) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } + + before do + user.account.follow!(other_account) + post :mute, params: {id: other_account.id, notifications: false } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'does not remove the following relation between user and target user' do + expect(user.account.following?(other_account)).to be true + end + + it 'creates a muting relation' do + expect(user.account.muting?(other_account)).to be true + end + + it 'does not mute notifications' do + expect(user.account.muting_notifications?(other_account)).to be false + end end describe 'POST #unmute' do diff --git a/spec/controllers/api/v1/custom_emojis_controller_spec.rb b/spec/controllers/api/v1/custom_emojis_controller_spec.rb new file mode 100644 index 000000000..9f3522812 --- /dev/null +++ b/spec/controllers/api/v1/custom_emojis_controller_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Api::V1::CustomEmojisController, type: :controller do + render_views + + describe 'GET #index' do + before do + Fabricate(:custom_emoji) + get :index + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/api/v1/favourites_controller_spec.rb b/spec/controllers/api/v1/favourites_controller_spec.rb index 3de045377..46cf70f4d 100644 --- a/spec/controllers/api/v1/favourites_controller_spec.rb +++ b/spec/controllers/api/v1/favourites_controller_spec.rb @@ -70,8 +70,7 @@ RSpec.describe Api::V1::FavouritesController, type: :controller do it 'does not add pagination headers if not necessary' do get :index - expect(response.headers['Link'].find_link(['rel', 'next'])).to eq nil - expect(response.headers['Link'].find_link(['rel', 'prev'])).to eq nil + expect(response.headers['Link']).to eq nil end end end diff --git a/spec/controllers/api/v1/follows_controller_spec.rb b/spec/controllers/api/v1/follows_controller_spec.rb index b5e1d16dd..ea9e76d68 100644 --- a/spec/controllers/api/v1/follows_controller_spec.rb +++ b/spec/controllers/api/v1/follows_controller_spec.rb @@ -42,5 +42,10 @@ RSpec.describe Api::V1::FollowsController, type: :controller do it 'subscribes to remote hub' do expect(a_request(:post, "https://quitter.no/main/push/hub")).to have_been_made end + + it 'returns http success if already following, too' do + post :create, params: { uri: 'gargron@quitter.no' } + expect(response).to have_http_status(:success) + end end end diff --git a/spec/controllers/api/v1/media_controller_spec.rb b/spec/controllers/api/v1/media_controller_spec.rb index 6bad3f05d..baa22d7e4 100644 --- a/spec/controllers/api/v1/media_controller_spec.rb +++ b/spec/controllers/api/v1/media_controller_spec.rb @@ -53,7 +53,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do end it 'returns media ID in JSON' do - expect(body_as_json[:id]).to eq MediaAttachment.first.id + expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s end end @@ -75,7 +75,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do end it 'returns media ID in JSON' do - expect(body_as_json[:id]).to eq MediaAttachment.first.id + expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s end end @@ -97,7 +97,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do end xit 'returns media ID in JSON' do - expect(body_as_json[:id]).to eq MediaAttachment.first.id + expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s end end end diff --git a/spec/controllers/api/v1/mutes_controller_spec.rb b/spec/controllers/api/v1/mutes_controller_spec.rb index 3e6fa887b..7387b9d2d 100644 --- a/spec/controllers/api/v1/mutes_controller_spec.rb +++ b/spec/controllers/api/v1/mutes_controller_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Api::V1::MutesController, type: :controller do let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'follow') } before do - Fabricate(:mute, account: user.account) + Fabricate(:mute, account: user.account, hide_notifications: false) allow(controller).to receive(:doorkeeper_token) { token } end @@ -18,4 +18,24 @@ RSpec.describe Api::V1::MutesController, type: :controller do expect(response).to have_http_status(:success) end end + + describe 'GET #details' do + before do + get :details, params: { limit: 1 } + end + + let(:mutes) { JSON.parse(response.body) } + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'returns one mute' do + expect(mutes.size).to be(1) + end + + it 'returns whether the mute hides notifications' do + expect(mutes.first["hide_notifications"]).to be(false) + end + end end diff --git a/spec/controllers/api/v1/statuses/favourites_controller_spec.rb b/spec/controllers/api/v1/statuses/favourites_controller_spec.rb index 2a029230d..aba7cd458 100644 --- a/spec/controllers/api/v1/statuses/favourites_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/favourites_controller_spec.rb @@ -36,7 +36,7 @@ describe Api::V1::Statuses::FavouritesController do it 'return json with updated attributes' do hash_body = body_as_json - expect(hash_body[:id]).to eq status.id + expect(hash_body[:id]).to eq status.id.to_s expect(hash_body[:favourites_count]).to eq 1 expect(hash_body[:favourited]).to be true end diff --git a/spec/controllers/api/v1/statuses/pins_controller_spec.rb b/spec/controllers/api/v1/statuses/pins_controller_spec.rb new file mode 100644 index 000000000..79005c9de --- /dev/null +++ b/spec/controllers/api/v1/statuses/pins_controller_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Statuses::PinsController do + render_views + + let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) } + let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write', application: app) } + + context 'with an oauth token' do + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'POST #create' do + let(:status) { Fabricate(:status, account: user.account) } + + before do + post :create, params: { status_id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'updates the pinned attribute' do + expect(user.account.pinned?(status)).to be true + end + + it 'return json with updated attributes' do + hash_body = body_as_json + + expect(hash_body[:id]).to eq status.id.to_s + expect(hash_body[:pinned]).to be true + end + end + + describe 'POST #destroy' do + let(:status) { Fabricate(:status, account: user.account) } + + before do + Fabricate(:status_pin, status: status, account: user.account) + post :destroy, params: { status_id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'updates the pinned attribute' do + expect(user.account.pinned?(status)).to be false + end + end + end +end diff --git a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb index d6d36c1b2..7417ff672 100644 --- a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb @@ -36,7 +36,7 @@ describe Api::V1::Statuses::ReblogsController do it 'return json with updated attributes' do hash_body = body_as_json - expect(hash_body[:reblog][:id]).to eq status.id + expect(hash_body[:reblog][:id]).to eq status.id.to_s expect(hash_body[:reblog][:reblogs_count]).to eq 1 expect(hash_body[:reblog][:reblogged]).to be true end diff --git a/spec/controllers/auth/confirmations_controller_spec.rb b/spec/controllers/auth/confirmations_controller_spec.rb index cf7f91e52..2ec36c060 100644 --- a/spec/controllers/auth/confirmations_controller_spec.rb +++ b/spec/controllers/auth/confirmations_controller_spec.rb @@ -10,4 +10,22 @@ describe Auth::ConfirmationsController, type: :controller do expect(response).to have_http_status(:success) end end + + describe 'GET #show' do + let!(:user) { Fabricate(:user, confirmation_token: 'foobar', confirmed_at: nil) } + + before do + allow(BootstrapTimelineWorker).to receive(:perform_async) + @request.env['devise.mapping'] = Devise.mappings[:user] + get :show, params: { confirmation_token: 'foobar' } + end + + it 'redirects to login' do + expect(response).to redirect_to(new_user_session_path) + end + + it 'queues up bootstrapping of home timeline' do + expect(BootstrapTimelineWorker).to have_received(:perform_async).with(user.account_id) + end + end end diff --git a/spec/controllers/auth/passwords_controller_spec.rb b/spec/controllers/auth/passwords_controller_spec.rb index 60b225efa..992d2e29d 100644 --- a/spec/controllers/auth/passwords_controller_spec.rb +++ b/spec/controllers/auth/passwords_controller_spec.rb @@ -3,6 +3,8 @@ require 'rails_helper' describe Auth::PasswordsController, type: :controller do + include Devise::Test::ControllerHelpers + describe 'GET #new' do it 'returns http success' do @request.env['devise.mapping'] = Devise.mappings[:user] @@ -10,4 +12,27 @@ describe Auth::PasswordsController, type: :controller do expect(response).to have_http_status(:success) end end + + describe 'GET #edit' do + let(:user) { Fabricate(:user) } + + before do + request.env['devise.mapping'] = Devise.mappings[:user] + @token = user.send_reset_password_instructions + end + + context 'with valid reset_password_token' do + it 'returns http success' do + get :edit, params: { reset_password_token: @token } + expect(response).to have_http_status(:success) + end + end + + context 'with invalid reset_password_token' do + it 'redirects to #new' do + get :edit, params: { reset_password_token: 'some_invalid_value' } + expect(response).to redirect_to subject.new_password_path(subject.send(:resource_name)) + end + end + end end diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index 06fdbaabc..88f0a4734 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -28,7 +28,7 @@ RSpec.describe Auth::SessionsController, type: :controller do sign_in(user, scope: :user) delete :destroy - expect(response).to redirect_to(root_path) + expect(response).to redirect_to(new_user_session_path) end end @@ -38,7 +38,7 @@ RSpec.describe Auth::SessionsController, type: :controller do sign_in(user, scope: :user) delete :destroy - expect(response).to redirect_to(root_path) + expect(response).to redirect_to(new_user_session_path) end end end diff --git a/spec/controllers/concerns/account_controller_concern_spec.rb b/spec/controllers/concerns/account_controller_concern_spec.rb index bdc181edc..ae46f9ba6 100644 --- a/spec/controllers/concerns/account_controller_concern_spec.rb +++ b/spec/controllers/concerns/account_controller_concern_spec.rb @@ -33,7 +33,7 @@ describe ApplicationController, type: :controller do it 'sets link headers' do account = Fabricate(:account, username: 'username') get 'success', params: { account_username: 'username' } - expect(response.headers['Link'].to_s).to eq '<http://test.host/.well-known/webfinger?resource=acct%3Ausername%40cb6e6126.ngrok.io>; rel="lrdd"; type="application/xrd+xml", <http://test.host/users/username.atom>; rel="alternate"; type="application/atom+xml"' + expect(response.headers['Link'].to_s).to eq '<http://test.host/.well-known/webfinger?resource=acct%3Ausername%40cb6e6126.ngrok.io>; rel="lrdd"; type="application/xrd+xml", <http://test.host/users/username.atom>; rel="alternate"; type="application/atom+xml", <https://cb6e6126.ngrok.io/users/username>; rel="alternate"; type="application/activity+json"' end it 'returns http success' do diff --git a/spec/controllers/concerns/signature_verification_spec.rb b/spec/controllers/concerns/signature_verification_spec.rb index b371795ab..64648621e 100644 --- a/spec/controllers/concerns/signature_verification_spec.rb +++ b/spec/controllers/concerns/signature_verification_spec.rb @@ -16,7 +16,7 @@ describe ApplicationController, type: :controller do end before do - routes.draw { get 'success' => 'anonymous#success' } + routes.draw { match via: [:get, :post], 'success' => 'anonymous#success' } end context 'without signature header' do @@ -40,34 +40,74 @@ describe ApplicationController, type: :controller do context 'with signature header' do let!(:author) { Fabricate(:account) } - before do - get :success + context 'without body' do + before do + get :success - fake_request = Request.new(:get, request.url) - fake_request.on_behalf_of(author) + fake_request = Request.new(:get, request.url) + fake_request.on_behalf_of(author) - request.headers.merge!(fake_request.headers) - end + request.headers.merge!(fake_request.headers) + end - describe '#signed_request?' do - it 'returns true' do - expect(controller.signed_request?).to be true + describe '#signed_request?' do + it 'returns true' do + expect(controller.signed_request?).to be true + end + end + + describe '#signed_request_account' do + it 'returns an account' do + expect(controller.signed_request_account).to eq author + end + + it 'returns nil when path does not match' do + request.path = '/alternative-path' + expect(controller.signed_request_account).to be_nil + end + + it 'returns nil when method does not match' do + post :success + expect(controller.signed_request_account).to be_nil + end end end - describe '#signed_request_account' do - it 'returns an account' do - expect(controller.signed_request_account).to eq author + context 'with body' do + before do + post :success, body: 'Hello world' + + fake_request = Request.new(:post, request.url, body: 'Hello world') + fake_request.on_behalf_of(author) + + request.headers.merge!(fake_request.headers) end - it 'returns nil when path does not match' do - request.path = '/alternative-path' - expect(controller.signed_request_account).to be_nil + describe '#signed_request?' do + it 'returns true' do + expect(controller.signed_request?).to be true + end end - it 'returns nil when method does not match' do - post :success - expect(controller.signed_request_account).to be_nil + describe '#signed_request_account' do + it 'returns an account' do + expect(controller.signed_request_account).to eq author + end + + it 'returns nil when path does not match' do + request.path = '/alternative-path' + expect(controller.signed_request_account).to be_nil + end + + it 'returns nil when method does not match' do + get :success + expect(controller.signed_request_account).to be_nil + end + + it 'returns nil when body has been tampered' do + request.headers['RAW_POST_DATA'] = 'doo doo doo' + expect(controller.signed_request_account).to be_nil + end end end end diff --git a/spec/controllers/home_controller_spec.rb b/spec/controllers/home_controller_spec.rb index d44d720b1..1077a7288 100644 --- a/spec/controllers/home_controller_spec.rb +++ b/spec/controllers/home_controller_spec.rb @@ -6,6 +6,7 @@ RSpec.describe HomeController, type: :controller do describe 'GET #index' do context 'when not signed in' do it 'redirects to about page' do + @request.path = '/' get :index expect(response).to redirect_to(about_path) end @@ -13,6 +14,7 @@ RSpec.describe HomeController, type: :controller do context 'when signed in' do let(:user) { Fabricate(:user) } + subject do sign_in(user) get :index diff --git a/spec/controllers/remote_follow_controller_spec.rb b/spec/controllers/remote_follow_controller_spec.rb index 915c86f8e..86b1eb8d0 100644 --- a/spec/controllers/remote_follow_controller_spec.rb +++ b/spec/controllers/remote_follow_controller_spec.rb @@ -87,6 +87,14 @@ describe RemoteFollowController do expect(response).to render_template(:new) expect(response.body).to include(I18n.t('remote_follow.missing_resource')) end + + it 'renders new when occur HTTP::ConnectionError' do + allow(Goldfinger).to receive(:finger).with('acct:user@unknown').and_raise(HTTP::ConnectionError) + post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@unknown' } } + + expect(response).to render_template(:new) + expect(response.body).to include(I18n.t('remote_follow.missing_resource')) + end end end diff --git a/spec/controllers/settings/applications_controller_spec.rb b/spec/controllers/settings/applications_controller_spec.rb new file mode 100644 index 000000000..ca66f8d23 --- /dev/null +++ b/spec/controllers/settings/applications_controller_spec.rb @@ -0,0 +1,188 @@ +require 'rails_helper' + +describe Settings::ApplicationsController do + render_views + + let!(:user) { Fabricate(:user) } + let!(:app) { Fabricate(:application, owner: user) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + let!(:other_app) { Fabricate(:application) } + + it 'shows apps' do + get :index + expect(response).to have_http_status(:success) + expect(assigns(:applications)).to include(app) + expect(assigns(:applications)).to_not include(other_app) + end + end + + + describe 'GET #show' do + it 'returns http success' do + get :show, params: { id: app.id } + expect(response).to have_http_status(:success) + expect(assigns[:application]).to eql(app) + end + + it 'returns 404 if you dont own app' do + app.update!(owner: nil) + + get :show, params: { id: app.id } + expect(response.status).to eq 404 + end + end + + describe 'GET #new' do + it 'works' do + get :new + expect(response).to have_http_status(:success) + end + end + + describe 'POST #create' do + context 'success (passed scopes as a String)' do + def call_create + post :create, params: { + doorkeeper_application: { + name: 'My New App', + redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', + website: 'http://google.com', + scopes: 'read write follow' + } + } + response + end + + it 'creates an entry in the database' do + expect { call_create }.to change(Doorkeeper::Application, :count) + end + + it 'redirects back to applications page' do + expect(call_create).to redirect_to(settings_applications_path) + end + end + + context 'success (passed scopes as an Array)' do + def call_create + post :create, params: { + doorkeeper_application: { + name: 'My New App', + redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', + website: 'http://google.com', + scopes: [ 'read', 'write', 'follow' ] + } + } + response + end + + it 'creates an entry in the database' do + expect { call_create }.to change(Doorkeeper::Application, :count) + end + + it 'redirects back to applications page' do + expect(call_create).to redirect_to(settings_applications_path) + end + end + + context 'failure' do + before do + post :create, params: { + doorkeeper_application: { + name: '', + redirect_uri: '', + website: '', + scopes: [] + } + } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'renders form again' do + expect(response).to render_template(:new) + end + end + end + + describe 'PATCH #update' do + context 'success' do + let(:opts) { + { + website: 'https://foo.bar/' + } + } + + def call_update + patch :update, params: { + id: app.id, + doorkeeper_application: opts + } + response + end + + it 'updates existing application' do + call_update + expect(app.reload.website).to eql(opts[:website]) + end + + it 'redirects back to applications page' do + expect(call_update).to redirect_to(settings_applications_path) + end + end + + context 'failure' do + before do + patch :update, params: { + id: app.id, + doorkeeper_application: { + name: '', + redirect_uri: '', + website: '', + scopes: [] + } + } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'renders form again' do + expect(response).to render_template(:show) + end + end + end + + describe 'destroy' do + before do + post :destroy, params: { id: app.id } + end + + it 'redirects back to applications page' do + expect(response).to redirect_to(settings_applications_path) + end + + it 'removes the app' do + expect(Doorkeeper::Application.find_by(id: app.id)).to be_nil + end + end + + describe 'regenerate' do + let(:token) { user.token_for_app(app) } + before do + expect(token).to_not be_nil + post :regenerate, params: { id: app.id } + end + + it 'should create new token' do + expect(user.token_for_app(app)).to_not eql(token) + end + end +end diff --git a/spec/controllers/settings/profiles_controller_spec.rb b/spec/controllers/settings/profiles_controller_spec.rb index e502dbda7..ee3315be6 100644 --- a/spec/controllers/settings/profiles_controller_spec.rb +++ b/spec/controllers/settings/profiles_controller_spec.rb @@ -17,11 +17,13 @@ RSpec.describe Settings::ProfilesController, type: :controller do describe 'PUT #update' do it 'updates the user profile' do + allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async) account = Fabricate(:account, user: @user, display_name: 'Old name') put :update, params: { account: { display_name: 'New name' } } expect(account.reload.display_name).to eq 'New name' expect(response).to redirect_to(settings_profile_path) + expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id) end end end diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb index 88d365624..95fb4d594 100644 --- a/spec/controllers/statuses_controller_spec.rb +++ b/spec/controllers/statuses_controller_spec.rb @@ -30,6 +30,18 @@ describe StatusesController do end end + context 'status is a reblog' do + it 'redirects to the original status' do + original_account = Fabricate(:account, domain: 'example.com') + original_status = Fabricate(:status, account: original_account, uri: 'tag:example.com,2017:foo', url: 'https://example.com/123') + status = Fabricate(:status, reblog: original_status) + + get :show, params: { account_username: status.account.username, id: status.id } + + expect(response).to redirect_to(original_status.url) + end + end + context 'account is not suspended and status is permitted' do it 'assigns @account' do status = Fabricate(:status) diff --git a/spec/controllers/stream_entries_controller_spec.rb b/spec/controllers/stream_entries_controller_spec.rb index 2cc428e0c..f81e2be7b 100644 --- a/spec/controllers/stream_entries_controller_spec.rb +++ b/spec/controllers/stream_entries_controller_spec.rb @@ -21,7 +21,7 @@ RSpec.describe StreamEntriesController, type: :controller do get route, params: { account_username: alice.username, id: status.stream_entry.id } - expect(response.headers['Link'].to_s).to eq "<http://test.host/users/alice/updates/#{status.stream_entry.id}.atom>; rel=\"alternate\"; type=\"application/atom+xml\"" + expect(response.headers['Link'].to_s).to eq "<http://test.host/users/alice/updates/#{status.stream_entry.id}.atom>; rel=\"alternate\"; type=\"application/atom+xml\", <https://cb6e6126.ngrok.io/users/alice/statuses/#{status.id}>; rel=\"alternate\"; type=\"application/activity+json\"" end end @@ -88,14 +88,12 @@ RSpec.describe StreamEntriesController, type: :controller do describe 'GET #embed' do include_examples 'before_action', :embed - it 'returns embedded view of status' do + it 'redirects to new embed page' do status = Fabricate(:status) get :embed, params: { account_username: status.account.username, id: status.stream_entry.id } - expect(response).to have_http_status(:success) - expect(response.headers['X-Frame-Options']).to eq 'ALLOWALL' - expect(response).to render_template(layout: 'embedded') + expect(response).to redirect_to(embed_short_account_status_url(status.account, status)) end end end |