Gab Social. All are welcome.
This commit is contained in:
53
spec/controllers/concerns/account_controller_concern_spec.rb
Normal file
53
spec/controllers/concerns/account_controller_concern_spec.rb
Normal file
@@ -0,0 +1,53 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ApplicationController, type: :controller do
|
||||
controller do
|
||||
include AccountControllerConcern
|
||||
|
||||
def success
|
||||
head 200
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
routes.draw { get 'success' => 'anonymous#success' }
|
||||
end
|
||||
|
||||
context 'when account is suspended' do
|
||||
it 'returns http gone' do
|
||||
account = Fabricate(:account, suspended: true, user: Fabricate(:user))
|
||||
get 'success', params: { account_username: account.username }
|
||||
expect(response).to have_http_status(410)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account is deleted by owner' do
|
||||
it 'returns http gone' do
|
||||
account = Fabricate(:account, suspended: true, user: nil)
|
||||
get 'success', params: { account_username: account.username }
|
||||
expect(response).to have_http_status(410)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account is not suspended' do
|
||||
it 'assigns @account' do
|
||||
account = Fabricate(:account, user: Fabricate(:user))
|
||||
get 'success', params: { account_username: account.username }
|
||||
expect(assigns(:account)).to eq account
|
||||
end
|
||||
|
||||
it 'sets link headers' do
|
||||
account = Fabricate(:account, username: 'username', user: Fabricate(:user))
|
||||
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", <https://cb6e6126.ngrok.io/users/username>; rel="alternate"; type="application/activity+json"'
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
account = Fabricate(:account, user: Fabricate(:user))
|
||||
get 'success', params: { account_username: account.username }
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
26
spec/controllers/concerns/accountable_concern_spec.rb
Normal file
26
spec/controllers/concerns/accountable_concern_spec.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountableConcern do
|
||||
class Hoge
|
||||
include AccountableConcern
|
||||
attr_reader :current_account
|
||||
|
||||
def initialize(current_account)
|
||||
@current_account = current_account
|
||||
end
|
||||
end
|
||||
|
||||
let(:user) { Fabricate(:user, account: Fabricate(:account)) }
|
||||
let(:target) { Fabricate(:user, account: Fabricate(:account)) }
|
||||
let(:hoge) { Hoge.new(user.account) }
|
||||
|
||||
describe '#log_action' do
|
||||
it 'creates Admin::ActionLog' do
|
||||
expect do
|
||||
hoge.log_action(:create, target.account)
|
||||
end.to change { Admin::ActionLog.count }.by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
34
spec/controllers/concerns/export_controller_concern_spec.rb
Normal file
34
spec/controllers/concerns/export_controller_concern_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ApplicationController, type: :controller do
|
||||
controller do
|
||||
include ExportControllerConcern
|
||||
def index
|
||||
send_export_file
|
||||
end
|
||||
|
||||
def export_data
|
||||
@export.account.username
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns a csv of the exported data when signed in' do
|
||||
user = Fabricate(:user)
|
||||
sign_in user
|
||||
get :index, format: :csv
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.content_type).to eq 'text/csv'
|
||||
expect(response.headers['Content-Disposition']).to eq 'attachment; filename="anonymous.csv"'
|
||||
expect(response.body).to eq user.account.username
|
||||
end
|
||||
|
||||
it 'returns unauthorized when not signed in' do
|
||||
get :index, format: :csv
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
end
|
||||
68
spec/controllers/concerns/localized_spec.rb
Normal file
68
spec/controllers/concerns/localized_spec.rb
Normal file
@@ -0,0 +1,68 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ApplicationController, type: :controller do
|
||||
controller do
|
||||
include Localized
|
||||
|
||||
def success
|
||||
head 200
|
||||
end
|
||||
end
|
||||
|
||||
around do |example|
|
||||
current_locale = I18n.locale
|
||||
example.run
|
||||
I18n.locale = current_locale
|
||||
end
|
||||
|
||||
before do
|
||||
routes.draw { get 'success' => 'anonymous#success' }
|
||||
end
|
||||
|
||||
shared_examples 'default locale' do
|
||||
it 'sets available and preferred language' do
|
||||
request.headers['Accept-Language'] = 'ca-ES, fa'
|
||||
get 'success'
|
||||
expect(I18n.locale).to eq :fa
|
||||
end
|
||||
|
||||
it 'sets available and compatible language if none of available languages are preferred' do
|
||||
request.headers['Accept-Language'] = 'fa-IR'
|
||||
get 'success'
|
||||
expect(I18n.locale).to eq :fa
|
||||
end
|
||||
|
||||
it 'sets default locale if none of available languages are compatible' do
|
||||
request.headers['Accept-Language'] = ''
|
||||
get 'success'
|
||||
expect(I18n.locale).to eq :en
|
||||
end
|
||||
end
|
||||
|
||||
context 'user with valid locale has signed in' do
|
||||
it "sets user's locale" do
|
||||
user = Fabricate(:user, locale: :ca)
|
||||
|
||||
sign_in(user)
|
||||
get 'success'
|
||||
|
||||
expect(I18n.locale).to eq :ca
|
||||
end
|
||||
end
|
||||
|
||||
context 'user with invalid locale has signed in' do
|
||||
before do
|
||||
user = Fabricate.build(:user, locale: :invalid)
|
||||
user.save!(validate: false)
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
include_examples 'default locale'
|
||||
end
|
||||
|
||||
context 'user has not signed in' do
|
||||
include_examples 'default locale'
|
||||
end
|
||||
end
|
||||
30
spec/controllers/concerns/obfuscate_filename_spec.rb
Normal file
30
spec/controllers/concerns/obfuscate_filename_spec.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ApplicationController, type: :controller do
|
||||
controller do
|
||||
include ObfuscateFilename
|
||||
|
||||
obfuscate_filename :file
|
||||
|
||||
def file
|
||||
render plain: params[:file]&.original_filename
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
routes.draw { get 'file' => 'anonymous#file' }
|
||||
end
|
||||
|
||||
it 'obfusticates filename if the given parameter is specified' do
|
||||
file = fixture_file_upload('files/imports.txt', 'text/plain')
|
||||
post 'file', params: { file: file }
|
||||
expect(response.body).to end_with '.txt'
|
||||
expect(response.body).not_to include 'imports'
|
||||
end
|
||||
|
||||
it 'does nothing if the given parameter is not specified' do
|
||||
post 'file'
|
||||
end
|
||||
end
|
||||
56
spec/controllers/concerns/rate_limit_headers_spec.rb
Normal file
56
spec/controllers/concerns/rate_limit_headers_spec.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ApplicationController do
|
||||
controller do
|
||||
include RateLimitHeaders
|
||||
|
||||
def show
|
||||
head 200
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
routes.draw { get 'show' => 'anonymous#show' }
|
||||
end
|
||||
|
||||
describe 'rate limiting' do
|
||||
context 'throttling is off' do
|
||||
before do
|
||||
request.env['rack.attack.throttle_data'] = nil
|
||||
end
|
||||
|
||||
it 'does not apply rate limiting' do
|
||||
get 'show'
|
||||
|
||||
expect(response.headers['X-RateLimit-Limit']).to be_nil
|
||||
expect(response.headers['X-RateLimit-Remaining']).to be_nil
|
||||
expect(response.headers['X-RateLimit-Reset']).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'throttling is on' do
|
||||
let(:start_time) { DateTime.new(2017, 1, 1, 12, 0, 0).utc }
|
||||
|
||||
before do
|
||||
request.env['rack.attack.throttle_data'] = { 'throttle_authenticated_api' => { limit: 100, count: 20, period: 10 } }
|
||||
travel_to start_time do
|
||||
get 'show'
|
||||
end
|
||||
end
|
||||
|
||||
it 'applies rate limiting limit header' do
|
||||
expect(response.headers['X-RateLimit-Limit']).to eq '100'
|
||||
end
|
||||
|
||||
it 'applies rate limiting remaining header' do
|
||||
expect(response.headers['X-RateLimit-Remaining']).to eq '80'
|
||||
end
|
||||
|
||||
it 'applies rate limiting reset header' do
|
||||
expect(response.headers['X-RateLimit-Reset']).to eq (start_time + 10.seconds).iso8601(6)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
138
spec/controllers/concerns/signature_verification_spec.rb
Normal file
138
spec/controllers/concerns/signature_verification_spec.rb
Normal file
@@ -0,0 +1,138 @@
|
||||
# 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 { match via: [:get, :post], '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) }
|
||||
|
||||
context 'without body' do
|
||||
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
|
||||
|
||||
context 'with request older than a day' do
|
||||
before do
|
||||
get :success
|
||||
|
||||
fake_request = Request.new(:get, request.url)
|
||||
fake_request.add_headers({ 'Date' => 2.days.ago.utc.httpdate })
|
||||
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 nil' do
|
||||
expect(controller.signed_request_account).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
get :success
|
||||
expect(controller.signed_request_account).to be_nil
|
||||
end
|
||||
|
||||
it 'returns nil when body has been tampered' do
|
||||
post :success, body: 'doo doo doo'
|
||||
expect(controller.signed_request_account).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
91
spec/controllers/concerns/user_tracking_concern_spec.rb
Normal file
91
spec/controllers/concerns/user_tracking_concern_spec.rb
Normal file
@@ -0,0 +1,91 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ApplicationController, type: :controller do
|
||||
controller do
|
||||
include UserTrackingConcern
|
||||
|
||||
def show
|
||||
render plain: 'show'
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
routes.draw { get 'show' => 'anonymous#show' }
|
||||
end
|
||||
|
||||
describe 'when signed in' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
it 'does not track when there is a recent sign in' do
|
||||
user.update(current_sign_in_at: 60.minutes.ago)
|
||||
prior = user.current_sign_in_at
|
||||
sign_in user, scope: :user
|
||||
get :show
|
||||
|
||||
expect(user.reload.current_sign_in_at).to be_within(1.0).of(prior)
|
||||
end
|
||||
|
||||
it 'tracks when sign in is nil' do
|
||||
user.update(current_sign_in_at: nil)
|
||||
sign_in user, scope: :user
|
||||
get :show
|
||||
|
||||
expect_updated_sign_in_at(user)
|
||||
end
|
||||
|
||||
it 'tracks when sign in is older than one day' do
|
||||
user.update(current_sign_in_at: 2.days.ago)
|
||||
sign_in user, scope: :user
|
||||
get :show
|
||||
|
||||
expect_updated_sign_in_at(user)
|
||||
end
|
||||
|
||||
describe 'feed regeneration' do
|
||||
before do
|
||||
alice = Fabricate(:account)
|
||||
bob = Fabricate(:account)
|
||||
|
||||
user.account.follow!(alice)
|
||||
user.account.follow!(bob)
|
||||
|
||||
Fabricate(:status, account: alice, text: 'hello world')
|
||||
Fabricate(:status, account: bob, text: 'yes hello')
|
||||
Fabricate(:status, account: user.account, text: 'test')
|
||||
|
||||
user.update(last_sign_in_at: 'Tue, 04 Jul 2017 14:45:56 UTC +00:00', current_sign_in_at: 'Wed, 05 Jul 2017 22:10:52 UTC +00:00')
|
||||
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
it 'sets a regeneration marker while regenerating' do
|
||||
allow(RegenerationWorker).to receive(:perform_async)
|
||||
get :show
|
||||
|
||||
expect_updated_sign_in_at(user)
|
||||
expect(Redis.current.get("account:#{user.account_id}:regeneration")).to eq 'true'
|
||||
expect(RegenerationWorker).to have_received(:perform_async)
|
||||
end
|
||||
|
||||
it 'sets the regeneration marker to expire' do
|
||||
allow(RegenerationWorker).to receive(:perform_async)
|
||||
get :show
|
||||
expect(Redis.current.ttl("account:#{user.account_id}:regeneration")).to be >= 0
|
||||
end
|
||||
|
||||
it 'regenerates feed when sign in is older than two weeks' do
|
||||
get :show
|
||||
|
||||
expect_updated_sign_in_at(user)
|
||||
expect(Redis.current.zcard(FeedManager.instance.key(:home, user.account_id))).to eq 3
|
||||
expect(Redis.current.get("account:#{user.account_id}:regeneration")).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
def expect_updated_sign_in_at(user)
|
||||
expect(user.reload.current_sign_in_at).to be_within(1.0).of(Time.now.utc)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user