Merge tag 'v2.7.0rc1' into instance_only_statuses
This commit is contained in:
25
spec/controllers/activitypub/collections_controller_spec.rb
Normal file
25
spec/controllers/activitypub/collections_controller_spec.rb
Normal file
@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActivityPub::CollectionsController, type: :controller do
|
||||
describe 'POST #show' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
context 'id is "featured"' do
|
||||
it 'returns 200 with "application/activity+json"' do
|
||||
post :show, params: { id: 'featured', account_username: account.username }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.content_type).to eq 'application/activity+json'
|
||||
end
|
||||
end
|
||||
|
||||
context 'id is not "featured"' do
|
||||
it 'returns 404' do
|
||||
post :show, params: { id: 'hoge', account_username: account.username }
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,7 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActivityPub::InboxesController, type: :controller do
|
||||
describe 'POST #create' do
|
||||
pending
|
||||
context 'if signed_request_account' do
|
||||
it 'returns 202' do
|
||||
allow(controller).to receive(:signed_request_account) do
|
||||
Fabricate(:account)
|
||||
end
|
||||
|
||||
post :create
|
||||
expect(response).to have_http_status(202)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not signed_request_account' do
|
||||
it 'returns 401' do
|
||||
allow(controller).to receive(:signed_request_account) do
|
||||
false
|
||||
end
|
||||
|
||||
post :create
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -24,8 +24,8 @@ RSpec.describe Admin::AccountsController, type: :controller do
|
||||
expect(h[:local]).to eq '1'
|
||||
expect(h[:remote]).to eq '1'
|
||||
expect(h[:by_domain]).to eq 'domain'
|
||||
expect(h[:active]).to eq '1'
|
||||
expect(h[:silenced]).to eq '1'
|
||||
expect(h[:alphabetic]).to eq '1'
|
||||
expect(h[:suspended]).to eq '1'
|
||||
expect(h[:username]).to eq 'username'
|
||||
expect(h[:display_name]).to eq 'display name'
|
||||
@ -39,8 +39,8 @@ RSpec.describe Admin::AccountsController, type: :controller do
|
||||
local: '1',
|
||||
remote: '1',
|
||||
by_domain: 'domain',
|
||||
active: '1',
|
||||
silenced: '1',
|
||||
alphabetic: '1',
|
||||
suspended: '1',
|
||||
username: 'username',
|
||||
display_name: 'display name',
|
||||
@ -191,58 +191,6 @@ RSpec.describe Admin::AccountsController, type: :controller do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #disable' do
|
||||
subject { post :disable, params: { id: account.id } }
|
||||
|
||||
let(:current_user) { Fabricate(:user, admin: current_user_admin) }
|
||||
let(:account) { Fabricate(:account, user: user) }
|
||||
let(:user) { Fabricate(:user, disabled: false, admin: target_user_admin) }
|
||||
|
||||
context 'when user is admin' do
|
||||
let(:current_user_admin) { true }
|
||||
|
||||
context 'when target user is admin' do
|
||||
let(:target_user_admin) { true }
|
||||
|
||||
it 'fails to disable account' do
|
||||
is_expected.to have_http_status :forbidden
|
||||
expect(user.reload).not_to be_disabled
|
||||
end
|
||||
end
|
||||
|
||||
context 'when target user is not admin' do
|
||||
let(:target_user_admin) { false }
|
||||
|
||||
it 'succeeds in disabling account' do
|
||||
is_expected.to redirect_to admin_account_path(account.id)
|
||||
expect(user.reload).to be_disabled
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not admin' do
|
||||
let(:current_user_admin) { false }
|
||||
|
||||
context 'when target user is admin' do
|
||||
let(:target_user_admin) { true }
|
||||
|
||||
it 'fails to disable account' do
|
||||
is_expected.to have_http_status :forbidden
|
||||
expect(user.reload).not_to be_disabled
|
||||
end
|
||||
end
|
||||
|
||||
context 'when target user is not admin' do
|
||||
let(:target_user_admin) { false }
|
||||
|
||||
it 'fails to disable account' do
|
||||
is_expected.to have_http_status :forbidden
|
||||
expect(user.reload).not_to be_disabled
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #redownload' do
|
||||
subject { post :redownload, params: { id: account.id } }
|
||||
|
||||
|
||||
14
spec/controllers/admin/action_logs_controller_spec.rb
Normal file
14
spec/controllers/admin/action_logs_controller_spec.rb
Normal file
@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::ActionLogsController, type: :controller do
|
||||
describe 'GET #index' do
|
||||
it 'returns 200' do
|
||||
sign_in Fabricate(:user, admin: true)
|
||||
get :index, params: { page: 1 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
14
spec/controllers/admin/dashboard_controller_spec.rb
Normal file
14
spec/controllers/admin/dashboard_controller_spec.rb
Normal file
@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::DashboardController, type: :controller do
|
||||
describe 'GET #index' do
|
||||
it 'returns 200' do
|
||||
sign_in Fabricate(:user, admin: true)
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -7,26 +7,6 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
|
||||
sign_in Fabricate(:user, admin: true), scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
around do |example|
|
||||
default_per_page = DomainBlock.default_per_page
|
||||
DomainBlock.paginates_per 1
|
||||
example.run
|
||||
DomainBlock.paginates_per default_per_page
|
||||
end
|
||||
|
||||
it 'renders domain blocks' do
|
||||
2.times { Fabricate(:domain_block) }
|
||||
|
||||
get :index, params: { page: 2 }
|
||||
|
||||
assigned = assigns(:domain_blocks)
|
||||
expect(assigned.count).to eq 1
|
||||
expect(assigned.klass).to be DomainBlock
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #new' do
|
||||
it 'assigns a new domain block' do
|
||||
get :new
|
||||
@ -53,7 +33,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
|
||||
|
||||
expect(DomainBlockWorker).to have_received(:perform_async)
|
||||
expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.created_msg')
|
||||
expect(response).to redirect_to(admin_domain_blocks_path)
|
||||
expect(response).to redirect_to(admin_instances_path(limited: '1'))
|
||||
end
|
||||
|
||||
it 'renders new when failed to save' do
|
||||
@ -76,7 +56,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
|
||||
|
||||
expect(service).to have_received(:call).with(domain_block, true)
|
||||
expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.destroyed_msg')
|
||||
expect(response).to redirect_to(admin_domain_blocks_path)
|
||||
expect(response).to redirect_to(admin_instances_path(limited: '1'))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::InvitesController do
|
||||
@ -40,4 +42,18 @@ describe Admin::InvitesController do
|
||||
expect(invite.reload).to be_expired
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #deactivate_all' do
|
||||
it 'expires all invites, then redirects to admin_invites_path' do
|
||||
invites = Fabricate.times(2, :invite, expires_at: nil)
|
||||
|
||||
post :deactivate_all
|
||||
|
||||
invites.each do |invite|
|
||||
expect(invite.reload).to be_expired
|
||||
end
|
||||
|
||||
expect(response).to redirect_to admin_invites_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -46,73 +46,37 @@ describe Admin::ReportsController do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
describe 'with an unknown outcome' do
|
||||
it 'rejects the change' do
|
||||
report = Fabricate(:report)
|
||||
put :update, params: { id: report, outcome: 'unknown' }
|
||||
describe 'POST #reopen' do
|
||||
it 'reopens the report' do
|
||||
report = Fabricate(:report)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
put :reopen, params: { id: report }
|
||||
expect(response).to redirect_to(admin_report_path(report))
|
||||
report.reload
|
||||
expect(report.action_taken_by_account).to eq nil
|
||||
expect(report.action_taken).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with an outcome of `resolve`' do
|
||||
it 'resolves the report' do
|
||||
report = Fabricate(:report)
|
||||
describe 'POST #assign_to_self' do
|
||||
it 'reopens the report' do
|
||||
report = Fabricate(:report)
|
||||
|
||||
put :update, params: { id: report, outcome: 'resolve' }
|
||||
expect(response).to redirect_to(admin_reports_path)
|
||||
report.reload
|
||||
expect(report.action_taken_by_account).to eq user.account
|
||||
expect(report.action_taken).to eq true
|
||||
end
|
||||
put :assign_to_self, params: { id: report }
|
||||
expect(response).to redirect_to(admin_report_path(report))
|
||||
report.reload
|
||||
expect(report.assigned_account).to eq user.account
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with an outsome of `silence`' do
|
||||
it 'silences the reported account' do
|
||||
report = Fabricate(:report)
|
||||
describe 'POST #unassign' do
|
||||
it 'reopens the report' do
|
||||
report = Fabricate(:report)
|
||||
|
||||
put :update, params: { id: report, outcome: 'silence' }
|
||||
expect(response).to redirect_to(admin_reports_path)
|
||||
report.reload
|
||||
expect(report.action_taken_by_account).to eq user.account
|
||||
expect(report.action_taken).to eq true
|
||||
expect(report.target_account).to be_silenced
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with an outsome of `reopen`' do
|
||||
it 'reopens the report' do
|
||||
report = Fabricate(:report)
|
||||
|
||||
put :update, params: { id: report, outcome: 'reopen' }
|
||||
expect(response).to redirect_to(admin_report_path(report))
|
||||
report.reload
|
||||
expect(report.action_taken_by_account).to eq nil
|
||||
expect(report.action_taken).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with an outsome of `assign_to_self`' do
|
||||
it 'reopens the report' do
|
||||
report = Fabricate(:report)
|
||||
|
||||
put :update, params: { id: report, outcome: 'assign_to_self' }
|
||||
expect(response).to redirect_to(admin_report_path(report))
|
||||
report.reload
|
||||
expect(report.assigned_account).to eq user.account
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with an outsome of `unassign`' do
|
||||
it 'reopens the report' do
|
||||
report = Fabricate(:report)
|
||||
|
||||
put :update, params: { id: report, outcome: 'unassign' }
|
||||
expect(response).to redirect_to(admin_report_path(report))
|
||||
report.reload
|
||||
expect(report.assigned_account).to eq nil
|
||||
end
|
||||
put :unassign, params: { id: report }
|
||||
expect(response).to redirect_to(admin_report_path(report))
|
||||
report.reload
|
||||
expect(report.assigned_account).to eq nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::SilencesController do
|
||||
render_views
|
||||
|
||||
before do
|
||||
sign_in Fabricate(:user, admin: true), scope: :user
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'redirects to admin accounts page' do
|
||||
account = Fabricate(:account, silenced: false)
|
||||
|
||||
post :create, params: { account_id: account.id }
|
||||
|
||||
account.reload
|
||||
expect(account.silenced?).to eq true
|
||||
expect(response).to redirect_to(admin_accounts_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
it 'redirects to admin accounts page' do
|
||||
account = Fabricate(:account, silenced: true)
|
||||
|
||||
delete :destroy, params: { account_id: account.id }
|
||||
|
||||
account.reload
|
||||
expect(account.silenced?).to eq false
|
||||
expect(response).to redirect_to(admin_accounts_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,32 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::SuspensionsController do
|
||||
render_views
|
||||
|
||||
before do
|
||||
sign_in Fabricate(:user, admin: true), scope: :user
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'redirects to admin accounts page' do
|
||||
account = Fabricate(:account, suspended: false)
|
||||
expect(Admin::SuspensionWorker).to receive(:perform_async).with(account.id)
|
||||
|
||||
post :create, params: { account_id: account.id, form_admin_suspension_confirmation: { acct: account.acct } }
|
||||
|
||||
expect(response).to redirect_to(admin_accounts_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
it 'redirects to admin accounts page' do
|
||||
account = Fabricate(:account, suspended: true)
|
||||
|
||||
delete :destroy, params: { account_id: account.id }
|
||||
|
||||
account.reload
|
||||
expect(account.suspended?).to eq false
|
||||
expect(response).to redirect_to(admin_accounts_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
71
spec/controllers/admin/tags_controller_spec.rb
Normal file
71
spec/controllers/admin/tags_controller_spec.rb
Normal file
@ -0,0 +1,71 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::TagsController, type: :controller do
|
||||
render_views
|
||||
|
||||
before do
|
||||
sign_in Fabricate(:user, admin: true)
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
before do
|
||||
account_tag_stat = Fabricate(:tag).account_tag_stat
|
||||
account_tag_stat.update(hidden: hidden, accounts_count: 1)
|
||||
get :index, params: { hidden: hidden }
|
||||
end
|
||||
|
||||
context 'with hidden tags' do
|
||||
let(:hidden) { true }
|
||||
|
||||
it 'returns status 200' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without hidden tags' do
|
||||
let(:hidden) { false }
|
||||
|
||||
it 'returns status 200' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #hide' do
|
||||
let(:tag) { Fabricate(:tag) }
|
||||
|
||||
before do
|
||||
tag.account_tag_stat.update(hidden: false)
|
||||
post :hide, params: { id: tag.id }
|
||||
end
|
||||
|
||||
it 'hides tag' do
|
||||
tag.reload
|
||||
expect(tag).to be_hidden
|
||||
end
|
||||
|
||||
it 'redirects to admin_tags_path' do
|
||||
expect(response).to redirect_to(admin_tags_path(controller.instance_variable_get(:@filter_params)))
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #unhide' do
|
||||
let(:tag) { Fabricate(:tag) }
|
||||
|
||||
before do
|
||||
tag.account_tag_stat.update(hidden: true)
|
||||
post :unhide, params: { id: tag.id }
|
||||
end
|
||||
|
||||
it 'unhides tag' do
|
||||
tag.reload
|
||||
expect(tag).not_to be_hidden
|
||||
end
|
||||
|
||||
it 'redirects to admin_tags_path' do
|
||||
expect(response).to redirect_to(admin_tags_path(controller.instance_variable_get(:@filter_params)))
|
||||
end
|
||||
end
|
||||
end
|
||||
46
spec/controllers/api/v1/accounts/pins_controller_spec.rb
Normal file
46
spec/controllers/api/v1/accounts/pins_controller_spec.rb
Normal file
@ -0,0 +1,46 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::Accounts::PinsController, type: :controller do
|
||||
let(:john) { Fabricate(:user, account: Fabricate(:account, username: 'john')) }
|
||||
let(:kevin) { Fabricate(:user, account: Fabricate(:account, username: 'kevin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: john.id, scopes: 'write:accounts') }
|
||||
|
||||
before do
|
||||
kevin.account.followers << john.account
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
subject { post :create, params: { account_id: kevin.account.id } }
|
||||
|
||||
it 'returns 200' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates account_pin' do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
subject { delete :destroy, params: { account_id: kevin.account.id } }
|
||||
|
||||
before do
|
||||
Fabricate(:account_pin, account: john.account, target_account: kevin.account)
|
||||
end
|
||||
|
||||
it 'returns 200' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'destroys account_pin' do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -19,6 +19,40 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
let(:app) { Fabricate(:application) }
|
||||
let(:token) { Doorkeeper::AccessToken.find_or_create_for(app, nil, 'read write', nil, false) }
|
||||
let(:agreement) { nil }
|
||||
|
||||
before do
|
||||
post :create, params: { username: 'test', password: '12345678', email: 'hello@world.tld', agreement: agreement }
|
||||
end
|
||||
|
||||
context 'given truthy agreement' do
|
||||
let(:agreement) { 'true' }
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns a new access token as JSON' do
|
||||
expect(body_as_json[:access_token]).to_not be_blank
|
||||
end
|
||||
|
||||
it 'creates a user' do
|
||||
user = User.find_by(email: 'hello@world.tld')
|
||||
expect(user).to_not be_nil
|
||||
expect(user.created_by_application_id).to eq app.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'given no agreement' do
|
||||
it 'returns http unprocessable entity' do
|
||||
expect(response).to have_http_status(422)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
let(:scopes) { 'read:accounts' }
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ RSpec.describe Api::V1::ConversationsController, type: :controller do
|
||||
let(:scopes) { 'read:statuses' }
|
||||
|
||||
before do
|
||||
PostStatusService.new.call(other.account, 'Hey @alice', nil, visibility: 'direct')
|
||||
PostStatusService.new.call(other.account, text: 'Hey @alice', visibility: 'direct')
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
|
||||
17
spec/controllers/api/v1/endorsements_controller_spec.rb
Normal file
17
spec/controllers/api/v1/endorsements_controller_spec.rb
Normal file
@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::EndorsementsController, type: :controller do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') }
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns 200' do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::Instances::ActivityController, type: :controller do
|
||||
describe 'GET #show' do
|
||||
it 'returns 200' do
|
||||
get :show
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
context '!Setting.activity_api_enabled' do
|
||||
it 'returns 404' do
|
||||
Setting.activity_api_enabled = false
|
||||
|
||||
get :show
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
21
spec/controllers/api/v1/instances/peers_controller_spec.rb
Normal file
21
spec/controllers/api/v1/instances/peers_controller_spec.rb
Normal file
@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::Instances::PeersController, type: :controller do
|
||||
describe 'GET #index' do
|
||||
it 'returns 200' do
|
||||
get :index
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
context '!Setting.peers_api_enabled' do
|
||||
it 'returns 404' do
|
||||
Setting.peers_api_enabled = false
|
||||
|
||||
get :index
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -50,9 +50,9 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do
|
||||
let(:scopes) { 'read:notifications' }
|
||||
|
||||
before do
|
||||
first_status = PostStatusService.new.call(user.account, 'Test')
|
||||
first_status = PostStatusService.new.call(user.account, text: 'Test')
|
||||
@reblog_of_first_status = ReblogService.new.call(other.account, first_status)
|
||||
mentioning_status = PostStatusService.new.call(other.account, 'Hello @alice')
|
||||
mentioning_status = PostStatusService.new.call(other.account, text: 'Hello @alice')
|
||||
@mention_from_status = mentioning_status.mentions.first
|
||||
@favourite = FavouriteService.new.call(other.account, first_status)
|
||||
@follow = FollowService.new.call(other.account, 'alice')
|
||||
|
||||
17
spec/controllers/api/v1/timelines/direct_controller_spec.rb
Normal file
17
spec/controllers/api/v1/timelines/direct_controller_spec.rb
Normal file
@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::Timelines::DirectController, type: :controller do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') }
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns 200' do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -17,7 +17,7 @@ describe Api::V1::Timelines::HomeController do
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
follow = Fabricate(:follow, account: user.account)
|
||||
PostStatusService.new.call(follow.target_account, 'New status for user home timeline.')
|
||||
PostStatusService.new.call(follow.target_account, text: 'New status for user home timeline.')
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
|
||||
@ -19,7 +19,7 @@ describe Api::V1::Timelines::ListController do
|
||||
before do
|
||||
follow = Fabricate(:follow, account: user.account)
|
||||
list.accounts << follow.target_account
|
||||
PostStatusService.new.call(follow.target_account, 'New status for user home timeline.')
|
||||
PostStatusService.new.call(follow.target_account, text: 'New status for user home timeline.')
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
|
||||
@ -16,7 +16,7 @@ describe Api::V1::Timelines::PublicController do
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
PostStatusService.new.call(user.account, 'New status from user for federated public timeline.')
|
||||
PostStatusService.new.call(user.account, text: 'New status from user for federated public timeline.')
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
@ -29,7 +29,7 @@ describe Api::V1::Timelines::PublicController do
|
||||
|
||||
describe 'GET #show with local only' do
|
||||
before do
|
||||
PostStatusService.new.call(user.account, 'New status from user for local public timeline.')
|
||||
PostStatusService.new.call(user.account, text: 'New status from user for local public timeline.')
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
|
||||
@ -16,7 +16,7 @@ describe Api::V1::Timelines::TagController do
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
PostStatusService.new.call(user.account, 'It is a #test')
|
||||
PostStatusService.new.call(user.account, text: 'It is a #test')
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
|
||||
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
|
||||
39
spec/controllers/remote_interaction_controller_spec.rb
Normal file
39
spec/controllers/remote_interaction_controller_spec.rb
Normal file
@ -0,0 +1,39 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe RemoteInteractionController, type: :controller do
|
||||
render_views
|
||||
|
||||
let(:status) { Fabricate(:status) }
|
||||
|
||||
describe 'GET #new' do
|
||||
it 'returns 200' do
|
||||
get :new, params: { id: status.id }
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
context '@remote_follow is valid' do
|
||||
it 'returns 302' do
|
||||
allow_any_instance_of(RemoteFollow).to receive(:valid?) { true }
|
||||
allow_any_instance_of(RemoteFollow).to receive(:addressable_template) do
|
||||
Addressable::Template.new('https://hoge.com')
|
||||
end
|
||||
|
||||
post :create, params: { id: status.id, remote_follow: { acct: '@hoge' } }
|
||||
expect(response).to have_http_status(302)
|
||||
end
|
||||
end
|
||||
|
||||
context '@remote_follow is invalid' do
|
||||
it 'returns 200' do
|
||||
allow_any_instance_of(RemoteFollow).to receive(:valid?) { false }
|
||||
post :create, params: { id: status.id, remote_follow: { acct: '@hoge' } }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,3 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Settings::ExportsController do
|
||||
@ -28,4 +30,23 @@ describe Settings::ExportsController do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
before do
|
||||
sign_in Fabricate(:user), scope: :user
|
||||
end
|
||||
|
||||
it 'redirects to settings_export_path' do
|
||||
post :create
|
||||
expect(response).to redirect_to(settings_export_path)
|
||||
end
|
||||
|
||||
it 'queues BackupWorker job by 1' do
|
||||
Sidekiq::Testing.fake! do
|
||||
expect do
|
||||
post :create
|
||||
end.to change(BackupWorker.jobs, :size).by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -26,4 +26,26 @@ RSpec.describe Settings::ProfilesController, type: :controller do
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update with new profile image' do
|
||||
it 'updates profile image' do
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
|
||||
account = Fabricate(:account, user: @user, display_name: 'AvatarTest')
|
||||
expect(account.avatar.instance.avatar_file_name).to be_nil
|
||||
|
||||
put :update, params: { account: { avatar: fixture_file_upload('files/avatar.gif', 'image/gif') } }
|
||||
expect(response).to redirect_to(settings_profile_path)
|
||||
expect(account.reload.avatar.instance.avatar_file_name).not_to be_nil
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update with oversized image' do
|
||||
it 'gives the user an error message' do
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
|
||||
account = Fabricate(:account, user: @user, display_name: 'AvatarTest')
|
||||
put :update, params: { account: { avatar: fixture_file_upload('files/4096x4097.png', 'image/png') } }
|
||||
expect(response.body).to include('images are not supported')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -115,14 +115,18 @@ describe StatusesController do
|
||||
end
|
||||
|
||||
it 'assigns @descendant_threads for threads with :next_status key if they are hitting the depth limit' do
|
||||
stub_const 'StatusesController::DESCENDANTS_DEPTH_LIMIT', 1
|
||||
stub_const 'StatusesController::DESCENDANTS_DEPTH_LIMIT', 2
|
||||
status = Fabricate(:status)
|
||||
child = Fabricate(:status, in_reply_to_id: status.id)
|
||||
child0 = Fabricate(:status, in_reply_to_id: status.id)
|
||||
child1 = Fabricate(:status, in_reply_to_id: child0.id)
|
||||
child2 = Fabricate(:status, in_reply_to_id: child0.id)
|
||||
|
||||
get :show, params: { account_username: status.account.username, id: status.id }
|
||||
|
||||
expect(assigns(:descendant_threads)[0][:statuses].pluck(:id)).not_to include child.id
|
||||
expect(assigns(:descendant_threads)[0][:next_status].id).to eq child.id
|
||||
expect(assigns(:descendant_threads)[0][:statuses].pluck(:id)).not_to include child1.id
|
||||
expect(assigns(:descendant_threads)[1][:statuses].pluck(:id)).not_to include child2.id
|
||||
expect(assigns(:descendant_threads)[0][:next_status].id).to eq child1.id
|
||||
expect(assigns(:descendant_threads)[1][:next_status].id).to eq child2.id
|
||||
end
|
||||
|
||||
it 'returns a success' do
|
||||
|
||||
6
spec/fabricators/account_stat_fabricator.rb
Normal file
6
spec/fabricators/account_stat_fabricator.rb
Normal file
@ -0,0 +1,6 @@
|
||||
Fabricator(:account_stat) do
|
||||
account nil
|
||||
statuses_count ""
|
||||
following_count ""
|
||||
followers_count ""
|
||||
end
|
||||
3
spec/fabricators/account_tag_stat_fabricator.rb
Normal file
3
spec/fabricators/account_tag_stat_fabricator.rb
Normal file
@ -0,0 +1,3 @@
|
||||
Fabricator(:account_tag_stat) do
|
||||
accounts_count ""
|
||||
end
|
||||
5
spec/fabricators/account_warning_fabricator.rb
Normal file
5
spec/fabricators/account_warning_fabricator.rb
Normal file
@ -0,0 +1,5 @@
|
||||
Fabricator(:account_warning) do
|
||||
account nil
|
||||
target_account nil
|
||||
text "MyText"
|
||||
end
|
||||
3
spec/fabricators/account_warning_preset_fabricator.rb
Normal file
3
spec/fabricators/account_warning_preset_fabricator.rb
Normal file
@ -0,0 +1,3 @@
|
||||
Fabricator(:account_warning_preset) do
|
||||
text "MyText"
|
||||
end
|
||||
4
spec/fabricators/scheduled_status_fabricator.rb
Normal file
4
spec/fabricators/scheduled_status_fabricator.rb
Normal file
@ -0,0 +1,4 @@
|
||||
Fabricator(:scheduled_status) do
|
||||
account
|
||||
scheduled_at { 20.hours.from_now }
|
||||
end
|
||||
@ -3,4 +3,5 @@ Fabricator(:user) do
|
||||
email { sequence(:email) { |i| "#{i}#{Faker::Internet.email}" } }
|
||||
password "123456789"
|
||||
confirmed_at { Time.zone.now }
|
||||
agreement true
|
||||
end
|
||||
|
||||
BIN
spec/fixtures/files/4096x4097.png
vendored
Normal file
BIN
spec/fixtures/files/4096x4097.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
17
spec/fixtures/requests/windows-1251.txt
vendored
Normal file
17
spec/fixtures/requests/windows-1251.txt
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
HTTP/1.1 200 OK
|
||||
server: nginx
|
||||
date: Wed, 12 Dec 2018 13:14:03 GMT
|
||||
content-type: text/html
|
||||
content-length: 190
|
||||
accept-ranges: bytes
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
|
||||
<title><3E><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD></title>
|
||||
</head>
|
||||
<body>
|
||||
<p><3E><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD></p>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,15 +1,55 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the Admin::AccountModerationNotesHelper. For example:
|
||||
#
|
||||
# describe Admin::AccountModerationNotesHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe Admin::AccountModerationNotesHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
include StreamEntriesHelper
|
||||
|
||||
describe '#admin_account_link_to' do
|
||||
context 'account is nil' do
|
||||
let(:account) { nil }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(helper.admin_account_link_to(account)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'with account' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
it 'calls #link_to' do
|
||||
expect(helper).to receive(:link_to).with(
|
||||
admin_account_path(account.id),
|
||||
class: name_tag_classes(account),
|
||||
title: account.acct
|
||||
)
|
||||
|
||||
helper.admin_account_link_to(account)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#admin_account_inline_link_to' do
|
||||
context 'account is nil' do
|
||||
let(:account) { nil }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(helper.admin_account_inline_link_to(account)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'with account' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
it 'calls #link_to' do
|
||||
expect(helper).to receive(:link_to).with(
|
||||
admin_account_path(account.id),
|
||||
class: name_tag_classes(account, true),
|
||||
title: account.acct
|
||||
)
|
||||
|
||||
helper.admin_account_inline_link_to(account)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -22,11 +22,35 @@ describe JsonLdHelper do
|
||||
end
|
||||
|
||||
describe '#first_of_value' do
|
||||
pending
|
||||
context 'value.is_a?(Array)' do
|
||||
it 'returns value.first' do
|
||||
value = ['a']
|
||||
expect(helper.first_of_value(value)).to be 'a'
|
||||
end
|
||||
end
|
||||
|
||||
context '!value.is_a?(Array)' do
|
||||
it 'returns value' do
|
||||
value = 'a'
|
||||
expect(helper.first_of_value(value)).to be 'a'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#supported_context?' do
|
||||
pending
|
||||
context "!json.nil? && equals_or_includes?(json['@context'], ActivityPub::TagManager::CONTEXT)" do
|
||||
it 'returns true' do
|
||||
json = { '@context' => ActivityPub::TagManager::CONTEXT }.as_json
|
||||
expect(helper.supported_context?(json)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'else' do
|
||||
it 'returns false' do
|
||||
json = nil
|
||||
expect(helper.supported_context?(json)).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#fetch_resource' do
|
||||
|
||||
@ -14,15 +14,72 @@ RSpec.describe ActivityPub::Activity::Block do
|
||||
}.with_indifferent_access
|
||||
end
|
||||
|
||||
describe '#perform' do
|
||||
subject { described_class.new(json, sender) }
|
||||
context 'when the recipient does not follow the sender' do
|
||||
describe '#perform' do
|
||||
subject { described_class.new(json, sender) }
|
||||
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
|
||||
it 'creates a block from sender to recipient' do
|
||||
expect(sender.blocking?(recipient)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the recipient follows the sender' do
|
||||
before do
|
||||
subject.perform
|
||||
recipient.follow!(sender)
|
||||
end
|
||||
|
||||
it 'creates a block from sender to recipient' do
|
||||
expect(sender.blocking?(recipient)).to be true
|
||||
describe '#perform' do
|
||||
subject { described_class.new(json, sender) }
|
||||
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
|
||||
it 'creates a block from sender to recipient' do
|
||||
expect(sender.blocking?(recipient)).to be true
|
||||
end
|
||||
|
||||
it 'ensures recipient is not following sender' do
|
||||
expect(recipient.following?(sender)).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a matching undo has been received first' do
|
||||
let(:undo_json) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: 'bar',
|
||||
type: 'Undo',
|
||||
actor: ActivityPub::TagManager.instance.uri_for(sender),
|
||||
object: json,
|
||||
}.with_indifferent_access
|
||||
end
|
||||
|
||||
before do
|
||||
recipient.follow!(sender)
|
||||
ActivityPub::Activity::Undo.new(undo_json, sender).perform
|
||||
end
|
||||
|
||||
describe '#perform' do
|
||||
subject { described_class.new(json, sender) }
|
||||
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
|
||||
it 'does not create a block from sender to recipient' do
|
||||
expect(sender.blocking?(recipient)).to be false
|
||||
end
|
||||
|
||||
it 'ensures recipient is not following sender' do
|
||||
expect(recipient.following?(sender)).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
52
spec/lib/activitypub/activity/move_spec.rb
Normal file
52
spec/lib/activitypub/activity/move_spec.rb
Normal file
@ -0,0 +1,52 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActivityPub::Activity::Move do
|
||||
let(:follower) { Fabricate(:account) }
|
||||
let(:old_account) { Fabricate(:account) }
|
||||
let(:new_account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
follower.follow!(old_account)
|
||||
|
||||
old_account.update!(uri: 'https://example.org/alice', domain: 'example.org', protocol: :activitypub, inbox_url: 'https://example.org/inbox')
|
||||
new_account.update!(uri: 'https://example.com/alice', domain: 'example.com', protocol: :activitypub, inbox_url: 'https://example.com/inbox', also_known_as: [old_account.uri])
|
||||
|
||||
stub_request(:post, 'https://example.org/inbox').to_return(status: 200)
|
||||
stub_request(:post, 'https://example.com/inbox').to_return(status: 200)
|
||||
|
||||
service_stub = double
|
||||
allow(ActivityPub::FetchRemoteAccountService).to receive(:new).and_return(service_stub)
|
||||
allow(service_stub).to receive(:call).and_return(new_account)
|
||||
end
|
||||
|
||||
let(:json) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: 'foo',
|
||||
type: 'Move',
|
||||
actor: old_account.uri,
|
||||
object: old_account.uri,
|
||||
target: new_account.uri,
|
||||
}.with_indifferent_access
|
||||
end
|
||||
|
||||
describe '#perform' do
|
||||
subject { described_class.new(json, old_account) }
|
||||
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
|
||||
it 'sets moved account on old account' do
|
||||
expect(old_account.reload.moved_to_account_id).to eq new_account.id
|
||||
end
|
||||
|
||||
it 'makes followers unfollow old account' do
|
||||
expect(follower.following?(old_account)).to be false
|
||||
end
|
||||
|
||||
it 'makes followers follow-request the new account' do
|
||||
expect(follower.requested?(new_account)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -108,14 +108,14 @@ RSpec.describe FeedManager do
|
||||
|
||||
it 'returns false for status by followee mentioning another account' do
|
||||
bob.follow!(alice)
|
||||
status = PostStatusService.new.call(alice, 'Hey @jeff')
|
||||
status = PostStatusService.new.call(alice, text: 'Hey @jeff')
|
||||
expect(FeedManager.instance.filter?(:home, status, bob.id)).to be false
|
||||
end
|
||||
|
||||
it 'returns true for status by followee mentioning blocked account' do
|
||||
bob.block!(jeff)
|
||||
bob.follow!(alice)
|
||||
status = PostStatusService.new.call(alice, 'Hey @jeff')
|
||||
status = PostStatusService.new.call(alice, text: 'Hey @jeff')
|
||||
expect(FeedManager.instance.filter?(:home, status, bob.id)).to be true
|
||||
end
|
||||
|
||||
@ -155,7 +155,7 @@ RSpec.describe FeedManager do
|
||||
context 'for mentions feed' do
|
||||
it 'returns true for status that mentions blocked account' do
|
||||
bob.block!(jeff)
|
||||
status = PostStatusService.new.call(alice, 'Hey @jeff')
|
||||
status = PostStatusService.new.call(alice, text: 'Hey @jeff')
|
||||
expect(FeedManager.instance.filter?(:mentions, status, bob.id)).to be true
|
||||
end
|
||||
|
||||
|
||||
22
spec/mailers/admin_mailer_spec.rb
Normal file
22
spec/mailers/admin_mailer_spec.rb
Normal file
@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AdminMailer, type: :mailer do
|
||||
describe '.new_report' do
|
||||
let(:sender) { Fabricate(:account, username: 'John', user: Fabricate(:user)) }
|
||||
let(:recipient) { Fabricate(:account, username: 'Mike', user: Fabricate(:user, locale: :en)) }
|
||||
let(:report) { Fabricate(:report, account: sender, target_account: recipient) }
|
||||
let(:mail) { described_class.new_report(recipient, report) }
|
||||
|
||||
it 'renders the headers' do
|
||||
expect(mail.subject).to eq("New report for cb6e6126.ngrok.io (##{report.id})")
|
||||
expect(mail.to).to eq [recipient.user_email]
|
||||
expect(mail.from).to eq ['notifications@localhost']
|
||||
end
|
||||
|
||||
it 'renders the body' do
|
||||
expect(mail.body.encoded).to eq("Mike,\r\n\r\nJohn has reported Mike\r\n\r\nView: https://cb6e6126.ngrok.io/admin/reports/#{report.id}\r\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -126,19 +126,7 @@ RSpec.describe NotificationMailer, type: :mailer do
|
||||
end
|
||||
end
|
||||
|
||||
it 'includes activities since the date specified by :since option' do
|
||||
receiver.update!(last_emailed_at: '2000-02-01T00:00:00Z', current_sign_in_at: '2000-03-01T00:00:00Z')
|
||||
mail = NotificationMailer.digest(receiver.account, since: Time.parse('2000-01-01T00:00:00Z'))
|
||||
expect(mail.body.encoded).to include 'Jan 01, 2000, 00:00'
|
||||
end
|
||||
|
||||
it 'includes activities since the receiver was last emailed if :since option is unavailable' do
|
||||
receiver.update!(last_emailed_at: '2000-02-01T00:00:00Z', current_sign_in_at: '2000-03-01T00:00:00Z')
|
||||
mail = NotificationMailer.digest(receiver.account)
|
||||
expect(mail.body.encoded).to include 'Feb 01, 2000, 00:00'
|
||||
end
|
||||
|
||||
it 'includes activities since the receiver last signed in if :since option and the last emailed date are unavailable' do
|
||||
it 'includes activities since the receiver last signed in' do
|
||||
receiver.update!(last_emailed_at: nil, current_sign_in_at: '2000-03-01T00:00:00Z')
|
||||
mail = NotificationMailer.digest(receiver.account)
|
||||
expect(mail.body.encoded).to include 'Mar 01, 2000, 00:00'
|
||||
|
||||
@ -39,4 +39,9 @@ class UserMailerPreview < ActionMailer::Preview
|
||||
def backup_ready
|
||||
UserMailer.backup_ready(User.first, Backup.first)
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/user_mailer/warning
|
||||
def warning
|
||||
UserMailer.warning(User.first, AccountWarning.new(text: '', action: :silence))
|
||||
end
|
||||
end
|
||||
|
||||
@ -2,10 +2,10 @@ require 'rails_helper'
|
||||
|
||||
describe AccountFilter do
|
||||
describe 'with empty params' do
|
||||
it 'defaults to recent account list' do
|
||||
it 'defaults to recent local not-suspended account list' do
|
||||
filter = described_class.new({})
|
||||
|
||||
expect(filter.results).to eq Account.recent
|
||||
expect(filter.results).to eq Account.local.recent.without_suspended
|
||||
end
|
||||
end
|
||||
|
||||
@ -17,23 +17,6 @@ describe AccountFilter do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when an IP address is provided' do
|
||||
it 'filters with IP when valid' do
|
||||
filter = described_class.new(ip: '127.0.0.1')
|
||||
allow(User).to receive(:with_recent_ip_address).and_return(User.none)
|
||||
|
||||
filter.results
|
||||
expect(User).to have_received(:with_recent_ip_address).with('127.0.0.1')
|
||||
end
|
||||
|
||||
it 'skips IP when invalid' do
|
||||
filter = described_class.new(ip: '345.678.901.234')
|
||||
expect(User).not_to receive(:with_recent_ip_address)
|
||||
|
||||
filter.results
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with valid params' do
|
||||
it 'combines filters on Account' do
|
||||
filter = described_class.new(
|
||||
@ -60,13 +43,13 @@ describe AccountFilter do
|
||||
end
|
||||
|
||||
describe 'that call account methods' do
|
||||
%i(local remote silenced alphabetic suspended).each do |option|
|
||||
%i(local remote silenced suspended).each do |option|
|
||||
it "delegates the #{option} option" do
|
||||
allow(Account).to receive(option).and_return(Account.none)
|
||||
filter = described_class.new({ option => true })
|
||||
filter.results
|
||||
|
||||
expect(Account).to have_received(option)
|
||||
expect(Account).to have_received(option).at_least(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountPin, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
@ -760,24 +760,6 @@ RSpec.describe Account, type: :model do
|
||||
expect(Account.suspended).to match_array([account_1])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'without_followers' do
|
||||
it 'returns a relation of accounts without followers' do
|
||||
account_1 = Fabricate(:account)
|
||||
account_2 = Fabricate(:account)
|
||||
Fabricate(:follow, account: account_1, target_account: account_2)
|
||||
expect(Account.without_followers).to match_array([account_1])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with_followers' do
|
||||
it 'returns a relation of accounts with followers' do
|
||||
account_1 = Fabricate(:account)
|
||||
account_2 = Fabricate(:account)
|
||||
Fabricate(:follow, account: account_1, target_account: account_2)
|
||||
expect(Account.with_followers).to match_array([account_2])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when is local' do
|
||||
|
||||
4
spec/models/account_stat_spec.rb
Normal file
4
spec/models/account_stat_spec.rb
Normal file
@ -0,0 +1,4 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountStat, type: :model do
|
||||
end
|
||||
38
spec/models/account_tag_stat_spec.rb
Normal file
38
spec/models/account_tag_stat_spec.rb
Normal file
@ -0,0 +1,38 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountTagStat, type: :model do
|
||||
key = 'accounts_count'
|
||||
let(:account_tag_stat) { Fabricate(:tag).account_tag_stat }
|
||||
|
||||
describe '#increment_count!' do
|
||||
it 'calls #update' do
|
||||
args = { key => account_tag_stat.public_send(key) + 1 }
|
||||
expect(account_tag_stat).to receive(:update).with(args)
|
||||
account_tag_stat.increment_count!(key)
|
||||
end
|
||||
|
||||
it 'increments value by 1' do
|
||||
expect do
|
||||
account_tag_stat.increment_count!(key)
|
||||
end.to change { account_tag_stat.accounts_count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#decrement_count!' do
|
||||
it 'calls #update' do
|
||||
args = { key => [account_tag_stat.public_send(key) - 1, 0].max }
|
||||
expect(account_tag_stat).to receive(:update).with(args)
|
||||
account_tag_stat.decrement_count!(key)
|
||||
end
|
||||
|
||||
it 'decrements value by 1' do
|
||||
account_tag_stat.update(key => 1)
|
||||
|
||||
expect do
|
||||
account_tag_stat.decrement_count!(key)
|
||||
end.to change { account_tag_stat.accounts_count }.by(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
4
spec/models/admin/account_action_spec.rb
Normal file
4
spec/models/admin/account_action_spec.rb
Normal file
@ -0,0 +1,4 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::AccountAction, type: :model do
|
||||
end
|
||||
@ -118,5 +118,15 @@ describe StatusThreadingConcern do
|
||||
viewer.block_domain!('example.com')
|
||||
expect(status.descendants(4, viewer)).to_not include(reply2)
|
||||
end
|
||||
|
||||
it 'promotes self-replies to the top while leaving the rest in order' do
|
||||
a = Fabricate(:status, account: alice)
|
||||
d = Fabricate(:status, account: jeff, thread: a)
|
||||
e = Fabricate(:status, account: bob, thread: d)
|
||||
c = Fabricate(:status, account: alice, thread: a)
|
||||
f = Fabricate(:status, account: bob, thread: c)
|
||||
|
||||
expect(a.descendants(20)).to eq [c, d, e, f]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
70
spec/models/custom_emoji_filter_spec.rb
Normal file
70
spec/models/custom_emoji_filter_spec.rb
Normal file
@ -0,0 +1,70 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe CustomEmojiFilter do
|
||||
describe '#results' do
|
||||
let!(:custom_emoji_0) { Fabricate(:custom_emoji, domain: 'a') }
|
||||
let!(:custom_emoji_1) { Fabricate(:custom_emoji, domain: 'b') }
|
||||
let!(:custom_emoji_2) { Fabricate(:custom_emoji, domain: nil, shortcode: 'hoge') }
|
||||
|
||||
subject { described_class.new(params).results }
|
||||
|
||||
context 'params have values' do
|
||||
context 'local' do
|
||||
let(:params) { { local: true } }
|
||||
|
||||
it 'returns ActiveRecord::Relation' do
|
||||
expect(subject).to be_kind_of(ActiveRecord::Relation)
|
||||
expect(subject).to match_array([custom_emoji_2])
|
||||
end
|
||||
end
|
||||
|
||||
context 'remote' do
|
||||
let(:params) { { remote: true } }
|
||||
|
||||
it 'returns ActiveRecord::Relation' do
|
||||
expect(subject).to be_kind_of(ActiveRecord::Relation)
|
||||
expect(subject).to match_array([custom_emoji_0, custom_emoji_1])
|
||||
end
|
||||
end
|
||||
|
||||
context 'by_domain' do
|
||||
let(:params) { { by_domain: 'a' } }
|
||||
|
||||
it 'returns ActiveRecord::Relation' do
|
||||
expect(subject).to be_kind_of(ActiveRecord::Relation)
|
||||
expect(subject).to match_array([custom_emoji_0])
|
||||
end
|
||||
end
|
||||
|
||||
context 'shortcode' do
|
||||
let(:params) { { shortcode: 'hoge' } }
|
||||
|
||||
it 'returns ActiveRecord::Relation' do
|
||||
expect(subject).to be_kind_of(ActiveRecord::Relation)
|
||||
expect(subject).to match_array([custom_emoji_2])
|
||||
end
|
||||
end
|
||||
|
||||
context 'else' do
|
||||
let(:params) { { else: 'else' } }
|
||||
|
||||
it 'raises RuntimeError' do
|
||||
expect do
|
||||
subject
|
||||
end.to raise_error(RuntimeError, /Unknown filter: else/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'params without value' do
|
||||
let(:params) { { hoge: nil } }
|
||||
|
||||
it 'returns ActiveRecord::Relation' do
|
||||
expect(subject).to be_kind_of(ActiveRecord::Relation)
|
||||
expect(subject).to match_array([custom_emoji_0, custom_emoji_1, custom_emoji_2])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -75,4 +75,13 @@ RSpec.describe CustomEmoji, type: :model do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'pre_validation' do
|
||||
let(:custom_emoji) { Fabricate(:custom_emoji, domain: 'wWw.MaStOdOn.CoM') }
|
||||
|
||||
it 'should downcase' do
|
||||
custom_emoji.valid?
|
||||
expect(custom_emoji.domain).to eq('www.mastodon.com')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,5 +1,16 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Identity, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
describe '.find_for_oauth' do
|
||||
let(:auth) { Fabricate(:identity, user: Fabricate(:user)) }
|
||||
|
||||
it 'calls .find_or_create_by' do
|
||||
expect(described_class).to receive(:find_or_create_by).with(uid: auth.uid, provider: auth.provider)
|
||||
described_class.find_for_oauth(auth)
|
||||
end
|
||||
|
||||
it 'returns an instance of Identity' do
|
||||
expect(described_class.find_for_oauth(auth)).to be_instance_of Identity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Notification, type: :model do
|
||||
describe '#from_account' do
|
||||
pending
|
||||
end
|
||||
|
||||
describe '#target_status' do
|
||||
let(:notification) { Fabricate(:notification, activity: activity) }
|
||||
let(:status) { Fabricate(:status) }
|
||||
@ -101,7 +97,7 @@ RSpec.describe Notification, type: :model do
|
||||
before do
|
||||
allow(accounts_with_ids).to receive(:[]).with(stale_account1.id).and_return(account1)
|
||||
allow(accounts_with_ids).to receive(:[]).with(stale_account2.id).and_return(account2)
|
||||
allow(Account).to receive_message_chain(:where, :each_with_object).and_return(accounts_with_ids)
|
||||
allow(Account).to receive_message_chain(:where, :includes, :each_with_object).and_return(accounts_with_ids)
|
||||
end
|
||||
|
||||
let(:cached_items) do
|
||||
|
||||
4
spec/models/scheduled_status_spec.rb
Normal file
4
spec/models/scheduled_status_spec.rb
Normal file
@ -0,0 +1,4 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ScheduledStatus, type: :model do
|
||||
end
|
||||
@ -1,5 +1,4 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe StatusStat, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
|
||||
@ -89,18 +89,6 @@ RSpec.describe User, type: :model do
|
||||
expect(User.matches_email('specified')).to match_array([specified])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with_recent_ip_address' do
|
||||
it 'returns a relation of users who is, or was at last time, online with the given IP address' do
|
||||
specifieds = [
|
||||
Fabricate(:user, current_sign_in_ip: '0.0.0.42', last_sign_in_ip: '0.0.0.0'),
|
||||
Fabricate(:user, current_sign_in_ip: nil, last_sign_in_ip: '0.0.0.42')
|
||||
]
|
||||
Fabricate(:user, current_sign_in_ip: '0.0.0.0', last_sign_in_ip: '0.0.0.0')
|
||||
|
||||
expect(User.with_recent_ip_address('0.0.0.42')).to match_array(specifieds)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:account) { Fabricate(:account, username: 'alice') }
|
||||
@ -118,19 +106,19 @@ RSpec.describe User, type: :model do
|
||||
end
|
||||
|
||||
it 'should allow a non-blacklisted user to be created' do
|
||||
user = User.new(email: 'foo@example.com', account: account, password: password)
|
||||
user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true)
|
||||
|
||||
expect(user.valid?).to be_truthy
|
||||
end
|
||||
|
||||
it 'should not allow a blacklisted user to be created' do
|
||||
user = User.new(email: 'foo@mvrht.com', account: account, password: password)
|
||||
user = User.new(email: 'foo@mvrht.com', account: account, password: password, agreement: true)
|
||||
|
||||
expect(user.valid?).to be_falsey
|
||||
end
|
||||
|
||||
it 'should not allow a subdomain blacklisted user to be created' do
|
||||
user = User.new(email: 'foo@mvrht.com.topdomain.tld', account: account, password: password)
|
||||
user = User.new(email: 'foo@mvrht.com.topdomain.tld', account: account, password: password, agreement: true)
|
||||
|
||||
expect(user.valid?).to be_falsey
|
||||
end
|
||||
@ -222,17 +210,17 @@ RSpec.describe User, type: :model do
|
||||
end
|
||||
|
||||
it 'should not allow a user to be created unless they are whitelisted' do
|
||||
user = User.new(email: 'foo@example.com', account: account, password: password)
|
||||
user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true)
|
||||
expect(user.valid?).to be_falsey
|
||||
end
|
||||
|
||||
it 'should allow a user to be created if they are whitelisted' do
|
||||
user = User.new(email: 'foo@mastodon.space', account: account, password: password)
|
||||
user = User.new(email: 'foo@mastodon.space', account: account, password: password, agreement: true)
|
||||
expect(user.valid?).to be_truthy
|
||||
end
|
||||
|
||||
it 'should not allow a user with a whitelisted top domain as subdomain in their email address to be created' do
|
||||
user = User.new(email: 'foo@mastodon.space.userdomain.com', account: account, password: password)
|
||||
user = User.new(email: 'foo@mastodon.space.userdomain.com', account: account, password: password, agreement: true)
|
||||
expect(user.valid?).to be_falsey
|
||||
end
|
||||
|
||||
@ -254,7 +242,7 @@ RSpec.describe User, type: :model do
|
||||
|
||||
it_behaves_like 'Settings-extended' do
|
||||
def create!
|
||||
User.create!(account: Fabricate(:account), email: 'foo@mastodon.space', password: 'abcd1234')
|
||||
User.create!(account: Fabricate(:account), email: 'foo@mastodon.space', password: 'abcd1234', agreement: true)
|
||||
end
|
||||
|
||||
def fabricate
|
||||
|
||||
52
spec/policies/account_moderation_note_policy_spec.rb
Normal file
52
spec/policies/account_moderation_note_policy_spec.rb
Normal file
@ -0,0 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe AccountModerationNotePolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :create? do
|
||||
context 'staff' do
|
||||
it 'grants to create' do
|
||||
expect(subject).to permit(admin, AccountModerationNotePolicy)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not staff' do
|
||||
it 'denies to create' do
|
||||
expect(subject).to_not permit(john, AccountModerationNotePolicy)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :destroy? do
|
||||
let(:account_moderation_note) do
|
||||
Fabricate(:account_moderation_note,
|
||||
account: john,
|
||||
target_account: Fabricate(:account))
|
||||
end
|
||||
|
||||
context 'admin' do
|
||||
it 'grants to destroy' do
|
||||
expect(subject).to permit(admin, AccountModerationNotePolicy)
|
||||
end
|
||||
end
|
||||
|
||||
context 'owner' do
|
||||
it 'grants to destroy' do
|
||||
expect(subject).to permit(john, account_moderation_note)
|
||||
end
|
||||
end
|
||||
|
||||
context 'neither admin nor owner' do
|
||||
let(:kevin) { Fabricate(:user).account }
|
||||
|
||||
it 'denies to destroy' do
|
||||
expect(subject).to_not permit(kevin, account_moderation_note)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
86
spec/policies/account_policy_spec.rb
Normal file
86
spec/policies/account_policy_spec.rb
Normal file
@ -0,0 +1,86 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe AccountPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :index?, :show?, :unsuspend?, :unsilence?, :remove_avatar?, :remove_header? do
|
||||
context 'staff' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not staff' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :redownload?, :subscribe?, :unsubscribe? do
|
||||
context 'admin' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not admin' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :suspend?, :silence? do
|
||||
let(:staff) { Fabricate(:user, admin: true).account }
|
||||
|
||||
context 'staff' do
|
||||
context 'record is staff' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(admin, staff)
|
||||
end
|
||||
end
|
||||
|
||||
context 'record is not staff' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, john)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'not staff' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Account)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :memorialize? do
|
||||
let(:other_admin) { Fabricate(:user, admin: true).account }
|
||||
|
||||
context 'admin' do
|
||||
context 'record is admin' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(admin, other_admin)
|
||||
end
|
||||
end
|
||||
|
||||
context 'record is not admin' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, john)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'not admin' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Account)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
45
spec/policies/backup_policy_spec.rb
Normal file
45
spec/policies/backup_policy_spec.rb
Normal file
@ -0,0 +1,45 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe BackupPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :create? do
|
||||
context 'not user_signed_in?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(nil, Backup)
|
||||
end
|
||||
end
|
||||
|
||||
context 'user_signed_in?' do
|
||||
context 'no backups' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(john, Backup)
|
||||
end
|
||||
end
|
||||
|
||||
context 'backups are too old' do
|
||||
it 'permits' do
|
||||
travel(-8.days) do
|
||||
Fabricate(:backup, user: john.user)
|
||||
end
|
||||
|
||||
expect(subject).to permit(john, Backup)
|
||||
end
|
||||
end
|
||||
|
||||
context 'backups are newer' do
|
||||
it 'denies' do
|
||||
travel(-3.days) do
|
||||
Fabricate(:backup, user: john.user)
|
||||
end
|
||||
|
||||
expect(subject).to_not permit(john, Backup)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
38
spec/policies/custom_emoji_policy_spec.rb
Normal file
38
spec/policies/custom_emoji_policy_spec.rb
Normal file
@ -0,0 +1,38 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe CustomEmojiPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :index?, :enable?, :disable? do
|
||||
context 'staff' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, CustomEmoji)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not staff' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, CustomEmoji)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :create?, :update?, :copy?, :destroy? do
|
||||
context 'admin' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, CustomEmoji)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not admin' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, CustomEmoji)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/policies/domain_block_policy_spec.rb
Normal file
24
spec/policies/domain_block_policy_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe DomainBlockPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :index?, :show?, :create?, :destroy? do
|
||||
context 'admin' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, DomainBlock)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not admin' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, DomainBlock)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/policies/email_domain_block_policy_spec.rb
Normal file
24
spec/policies/email_domain_block_policy_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe EmailDomainBlockPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :index?, :create?, :destroy? do
|
||||
context 'admin' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, EmailDomainBlock)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not admin' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, EmailDomainBlock)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/policies/instance_policy_spec.rb
Normal file
24
spec/policies/instance_policy_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe InstancePolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :index? do
|
||||
context 'admin' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Instance)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not admin' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Instance)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
94
spec/policies/invite_policy_spec.rb
Normal file
94
spec/policies/invite_policy_spec.rb
Normal file
@ -0,0 +1,94 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe InvitePolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :index? do
|
||||
context 'staff?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Invite)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :create? do
|
||||
context 'min_required_role?' do
|
||||
it 'permits' do
|
||||
allow_any_instance_of(described_class).to receive(:min_required_role?) { true }
|
||||
expect(subject).to permit(john, Invite)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not min_required_role?' do
|
||||
it 'denies' do
|
||||
allow_any_instance_of(described_class).to receive(:min_required_role?) { false }
|
||||
expect(subject).to_not permit(john, Invite)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :deactivate_all? do
|
||||
context 'admin?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Invite)
|
||||
end
|
||||
end
|
||||
|
||||
context 'not admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Invite)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :destroy? do
|
||||
context 'owner?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(john, Fabricate(:invite, user: john.user))
|
||||
end
|
||||
end
|
||||
|
||||
context 'not owner?' do
|
||||
context 'Setting.min_invite_role == "admin"' do
|
||||
before do
|
||||
Setting.min_invite_role = 'admin'
|
||||
end
|
||||
|
||||
context 'admin?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Fabricate(:invite))
|
||||
end
|
||||
end
|
||||
|
||||
context 'not admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Fabricate(:invite))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'Setting.min_invite_role != "admin"' do
|
||||
before do
|
||||
Setting.min_invite_role = 'else'
|
||||
end
|
||||
|
||||
context 'staff?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Fabricate(:invite))
|
||||
end
|
||||
end
|
||||
|
||||
context 'not staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Fabricate(:invite))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/policies/relay_policy_spec.rb
Normal file
24
spec/policies/relay_policy_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe RelayPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :update? do
|
||||
context 'admin?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Relay)
|
||||
end
|
||||
end
|
||||
|
||||
context '!admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Relay)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
48
spec/policies/report_note_policy_spec.rb
Normal file
48
spec/policies/report_note_policy_spec.rb
Normal file
@ -0,0 +1,48 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe ReportNotePolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :create? do
|
||||
context 'staff?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, ReportNote)
|
||||
end
|
||||
end
|
||||
|
||||
context '!staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, ReportNote)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :destroy? do
|
||||
context 'admin?' do
|
||||
it 'permit' do
|
||||
expect(subject).to permit(admin, ReportNote)
|
||||
end
|
||||
end
|
||||
|
||||
context 'admin?' do
|
||||
context 'owner?' do
|
||||
it 'permit' do
|
||||
report_note = Fabricate(:report_note, account: john)
|
||||
expect(subject).to permit(john, report_note)
|
||||
end
|
||||
end
|
||||
|
||||
context '!owner?' do
|
||||
it 'denies' do
|
||||
report_note = Fabricate(:report_note)
|
||||
expect(subject).to_not permit(john, report_note)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/policies/report_policy_spec.rb
Normal file
24
spec/policies/report_policy_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe ReportPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :update?, :index?, :show? do
|
||||
context 'staff?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Report)
|
||||
end
|
||||
end
|
||||
|
||||
context '!staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Report)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/policies/settings_policy_spec.rb
Normal file
24
spec/policies/settings_policy_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe SettingsPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :update?, :show? do
|
||||
context 'admin?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Settings)
|
||||
end
|
||||
end
|
||||
|
||||
context '!admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Settings)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,3 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
@ -118,4 +120,30 @@ RSpec.describe StatusPolicy, type: :model do
|
||||
expect(subject).to_not permit(nil, status)
|
||||
end
|
||||
end
|
||||
|
||||
permissions :favourite? do
|
||||
it 'grants access when viewer is not blocked' do
|
||||
follow = Fabricate(:follow)
|
||||
status.account = follow.target_account
|
||||
|
||||
expect(subject).to permit(follow.account, status)
|
||||
end
|
||||
|
||||
it 'denies when viewer is blocked' do
|
||||
block = Fabricate(:block)
|
||||
status.account = block.target_account
|
||||
|
||||
expect(subject).to_not permit(block.account, status)
|
||||
end
|
||||
end
|
||||
|
||||
permissions :index?, :update? do
|
||||
it 'grants access if staff' do
|
||||
expect(subject).to permit(admin.account)
|
||||
end
|
||||
|
||||
it 'denies access unless staff' do
|
||||
expect(subject).to_not permit(alice)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
24
spec/policies/subscription_policy_spec.rb
Normal file
24
spec/policies/subscription_policy_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe SubscriptionPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :index? do
|
||||
context 'admin?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Subscription)
|
||||
end
|
||||
end
|
||||
|
||||
context '!admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Subscription)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/policies/tag_policy_spec.rb
Normal file
24
spec/policies/tag_policy_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe TagPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :index?, :hide?, :unhide? do
|
||||
context 'staff?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, Tag)
|
||||
end
|
||||
end
|
||||
|
||||
context '!staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, Tag)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
167
spec/policies/user_policy_spec.rb
Normal file
167
spec/policies/user_policy_spec.rb
Normal file
@ -0,0 +1,167 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pundit/rspec'
|
||||
|
||||
RSpec.describe UserPolicy do
|
||||
let(:subject) { described_class }
|
||||
let(:admin) { Fabricate(:user, admin: true).account }
|
||||
let(:john) { Fabricate(:user).account }
|
||||
|
||||
permissions :reset_password?, :change_email? do
|
||||
context 'staff?' do
|
||||
context '!record.staff?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, john.user)
|
||||
end
|
||||
end
|
||||
|
||||
context 'record.staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(admin, admin.user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '!staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, User)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :disable_2fa? do
|
||||
context 'admin?' do
|
||||
context '!record.staff?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, john.user)
|
||||
end
|
||||
end
|
||||
|
||||
context 'record.staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(admin, admin.user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '!admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, User)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :confirm? do
|
||||
context 'staff?' do
|
||||
context '!record.confirmed?' do
|
||||
it 'permits' do
|
||||
john.user.update(confirmed_at: nil)
|
||||
expect(subject).to permit(admin, john.user)
|
||||
end
|
||||
end
|
||||
|
||||
context 'record.confirmed?' do
|
||||
it 'denies' do
|
||||
john.user.confirm!
|
||||
expect(subject).to_not permit(admin, john.user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '!staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, User)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :enable? do
|
||||
context 'staff?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, User)
|
||||
end
|
||||
end
|
||||
|
||||
context '!staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, User)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :disable? do
|
||||
context 'staff?' do
|
||||
context '!record.admin?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, john.user)
|
||||
end
|
||||
end
|
||||
|
||||
context 'record.admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(admin, admin.user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '!staff?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, User)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :promote? do
|
||||
context 'admin?' do
|
||||
context 'promoteable?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, john.user)
|
||||
end
|
||||
end
|
||||
|
||||
context '!promoteable?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(admin, admin.user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '!admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, User)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
permissions :demote? do
|
||||
context 'admin?' do
|
||||
context '!record.admin?' do
|
||||
context 'demoteable?' do
|
||||
it 'permits' do
|
||||
john.user.update(moderator: true)
|
||||
expect(subject).to permit(admin, john.user)
|
||||
end
|
||||
end
|
||||
|
||||
context '!demoteable?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(admin, john.user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'record.admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(admin, admin.user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '!admin?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(john, User)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -111,4 +111,37 @@ describe InstancePresenter do
|
||||
expect(instance_presenter.domain_count).to eq(345)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#version_number' do
|
||||
it 'returns Mastodon::Version' do
|
||||
expect(instance_presenter.version_number).to be(Mastodon::Version)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#source_url' do
|
||||
it 'returns "https://github.com/tootsuite/mastodon"' do
|
||||
expect(instance_presenter.source_url).to eq('https://github.com/tootsuite/mastodon')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#thumbnail' do
|
||||
it 'returns SiteUpload' do
|
||||
thumbnail = Fabricate(:site_upload, var: 'thumbnail')
|
||||
expect(instance_presenter.thumbnail).to eq(thumbnail)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#hero' do
|
||||
it 'returns SiteUpload' do
|
||||
hero = Fabricate(:site_upload, var: 'hero')
|
||||
expect(instance_presenter.hero).to eq(hero)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#mascot' do
|
||||
it 'returns SiteUpload' do
|
||||
mascot = Fabricate(:site_upload, var: 'mascot')
|
||||
expect(instance_presenter.mascot).to eq(mascot)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -26,9 +26,9 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
|
||||
context 'when actor differs from sender' do
|
||||
let(:forwarder) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/other_account') }
|
||||
|
||||
it 'processes payload with sender if no signature exists' do
|
||||
expect_any_instance_of(ActivityPub::LinkedDataSignature).not_to receive(:verify_account!)
|
||||
expect(ActivityPub::Activity).to receive(:factory).with(instance_of(Hash), forwarder, instance_of(Hash))
|
||||
it 'does not process payload if no signature exists' do
|
||||
expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_account!).and_return(nil)
|
||||
expect(ActivityPub::Activity).not_to receive(:factory)
|
||||
|
||||
subject.call(json, forwarder)
|
||||
end
|
||||
|
||||
41
spec/services/app_sign_up_service_spec.rb
Normal file
41
spec/services/app_sign_up_service_spec.rb
Normal file
@ -0,0 +1,41 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AppSignUpService, type: :service do
|
||||
let(:app) { Fabricate(:application, scopes: 'read write') }
|
||||
let(:good_params) { { username: 'alice', password: '12345678', email: 'good@email.com', agreement: true } }
|
||||
|
||||
subject { described_class.new }
|
||||
|
||||
describe '#call' do
|
||||
it 'returns nil when registrations are closed' do
|
||||
Setting.open_registrations = false
|
||||
expect(subject.call(app, good_params)).to be_nil
|
||||
end
|
||||
|
||||
it 'raises an error when params are missing' do
|
||||
expect { subject.call(app, {}) }.to raise_error ActiveRecord::RecordInvalid
|
||||
end
|
||||
|
||||
it 'creates an unconfirmed user with access token' do
|
||||
access_token = subject.call(app, good_params)
|
||||
expect(access_token).to_not be_nil
|
||||
user = User.find_by(id: access_token.resource_owner_id)
|
||||
expect(user).to_not be_nil
|
||||
expect(user.confirmed?).to be false
|
||||
end
|
||||
|
||||
it 'creates access token with the app\'s scopes' do
|
||||
access_token = subject.call(app, good_params)
|
||||
expect(access_token).to_not be_nil
|
||||
expect(access_token.scopes.to_s).to eq 'read write'
|
||||
end
|
||||
|
||||
it 'creates an account' do
|
||||
access_token = subject.call(app, good_params)
|
||||
expect(access_token).to_not be_nil
|
||||
user = User.find_by(id: access_token.resource_owner_id)
|
||||
expect(user).to_not be_nil
|
||||
expect(user.account).to_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -8,8 +8,8 @@ RSpec.describe BatchedRemoveStatusService, type: :service do
|
||||
let!(:jeff) { Fabricate(:user).account }
|
||||
let!(:hank) { Fabricate(:account, username: 'hank', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
|
||||
|
||||
let(:status1) { PostStatusService.new.call(alice, 'Hello @bob@example.com') }
|
||||
let(:status2) { PostStatusService.new.call(alice, 'Another status') }
|
||||
let(:status1) { PostStatusService.new.call(alice, text: 'Hello @bob@example.com') }
|
||||
let(:status2) { PostStatusService.new.call(alice, text: 'Another status') }
|
||||
|
||||
before do
|
||||
allow(Redis.current).to receive_messages(publish: nil)
|
||||
|
||||
@ -17,6 +17,8 @@ RSpec.describe FetchLinkCardService, type: :service do
|
||||
stub_request(:head, 'https://github.com/qbi/WannaCry').to_return(status: 404)
|
||||
stub_request(:head, 'http://example.com/test-').to_return(status: 200, headers: { 'Content-Type' => 'text/html' })
|
||||
stub_request(:get, 'http://example.com/test-').to_return(request_fixture('idn.txt'))
|
||||
stub_request(:head, 'http://example.com/windows-1251').to_return(status: 200, headers: { 'Content-Type' => 'text/html' })
|
||||
stub_request(:get, 'http://example.com/windows-1251').to_return(request_fixture('windows-1251.txt'))
|
||||
|
||||
subject.call(status)
|
||||
end
|
||||
@ -57,6 +59,15 @@ RSpec.describe FetchLinkCardService, type: :service do
|
||||
end
|
||||
end
|
||||
|
||||
context do
|
||||
let(:status) { Fabricate(:status, text: 'Check out http://example.com/windows-1251') }
|
||||
|
||||
it 'works with windows-1251' do
|
||||
expect(a_request(:get, 'http://example.com/windows-1251')).to have_been_made.at_least_once
|
||||
expect(status.preview_cards.first.title).to eq('сэмпл текст')
|
||||
end
|
||||
end
|
||||
|
||||
context do
|
||||
let(:status) { Fabricate(:status, text: 'テストhttp://example.com/日本語') }
|
||||
|
||||
|
||||
60
spec/services/hashtag_query_service_spec.rb
Normal file
60
spec/services/hashtag_query_service_spec.rb
Normal file
@ -0,0 +1,60 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe HashtagQueryService, type: :service do
|
||||
describe '.call' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:tag1) { Fabricate(:tag) }
|
||||
let(:tag2) { Fabricate(:tag) }
|
||||
let!(:status1) { Fabricate(:status, tags: [tag1]) }
|
||||
let!(:status2) { Fabricate(:status, tags: [tag2]) }
|
||||
let!(:both) { Fabricate(:status, tags: [tag1, tag2]) }
|
||||
|
||||
it 'can add tags in "any" mode' do
|
||||
results = subject.call(tag1, { any: [tag2.name] })
|
||||
expect(results).to include status1
|
||||
expect(results).to include status2
|
||||
expect(results).to include both
|
||||
end
|
||||
|
||||
it 'can remove tags in "all" mode' do
|
||||
results = subject.call(tag1, { all: [tag2.name] })
|
||||
expect(results).to_not include status1
|
||||
expect(results).to_not include status2
|
||||
expect(results).to include both
|
||||
end
|
||||
|
||||
it 'can remove tags in "none" mode' do
|
||||
results = subject.call(tag1, { none: [tag2.name] })
|
||||
expect(results).to include status1
|
||||
expect(results).to_not include status2
|
||||
expect(results).to_not include both
|
||||
end
|
||||
|
||||
it 'ignores an invalid mode' do
|
||||
results = subject.call(tag1, { wark: [tag2.name] })
|
||||
expect(results).to include status1
|
||||
expect(results).to_not include status2
|
||||
expect(results).to include both
|
||||
end
|
||||
|
||||
it 'handles being passed non existant tag names' do
|
||||
results = subject.call(tag1, { any: ['wark'] })
|
||||
expect(results).to include status1
|
||||
expect(results).to_not include status2
|
||||
expect(results).to include both
|
||||
end
|
||||
|
||||
it 'can restrict to an account' do
|
||||
BlockService.new.call(account, status1.account)
|
||||
results = subject.call(tag1, { none: [tag2.name] }, account)
|
||||
expect(results).to_not include status1
|
||||
end
|
||||
|
||||
it 'can restrict to local' do
|
||||
status1.account.update(domain: 'example.com')
|
||||
status1.update(local: false, uri: 'example.com/toot')
|
||||
results = subject.call(tag1, { any: [tag2.name] }, nil, true)
|
||||
expect(results).to_not include status1
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -7,7 +7,7 @@ RSpec.describe PostStatusService, type: :service do
|
||||
account = Fabricate(:account)
|
||||
text = "test status update"
|
||||
|
||||
status = subject.call(account, text)
|
||||
status = subject.call(account, text: text)
|
||||
|
||||
expect(status).to be_persisted
|
||||
expect(status.text).to eq text
|
||||
@ -18,13 +18,37 @@ RSpec.describe PostStatusService, type: :service do
|
||||
account = Fabricate(:account)
|
||||
text = "test status update"
|
||||
|
||||
status = subject.call(account, text, in_reply_to_status)
|
||||
status = subject.call(account, text: text, thread: in_reply_to_status)
|
||||
|
||||
expect(status).to be_persisted
|
||||
expect(status.text).to eq text
|
||||
expect(status.thread).to eq in_reply_to_status
|
||||
end
|
||||
|
||||
it 'schedules a status' do
|
||||
account = Fabricate(:account)
|
||||
future = Time.now.utc + 2.hours
|
||||
|
||||
status = subject.call(account, text: 'Hi future!', scheduled_at: future)
|
||||
|
||||
expect(status).to be_a ScheduledStatus
|
||||
expect(status.scheduled_at).to eq future
|
||||
expect(status.params['text']).to eq 'Hi future!'
|
||||
end
|
||||
|
||||
it 'creates response to the original status of boost' do
|
||||
boosted_status = Fabricate(:status)
|
||||
in_reply_to_status = Fabricate(:status, reblog: boosted_status)
|
||||
account = Fabricate(:account)
|
||||
text = "test status update"
|
||||
|
||||
status = subject.call(account, text: text, thread: in_reply_to_status)
|
||||
|
||||
expect(status).to be_persisted
|
||||
expect(status.text).to eq text
|
||||
expect(status.thread).to eq boosted_status
|
||||
end
|
||||
|
||||
it 'creates a sensitive status' do
|
||||
status = create_status_with_options(sensitive: true)
|
||||
|
||||
@ -55,6 +79,13 @@ RSpec.describe PostStatusService, type: :service do
|
||||
expect(status.visibility).to eq "private"
|
||||
end
|
||||
|
||||
it 'creates a status with limited visibility for silenced users' do
|
||||
status = subject.call(Fabricate(:account, silenced: true), text: 'test', visibility: :public)
|
||||
|
||||
expect(status).to be_persisted
|
||||
expect(status.visibility).to eq "unlisted"
|
||||
end
|
||||
|
||||
it 'creates a status for the given application' do
|
||||
application = Fabricate(:application)
|
||||
|
||||
@ -68,7 +99,7 @@ RSpec.describe PostStatusService, type: :service do
|
||||
account = Fabricate(:account)
|
||||
text = 'This is an English text.'
|
||||
|
||||
status = subject.call(account, text)
|
||||
status = subject.call(account, text: text)
|
||||
|
||||
expect(status.language).to eq 'en'
|
||||
end
|
||||
@ -79,7 +110,7 @@ RSpec.describe PostStatusService, type: :service do
|
||||
allow(ProcessMentionsService).to receive(:new).and_return(mention_service)
|
||||
account = Fabricate(:account)
|
||||
|
||||
status = subject.call(account, "test status update")
|
||||
status = subject.call(account, text: "test status update")
|
||||
|
||||
expect(ProcessMentionsService).to have_received(:new)
|
||||
expect(mention_service).to have_received(:call).with(status)
|
||||
@ -91,7 +122,7 @@ RSpec.describe PostStatusService, type: :service do
|
||||
allow(ProcessHashtagsService).to receive(:new).and_return(hashtags_service)
|
||||
account = Fabricate(:account)
|
||||
|
||||
status = subject.call(account, "test status update")
|
||||
status = subject.call(account, text: "test status update")
|
||||
|
||||
expect(ProcessHashtagsService).to have_received(:new)
|
||||
expect(hashtags_service).to have_received(:call).with(status)
|
||||
@ -104,7 +135,7 @@ RSpec.describe PostStatusService, type: :service do
|
||||
|
||||
account = Fabricate(:account)
|
||||
|
||||
status = subject.call(account, "test status update")
|
||||
status = subject.call(account, text: "test status update")
|
||||
|
||||
expect(DistributionWorker).to have_received(:perform_async).with(status.id)
|
||||
expect(Pubsubhubbub::DistributionWorker).to have_received(:perform_async).with(status.stream_entry.id)
|
||||
@ -115,7 +146,7 @@ RSpec.describe PostStatusService, type: :service do
|
||||
allow(LinkCrawlWorker).to receive(:perform_async)
|
||||
account = Fabricate(:account)
|
||||
|
||||
status = subject.call(account, "test status update")
|
||||
status = subject.call(account, text: "test status update")
|
||||
|
||||
expect(LinkCrawlWorker).to have_received(:perform_async).with(status.id)
|
||||
end
|
||||
@ -126,8 +157,7 @@ RSpec.describe PostStatusService, type: :service do
|
||||
|
||||
status = subject.call(
|
||||
account,
|
||||
"test status update",
|
||||
nil,
|
||||
text: "test status update",
|
||||
media_ids: [media.id],
|
||||
)
|
||||
|
||||
@ -140,8 +170,7 @@ RSpec.describe PostStatusService, type: :service do
|
||||
expect do
|
||||
subject.call(
|
||||
account,
|
||||
"test status update",
|
||||
nil,
|
||||
text: "test status update",
|
||||
media_ids: [
|
||||
Fabricate(:media_attachment, account: account),
|
||||
Fabricate(:media_attachment, account: account),
|
||||
@ -162,8 +191,7 @@ RSpec.describe PostStatusService, type: :service do
|
||||
expect do
|
||||
subject.call(
|
||||
account,
|
||||
"test status update",
|
||||
nil,
|
||||
text: "test status update",
|
||||
media_ids: [
|
||||
Fabricate(:media_attachment, type: :video, account: account),
|
||||
Fabricate(:media_attachment, type: :image, account: account),
|
||||
@ -177,12 +205,12 @@ RSpec.describe PostStatusService, type: :service do
|
||||
|
||||
it 'returns existing status when used twice with idempotency key' do
|
||||
account = Fabricate(:account)
|
||||
status1 = subject.call(account, 'test', nil, idempotency: 'meepmeep')
|
||||
status2 = subject.call(account, 'test', nil, idempotency: 'meepmeep')
|
||||
status1 = subject.call(account, text: 'test', idempotency: 'meepmeep')
|
||||
status2 = subject.call(account, text: 'test', idempotency: 'meepmeep')
|
||||
expect(status2.id).to eq status1.id
|
||||
end
|
||||
|
||||
def create_status_with_options(**options)
|
||||
subject.call(Fabricate(:account), 'test', nil, options)
|
||||
subject.call(Fabricate(:account), options.merge(text: 'test'))
|
||||
end
|
||||
end
|
||||
|
||||
@ -19,7 +19,7 @@ RSpec.describe RemoveStatusService, type: :service do
|
||||
jeff.follow!(alice)
|
||||
hank.follow!(alice)
|
||||
|
||||
@status = PostStatusService.new.call(alice, 'Hello @bob@example.com')
|
||||
@status = PostStatusService.new.call(alice, text: 'Hello @bob@example.com')
|
||||
Fabricate(:status, account: bill, reblog: @status, uri: 'hoge')
|
||||
subject.call(@status)
|
||||
end
|
||||
|
||||
@ -119,8 +119,6 @@ RSpec.describe ResolveAccountService, type: :service do
|
||||
expect(account.actor_type).to eq 'Person'
|
||||
end
|
||||
end
|
||||
|
||||
pending
|
||||
end
|
||||
|
||||
it 'processes one remote account at a time using locks' do
|
||||
|
||||
31
spec/validators/blacklisted_email_validator_spec.rb
Normal file
31
spec/validators/blacklisted_email_validator_spec.rb
Normal file
@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe BlacklistedEmailValidator, type: :validator do
|
||||
describe '#validate' do
|
||||
let(:user) { double(email: 'info@mail.com', errors: errors) }
|
||||
let(:errors) { double(add: nil) }
|
||||
|
||||
before do
|
||||
allow_any_instance_of(described_class).to receive(:blocked_email?) { blocked_email }
|
||||
described_class.new.validate(user)
|
||||
end
|
||||
|
||||
context 'blocked_email?' do
|
||||
let(:blocked_email) { true }
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add).with(:email, I18n.t('users.invalid_email'))
|
||||
end
|
||||
end
|
||||
|
||||
context '!blocked_email?' do
|
||||
let(:blocked_email) { false }
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).not_to have_received(:add).with(:email, I18n.t('users.invalid_email'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
46
spec/validators/disallowed_hashtags_validator_spec.rb
Normal file
46
spec/validators/disallowed_hashtags_validator_spec.rb
Normal file
@ -0,0 +1,46 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe DisallowedHashtagsValidator, type: :validator do
|
||||
describe '#validate' do
|
||||
before do
|
||||
allow_any_instance_of(described_class).to receive(:select_tags) { tags }
|
||||
described_class.new.validate(status)
|
||||
end
|
||||
|
||||
let(:status) { double(errors: errors, local?: local, reblog?: reblog, text: '') }
|
||||
let(:errors) { double(add: nil) }
|
||||
|
||||
context 'unless status.local? && !status.reblog?' do
|
||||
let(:local) { false }
|
||||
let(:reblog) { true }
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).not_to have_received(:add).with(:text, any_args)
|
||||
end
|
||||
end
|
||||
|
||||
context 'status.local? && !status.reblog?' do
|
||||
let(:local) { true }
|
||||
let(:reblog) { false }
|
||||
|
||||
context 'tags.empty?' do
|
||||
let(:tags) { [] }
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).not_to have_received(:add).with(:text, any_args)
|
||||
end
|
||||
end
|
||||
|
||||
context '!tags.empty?' do
|
||||
let(:tags) { %w(a b c) }
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add)
|
||||
.with(:text, I18n.t('statuses.disallowed_hashtags', tags: tags.join(', '), count: tags.size))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
75
spec/validators/email_mx_validator_spec.rb
Normal file
75
spec/validators/email_mx_validator_spec.rb
Normal file
@ -0,0 +1,75 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe EmailMxValidator do
|
||||
describe '#validate' do
|
||||
let(:user) { double(email: 'foo@example.com', errors: double(add: nil)) }
|
||||
|
||||
it 'adds an error if there are no DNS records for the e-mail domain' do
|
||||
resolver = double
|
||||
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'adds an error if a MX record exists but does not lead to an IP' do
|
||||
resolver = double
|
||||
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([double(exchange: 'mail.example.com')])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'adds an error if the A record is blacklisted' do
|
||||
EmailDomainBlock.create!(domain: '1.2.3.4')
|
||||
resolver = double
|
||||
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([double(address: '1.2.3.4')])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'adds an error if the MX record is blacklisted' do
|
||||
EmailDomainBlock.create!(domain: '2.3.4.5')
|
||||
resolver = double
|
||||
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([double(exchange: 'mail.example.com')])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([double(address: '2.3.4.5')])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'adds an error if the MX hostname is blacklisted' do
|
||||
EmailDomainBlock.create!(domain: 'mail.example.com')
|
||||
resolver = double
|
||||
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([double(exchange: 'mail.example.com')])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([double(address: '2.3.4.5')])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to have_received(:add)
|
||||
end
|
||||
end
|
||||
end
|
||||
51
spec/validators/follow_limit_validator_spec.rb
Normal file
51
spec/validators/follow_limit_validator_spec.rb
Normal file
@ -0,0 +1,51 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe FollowLimitValidator, type: :validator do
|
||||
describe '#validate' do
|
||||
before do
|
||||
allow_any_instance_of(described_class).to receive(:limit_reached?).with(account) do
|
||||
limit_reached
|
||||
end
|
||||
|
||||
described_class.new.validate(follow)
|
||||
end
|
||||
|
||||
let(:follow) { double(account: account, errors: errors) }
|
||||
let(:errors) { double(add: nil) }
|
||||
let(:account) { double(nil?: _nil, local?: local, following_count: 0, followers_count: 0) }
|
||||
let(:_nil) { true }
|
||||
let(:local) { false }
|
||||
|
||||
context 'follow.account.nil? || !follow.account.local?' do
|
||||
let(:_nil) { true }
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).not_to have_received(:add).with(:base, any_args)
|
||||
end
|
||||
end
|
||||
|
||||
context '!(follow.account.nil? || !follow.account.local?)' do
|
||||
let(:_nil) { false }
|
||||
let(:local) { true }
|
||||
|
||||
context 'limit_reached?' do
|
||||
let(:limit_reached) { true }
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add)
|
||||
.with(:base, I18n.t('users.follow_limit_reached', limit: FollowLimitValidator::LIMIT))
|
||||
end
|
||||
end
|
||||
|
||||
context '!limit_reached?' do
|
||||
let(:limit_reached) { false }
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).not_to have_received(:add).with(:base, any_args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -4,8 +4,17 @@ require 'rails_helper'
|
||||
|
||||
describe StatusLengthValidator do
|
||||
describe '#validate' do
|
||||
it 'does not add errors onto remote statuses'
|
||||
it 'does not add errors onto local reblogs'
|
||||
it 'does not add errors onto remote statuses' do
|
||||
status = double(local?: false)
|
||||
subject.validate(status)
|
||||
expect(status).not_to receive(:errors)
|
||||
end
|
||||
|
||||
it 'does not add errors onto local reblogs' do
|
||||
status = double(local?: false, reblog?: true)
|
||||
subject.validate(status)
|
||||
expect(status).not_to receive(:errors)
|
||||
end
|
||||
|
||||
it 'adds an error when content warning is over 500 characters' do
|
||||
status = double(spoiler_text: 'a' * 520, text: '', errors: double(add: nil), local?: true, reblog?: false)
|
||||
|
||||
57
spec/validators/status_pin_validator_spec.rb
Normal file
57
spec/validators/status_pin_validator_spec.rb
Normal file
@ -0,0 +1,57 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe StatusPinValidator, type: :validator do
|
||||
describe '#validate' do
|
||||
before do
|
||||
subject.validate(pin)
|
||||
end
|
||||
|
||||
let(:pin) { double(account: account, errors: errors, status: status, account_id: pin_account_id) }
|
||||
let(:status) { double(reblog?: reblog, account_id: status_account_id, visibility: visibility) }
|
||||
let(:account) { double(status_pins: status_pins, local?: local) }
|
||||
let(:status_pins) { double(count: count) }
|
||||
let(:errors) { double(add: nil) }
|
||||
let(:pin_account_id) { 1 }
|
||||
let(:status_account_id) { 1 }
|
||||
let(:visibility) { 'public' }
|
||||
let(:local) { false }
|
||||
let(:reblog) { false }
|
||||
let(:count) { 0 }
|
||||
|
||||
context 'pin.status.reblog?' do
|
||||
let(:reblog) { true }
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add).with(:base, I18n.t('statuses.pin_errors.reblog'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'pin.account_id != pin.status.account_id' do
|
||||
let(:pin_account_id) { 1 }
|
||||
let(:status_account_id) { 2 }
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add).with(:base, I18n.t('statuses.pin_errors.ownership'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'unless %w(public unlisted).include?(pin.status.visibility)' do
|
||||
let(:visibility) { '' }
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add).with(:base, I18n.t('statuses.pin_errors.private'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'pin.account.status_pins.count > 4 && pin.account.local?' do
|
||||
let(:count) { 5 }
|
||||
let(:local) { true }
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add).with(:base, I18n.t('statuses.pin_errors.limit'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -15,14 +15,6 @@ describe UniqueUsernameValidator do
|
||||
expect(account).to be_valid
|
||||
end
|
||||
|
||||
it 'adds an error when the username is already used with ignoring dots' do
|
||||
pending 'allowing dots in username is still in development'
|
||||
Fabricate(:account, username: 'abcd.ef')
|
||||
account = double(username: 'ab.cdef', persisted?: false, errors: double(add: nil))
|
||||
subject.validate(account)
|
||||
expect(account.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'adds an error when the username is already used with ignoring cases' do
|
||||
Fabricate(:account, username: 'ABCdef')
|
||||
account = double(username: 'abcDEF', persisted?: false, errors: double(add: nil))
|
||||
|
||||
44
spec/validators/unreserved_username_validator_spec.rb
Normal file
44
spec/validators/unreserved_username_validator_spec.rb
Normal file
@ -0,0 +1,44 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe UnreservedUsernameValidator, type: :validator do
|
||||
describe '#validate' do
|
||||
before do
|
||||
allow(validator).to receive(:reserved_username?) { reserved_username }
|
||||
validator.validate(account)
|
||||
end
|
||||
|
||||
let(:validator) { described_class.new }
|
||||
let(:account) { double(username: username, errors: errors) }
|
||||
let(:errors ) { double(add: nil) }
|
||||
|
||||
context '@username.nil?' do
|
||||
let(:username) { nil }
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).not_to have_received(:add).with(:username, any_args)
|
||||
end
|
||||
end
|
||||
|
||||
context '!@username.nil?' do
|
||||
let(:username) { '' }
|
||||
|
||||
context 'reserved_username?' do
|
||||
let(:reserved_username) { true }
|
||||
|
||||
it 'calls erros.add' do
|
||||
expect(errors).to have_received(:add).with(:username, I18n.t('accounts.reserved_username'))
|
||||
end
|
||||
end
|
||||
|
||||
context '!reserved_username?' do
|
||||
let(:reserved_username) { false }
|
||||
|
||||
it 'not calls erros.add' do
|
||||
expect(errors).not_to have_received(:add).with(:username, any_args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
34
spec/validators/url_validator_spec.rb
Normal file
34
spec/validators/url_validator_spec.rb
Normal file
@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe UrlValidator, type: :validator do
|
||||
describe '#validate_each' do
|
||||
before do
|
||||
allow(validator).to receive(:compliant?).with(value) { compliant }
|
||||
validator.validate_each(record, attribute, value)
|
||||
end
|
||||
|
||||
let(:validator) { described_class.new(attributes: [attribute]) }
|
||||
let(:record) { double(errors: errors) }
|
||||
let(:errors) { double(add: nil) }
|
||||
let(:value) { '' }
|
||||
let(:attribute) { :foo }
|
||||
|
||||
context 'unless compliant?' do
|
||||
let(:compliant) { false }
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add).with(attribute, I18n.t('applications.invalid_url'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'if compliant?' do
|
||||
let(:compliant) { true }
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).not_to have_received(:add).with(attribute, any_args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
23
spec/workers/publish_scheduled_status_worker_spec.rb
Normal file
23
spec/workers/publish_scheduled_status_worker_spec.rb
Normal file
@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe PublishScheduledStatusWorker do
|
||||
subject { described_class.new }
|
||||
|
||||
let(:scheduled_status) { Fabricate(:scheduled_status, params: { text: 'Hello world, future!' }) }
|
||||
|
||||
describe 'perform' do
|
||||
before do
|
||||
subject.perform(scheduled_status.id)
|
||||
end
|
||||
|
||||
it 'creates a status' do
|
||||
expect(scheduled_status.account.statuses.first.text).to eq 'Hello world, future!'
|
||||
end
|
||||
|
||||
it 'removes the scheduled status' do
|
||||
expect(ScheduledStatus.find_by(id: scheduled_status.id)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user