diff options
author | kibigo! <marrus-sh@users.noreply.github.com> | 2017-07-15 14:33:15 -0700 |
---|---|---|
committer | kibigo! <marrus-sh@users.noreply.github.com> | 2017-07-15 14:33:15 -0700 |
commit | 09cfc079b0958c42fe619e2d88c3f9fd1d7c7900 (patch) | |
tree | 156de790a5bec0fdf050e392bee8a64b220d3a9d /spec/controllers | |
parent | 08d021916db9e350259b925d7e562aa13ba37422 (diff) | |
parent | 695439775eacea081c7257aabab39d0ec6b492dc (diff) |
Merge upstream (#81)
Diffstat (limited to 'spec/controllers')
8 files changed, 175 insertions, 320 deletions
diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb index 447e2dd53..d61c8c9bd 100644 --- a/spec/controllers/accounts_controller_spec.rb +++ b/spec/controllers/accounts_controller_spec.rb @@ -38,7 +38,7 @@ RSpec.describe AccountsController, type: :controller do context 'activitystreams2' do before do - get :show, params: { username: alice.username }, format: 'activitystreams2' + get :show, params: { username: alice.username }, format: 'json' end it 'assigns @account' do diff --git a/spec/controllers/api/activitypub/activities_controller_spec.rb b/spec/controllers/api/activitypub/activities_controller_spec.rb deleted file mode 100644 index 07df28ac2..000000000 --- a/spec/controllers/api/activitypub/activities_controller_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::ActivityPub::ActivitiesController, type: :controller do - render_views - - let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) } - - describe 'GET #show' do - describe 'normal status' do - public_status = nil - - before do - public_status = Fabricate(:status, account: user.account, text: 'Hello world', visibility: :public) - - @request.env['HTTP_ACCEPT'] = 'application/activity+json' - get :show_status, params: { id: public_status.id } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'sets Content-Type header to AS2' do - expect(response.header['Content-Type']).to include 'application/activity+json' - end - - it 'returns http success' do - json_data = JSON.parse(response.body) - expect(json_data).to include('@context' => 'https://www.w3.org/ns/activitystreams') - expect(json_data).to include('type' => 'Create') - expect(json_data).to include('id' => @request.url) - expect(json_data).to include('type' => 'Create') - expect(json_data).to include('object' => api_activitypub_note_url(public_status)) - expect(json_data).to include('url' => TagManager.instance.url_for(public_status)) - end - end - - describe 'reblog' do - original = nil - reblog = nil - - before do - original = Fabricate(:status, account: user.account, text: 'Hello world', visibility: :public) - reblog = Fabricate(:status, account: user.account, reblog_of_id: original.id, visibility: :public) - - @request.env['HTTP_ACCEPT'] = 'application/activity+json' - get :show_status, params: { id: reblog.id } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'sets Content-Type header to AS2' do - expect(response.header['Content-Type']).to include 'application/activity+json' - end - - it 'returns http success' do - json_data = JSON.parse(response.body) - expect(json_data).to include('@context' => 'https://www.w3.org/ns/activitystreams') - expect(json_data).to include('type' => 'Announce') - expect(json_data).to include('id' => @request.url) - expect(json_data).to include('type' => 'Announce') - expect(json_data).to include('object' => api_activitypub_status_url(original)) - expect(json_data).to include('url' => TagManager.instance.url_for(reblog)) - end - end - end -end diff --git a/spec/controllers/api/activitypub/notes_controller_spec.rb b/spec/controllers/api/activitypub/notes_controller_spec.rb deleted file mode 100644 index a0f05dc65..000000000 --- a/spec/controllers/api/activitypub/notes_controller_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::ActivityPub::NotesController, type: :controller do - render_views - - let(:user_alice) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) } - let(:user_bob) { Fabricate(:user, account: Fabricate(:account, username: 'bob')) } - - describe 'GET #show' do - describe 'normal status' do - public_status = nil - - before do - public_status = Fabricate(:status, account: user_alice.account, text: 'Hello world', visibility: :public) - - @request.env['HTTP_ACCEPT'] = 'application/activity+json' - get :show, params: { id: public_status.id } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'sets Content-Type header to AS2' do - expect(response.header['Content-Type']).to include 'application/activity+json' - end - - it 'returns http success' do - json_data = JSON.parse(response.body) - expect(json_data).to include('@context' => 'https://www.w3.org/ns/activitystreams') - expect(json_data).to include('type' => 'Note') - expect(json_data).to include('id' => @request.url) - expect(json_data).to include('name' => 'Hello world') - expect(json_data).to include('content' => 'Hello world') - expect(json_data).to include('published') - expect(json_data).to include('url' => TagManager.instance.url_for(public_status)) - end - end - - describe 'reply' do - original = nil - reply = nil - - before do - original = Fabricate(:status, account: user_alice.account, text: 'Hello world', visibility: :public) - reply = Fabricate(:status, account: user_bob.account, text: 'Hello world', in_reply_to_id: original.id, visibility: :public) - - @request.env['HTTP_ACCEPT'] = 'application/activity+json' - get :show, params: { id: reply.id } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'sets Content-Type header to AS2' do - expect(response.header['Content-Type']).to include 'application/activity+json' - end - - it 'returns http success' do - json_data = JSON.parse(response.body) - expect(json_data).to include('@context' => 'https://www.w3.org/ns/activitystreams') - expect(json_data).to include('type' => 'Note') - expect(json_data).to include('id' => @request.url) - expect(json_data).to include('name' => 'Hello world') - expect(json_data).to include('content' => 'Hello world') - expect(json_data).to include('published') - expect(json_data).to include('url' => TagManager.instance.url_for(reply)) - expect(json_data).to include('inReplyTo' => api_activitypub_note_url(original)) - end - end - end -end diff --git a/spec/controllers/api/activitypub/outbox_controller_spec.rb b/spec/controllers/api/activitypub/outbox_controller_spec.rb deleted file mode 100644 index 049cf451d..000000000 --- a/spec/controllers/api/activitypub/outbox_controller_spec.rb +++ /dev/null @@ -1,156 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::ActivityPub::OutboxController, type: :controller do - render_views - - let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) } - - describe 'GET #show' do - before do - @request.headers['ACCEPT'] = 'application/activity+json' - end - - describe 'collection with small number of statuses' do - public_status = nil - - before do - public_status = Fabricate(:status, account: user.account, text: 'Hello world', visibility: :public) - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :private) - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :unlisted) - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :direct) - - get :show, params: { id: user.account.id } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'sets Content-Type header to AS2' do - expect(response.header['Content-Type']).to include 'application/activity+json' - end - - it 'returns AS2 JSON body' do - json_data = JSON.parse(response.body) - expect(json_data).to include('@context' => 'https://www.w3.org/ns/activitystreams') - expect(json_data).to include('id' => @request.url) - expect(json_data).to include('type' => 'OrderedCollection') - expect(json_data).to include('totalItems' => 1) - expect(json_data).to include('current') - expect(json_data).to include('first') - expect(json_data).to include('last') - end - end - - describe 'collection with large number of statuses' do - before do - 30.times do - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :public) - end - - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :private) - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :unlisted) - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :direct) - - get :show, params: { id: user.account.id } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'sets Content-Type header to AS2' do - expect(response.header['Content-Type']).to include 'application/activity+json' - end - - it 'returns AS2 JSON body' do - json_data = JSON.parse(response.body) - expect(json_data).to include('@context' => 'https://www.w3.org/ns/activitystreams') - expect(json_data).to include('id' => @request.url) - expect(json_data).to include('type' => 'OrderedCollection') - expect(json_data).to include('totalItems' => 30) - expect(json_data).to include('current') - expect(json_data).to include('first') - expect(json_data).to include('last') - end - end - - describe 'page with small number of statuses' do - statuses = [] - - before do - 5.times do - statuses << Fabricate(:status, account: user.account, text: 'Hello world', visibility: :public) - end - - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :private) - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :unlisted) - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :direct) - - get :show, params: { id: user.account.id, max_id: statuses.last.id + 1 } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'sets Content-Type header to AS2' do - expect(response.header['Content-Type']).to include 'application/activity+json' - end - - it 'returns AS2 JSON body' do - json_data = JSON.parse(response.body) - expect(json_data).to include('@context' => 'https://www.w3.org/ns/activitystreams') - expect(json_data).to include('id' => @request.url) - expect(json_data).to include('type' => 'OrderedCollectionPage') - expect(json_data).to include('partOf') - expect(json_data).to include('items') - expect(json_data['items'].length).to eq(5) - expect(json_data).to include('prev') - expect(json_data).to include('next') - expect(json_data).to include('current') - expect(json_data).to include('first') - expect(json_data).to include('last') - end - end - - describe 'page with large number of statuses' do - statuses = [] - - before do - 30.times do - statuses << Fabricate(:status, account: user.account, text: 'Hello world', visibility: :public) - end - - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :private) - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :unlisted) - Fabricate(:status, account: user.account, text: 'Hello world', visibility: :direct) - - get :show, params: { id: user.account.id, max_id: statuses.last.id + 1 } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'sets Content-Type header to AS2' do - expect(response.header['Content-Type']).to include 'application/activity+json' - end - - it 'returns AS2 JSON body' do - json_data = JSON.parse(response.body) - expect(json_data).to include('@context' => 'https://www.w3.org/ns/activitystreams') - expect(json_data).to include('id' => @request.url) - expect(json_data).to include('type' => 'OrderedCollectionPage') - expect(json_data).to include('partOf') - expect(json_data).to include('items') - expect(json_data['items'].length).to eq(20) - expect(json_data).to include('prev') - expect(json_data).to include('next') - expect(json_data).to include('current') - expect(json_data).to include('first') - expect(json_data).to include('last') - end - end - end -end diff --git a/spec/controllers/api/push_controller_spec.rb b/spec/controllers/api/push_controller_spec.rb index 18bfa70e5..647698bd1 100644 --- a/spec/controllers/api/push_controller_spec.rb +++ b/spec/controllers/api/push_controller_spec.rb @@ -21,6 +21,7 @@ RSpec.describe Api::PushController, type: :controller do 'https://callback.host/api', 'as1234df', '3600', + nil ) expect(response).to have_http_status(:success) end diff --git a/spec/controllers/api/web/push_subscriptions_controller_spec.rb b/spec/controllers/api/web/push_subscriptions_controller_spec.rb new file mode 100644 index 000000000..871176a07 --- /dev/null +++ b/spec/controllers/api/web/push_subscriptions_controller_spec.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::Web::PushSubscriptionsController do + render_views + + let(:user) { Fabricate(:user) } + + let(:create_payload) do + { + data: { + endpoint: 'https://fcm.googleapis.com/fcm/send/fiuH06a27qE:APA91bHnSiGcLwdaxdyqVXNDR9w1NlztsHb6lyt5WDKOC_Z_Q8BlFxQoR8tWFSXUIDdkyw0EdvxTu63iqamSaqVSevW5LfoFwojws8XYDXv_NRRLH6vo2CdgiN4jgHv5VLt2A8ah6lUX', + keys: { + p256dh: 'BEm_a0bdPDhf0SOsrnB2-ategf1hHoCnpXgQsFj5JCkcoMrMt2WHoPfEYOYPzOIs9mZE8ZUaD7VA5vouy0kEkr8=', + auth: 'eH_C8rq2raXqlcBVDa1gLg==', + }, + } + } + end + + let(:alerts_payload) do + { + data: { + alerts: { + follow: true, + favourite: false, + reblog: true, + mention: false, + } + } + } + end + + describe 'POST #create' do + it 'saves push subscriptions' do + sign_in(user) + + stub_request(:post, create_payload[:data][:endpoint]).to_return(status: 200) + + post :create, format: :json, params: create_payload + + user.reload + + push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:data][:endpoint]) + + expect(push_subscription['endpoint']).to eq(create_payload[:data][:endpoint]) + expect(push_subscription['key_p256dh']).to eq(create_payload[:data][:keys][:p256dh]) + expect(push_subscription['key_auth']).to eq(create_payload[:data][:keys][:auth]) + end + + it 'sends welcome notification' do + sign_in(user) + + stub_request(:post, create_payload[:data][:endpoint]).to_return(status: 200) + + post :create, format: :json, params: create_payload + end + end + + describe 'PUT #update' do + it 'changes alert settings' do + sign_in(user) + + stub_request(:post, create_payload[:data][:endpoint]).to_return(status: 200) + + post :create, format: :json, params: create_payload + + alerts_payload[:id] = Web::PushSubscription.find_by(endpoint: create_payload[:data][:endpoint]).id + + put :update, format: :json, params: alerts_payload + + push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:data][:endpoint]) + + expect(push_subscription.data['follow']).to eq(alerts_payload[:data][:follow]) + expect(push_subscription.data['favourite']).to eq(alerts_payload[:data][:favourite]) + expect(push_subscription.data['reblog']).to eq(alerts_payload[:data][:reblog]) + expect(push_subscription.data['mention']).to eq(alerts_payload[:data][:mention]) + end + end +end diff --git a/spec/controllers/concerns/signature_verification_spec.rb b/spec/controllers/concerns/signature_verification_spec.rb new file mode 100644 index 000000000..b371795ab --- /dev/null +++ b/spec/controllers/concerns/signature_verification_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ApplicationController, type: :controller do + controller do + include SignatureVerification + + def success + head 200 + end + + def alternative_success + head 200 + end + end + + before do + routes.draw { get 'success' => 'anonymous#success' } + end + + context 'without signature header' do + before do + get :success + end + + describe '#signed_request?' do + it 'returns false' do + expect(controller.signed_request?).to be false + end + end + + describe '#signed_request_account' do + it 'returns nil' do + expect(controller.signed_request_account).to be_nil + end + end + end + + context 'with signature header' do + let!(:author) { Fabricate(:account) } + + before do + get :success + + fake_request = Request.new(:get, request.url) + fake_request.on_behalf_of(author) + + request.headers.merge!(fake_request.headers) + end + + 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 +end diff --git a/spec/controllers/well_known/webfinger_controller_spec.rb b/spec/controllers/well_known/webfinger_controller_spec.rb index 3699efb56..466f87c45 100644 --- a/spec/controllers/well_known/webfinger_controller_spec.rb +++ b/spec/controllers/well_known/webfinger_controller_spec.rb @@ -9,7 +9,7 @@ describe WellKnown::WebfingerController, type: :controller do end before do - alice.private_key = <<PEM + alice.private_key = <<-PEM -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDHgPoPJlrfMZrVcuF39UbVssa8r4ObLP3dYl9Y17Mgp5K4mSYD R/Y2ag58tSi6ar2zM3Ze3QYsNfTq0NqN1g89eAu0MbSjWqpOsgntRPJiFuj3hai2 @@ -27,7 +27,7 @@ FTX8IvYBNTbpEttc1VCf/0ccnNpfb0CrFNSPWxRj7t7D -----END RSA PRIVATE KEY----- PEM - alice.public_key = <<PEM + alice.public_key = <<-PEM -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHgPoPJlrfMZrVcuF39UbVssa8 r4ObLP3dYl9Y17Mgp5K4mSYDR/Y2ag58tSi6ar2zM3Ze3QYsNfTq0NqN1g89eAu0 @@ -48,29 +48,23 @@ PEM it 'returns JSON when account can be found' do get :show, params: { resource: alice.to_webfinger_s }, format: :json + json = body_as_json + expect(response).to have_http_status(:success) expect(response.content_type).to eq 'application/jrd+json' - expect(response.body).to eq "{\"subject\":\"acct:alice@cb6e6126.ngrok.io\",\"aliases\":[\"https://cb6e6126.ngrok.io/@alice\",\"https://cb6e6126.ngrok.io/users/alice\"],\"links\":[{\"rel\":\"http://webfinger.net/rel/profile-page\",\"type\":\"text/html\",\"href\":\"https://cb6e6126.ngrok.io/@alice\"},{\"rel\":\"http://schemas.google.com/g/2010#updates-from\",\"type\":\"application/atom+xml\",\"href\":\"https://cb6e6126.ngrok.io/users/alice.atom\"},{\"rel\":\"self\",\"type\":\"application/activity+json\",\"href\":\"https://cb6e6126.ngrok.io/@alice\"},{\"rel\":\"salmon\",\"href\":\"#{api_salmon_url(alice.id)}\"},{\"rel\":\"magic-public-key\",\"href\":\"data:application/magic-public-key,RSA.x4D6DyZa3zGa1XLhd_VG1bLGvK-Dmyz93WJfWNezIKeSuJkmA0f2NmoOfLUoumq9szN2Xt0GLDX06tDajdYPPXgLtDG0o1qqTrIJ7UTyYhbo94Wotl9iJvEwa5IjP1Mn00YJ_KvFrzKCm15PC7up6r-NtHsqoYS8X1KAqcbnptU=.AQAB\"},{\"rel\":\"http://ostatus.org/schema/1.0/subscribe\",\"template\":\"https://cb6e6126.ngrok.io/authorize_follow?acct={uri}\"}]}" + expect(json[:subject]).to eq 'acct:alice@cb6e6126.ngrok.io' + expect(json[:aliases]).to include('https://cb6e6126.ngrok.io/@alice', 'https://cb6e6126.ngrok.io/users/alice') end it 'returns JSON when account can be found' do get :show, params: { resource: alice.to_webfinger_s }, format: :xml + xml = Nokogiri::XML(response.body) + expect(response).to have_http_status(:success) expect(response.content_type).to eq 'application/xrd+xml' - expect(response.body).to eq <<"XML" -<?xml version="1.0"?> -<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"> - <Subject>acct:alice@cb6e6126.ngrok.io</Subject> - <Alias>https://cb6e6126.ngrok.io/@alice</Alias> - <Alias>https://cb6e6126.ngrok.io/users/alice</Alias> - <Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="https://cb6e6126.ngrok.io/@alice"/> - <Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml" href="https://cb6e6126.ngrok.io/users/alice.atom"/> - <Link rel="salmon" href="#{api_salmon_url(alice.id)}"/> - <Link rel="magic-public-key" href="data:application/magic-public-key,RSA.x4D6DyZa3zGa1XLhd_VG1bLGvK-Dmyz93WJfWNezIKeSuJkmA0f2NmoOfLUoumq9szN2Xt0GLDX06tDajdYPPXgLtDG0o1qqTrIJ7UTyYhbo94Wotl9iJvEwa5IjP1Mn00YJ_KvFrzKCm15PC7up6r-NtHsqoYS8X1KAqcbnptU=.AQAB"/> - <Link rel="http://ostatus.org/schema/1.0/subscribe" template="https://cb6e6126.ngrok.io/authorize_follow?acct={uri}"/> -</XRD> -XML + expect(xml.at_xpath('//xmlns:Subject').content).to eq 'acct:alice@cb6e6126.ngrok.io' + expect(xml.xpath('//xmlns:Alias').map(&:content)).to include('https://cb6e6126.ngrok.io/@alice', 'https://cb6e6126.ngrok.io/users/alice') end it 'returns http not found when account cannot be found' do @@ -80,19 +74,22 @@ XML end it 'returns JSON when account can be found with alternate domains' do - Rails.configuration.x.alternate_domains = ["foo.org"] - username, domain = alice.to_webfinger_s.split("@") + Rails.configuration.x.alternate_domains = ['foo.org'] + username, = alice.to_webfinger_s.split('@') get :show, params: { resource: "#{username}@foo.org" }, format: :json + json = body_as_json + expect(response).to have_http_status(:success) expect(response.content_type).to eq 'application/jrd+json' - expect(response.body).to eq "{\"subject\":\"acct:alice@cb6e6126.ngrok.io\",\"aliases\":[\"https://cb6e6126.ngrok.io/@alice\",\"https://cb6e6126.ngrok.io/users/alice\"],\"links\":[{\"rel\":\"http://webfinger.net/rel/profile-page\",\"type\":\"text/html\",\"href\":\"https://cb6e6126.ngrok.io/@alice\"},{\"rel\":\"http://schemas.google.com/g/2010#updates-from\",\"type\":\"application/atom+xml\",\"href\":\"https://cb6e6126.ngrok.io/users/alice.atom\"},{\"rel\":\"self\",\"type\":\"application/activity+json\",\"href\":\"https://cb6e6126.ngrok.io/@alice\"},{\"rel\":\"salmon\",\"href\":\"#{api_salmon_url(alice.id)}\"},{\"rel\":\"magic-public-key\",\"href\":\"data:application/magic-public-key,RSA.x4D6DyZa3zGa1XLhd_VG1bLGvK-Dmyz93WJfWNezIKeSuJkmA0f2NmoOfLUoumq9szN2Xt0GLDX06tDajdYPPXgLtDG0o1qqTrIJ7UTyYhbo94Wotl9iJvEwa5IjP1Mn00YJ_KvFrzKCm15PC7up6r-NtHsqoYS8X1KAqcbnptU=.AQAB\"},{\"rel\":\"http://ostatus.org/schema/1.0/subscribe\",\"template\":\"https://cb6e6126.ngrok.io/authorize_follow?acct={uri}\"}]}" + expect(json[:subject]).to eq 'acct:alice@cb6e6126.ngrok.io' + expect(json[:aliases]).to include('https://cb6e6126.ngrok.io/@alice', 'https://cb6e6126.ngrok.io/users/alice') end it 'returns http not found when account can not be found with alternate domains' do - Rails.configuration.x.alternate_domains = ["foo.org"] - username, domain = alice.to_webfinger_s.split("@") + Rails.configuration.x.alternate_domains = ['foo.org'] + username, = alice.to_webfinger_s.split('@') get :show, params: { resource: "#{username}@bar.org" }, format: :json |