mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-15 16:59:41 +00:00
Merge commit '877090518682b6c77ba9bdfa0231afd56daec44d' into glitch-soc/merge-upstream
Conflicts: - `app/models/concerns/user/has_settings.rb`: Not a real conflict, upstream added a setting textually close to a glitch-soc one. Added upstream's new setting. - `app/views/settings/preferences/appearance/show.html.haml`: Not a real conflict, upstream added a setting textually close to a glitch-soc one. Added upstream's new setting. - `config/routes.rb`: Upstream moved web app routes to `config/routes/web_app.rb`, while glitch-soc had an extra route. Moved the extra route to `config/routes/web_app.rb`. - `spec/controllers/settings/preferences/appearance_controller_spec.rb`: This spec got converted to a system spec upstream. However, the theme setting works differently in glitch-soc, so the spec had been changed. Changed the corresponding system spec as well.
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
inherit_from: ../../.rubocop.yml
|
||||
|
||||
# Anonymous controllers in specs cannot access `described_class`, explanation:
|
||||
# https://github.com/rubocop/rubocop-rspec/blob/v2.26.1/lib/rubocop/cop/rspec/described_class.rb#L36-L56
|
||||
RSpec/DescribedClass:
|
||||
SkipBlocks: true
|
||||
@@ -1,57 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::AccountModerationNotesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:target_account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
subject { post :create, params: params }
|
||||
|
||||
context 'when parameters are valid' do
|
||||
let(:params) { { account_moderation_note: { target_account_id: target_account.id, content: 'test content' } } }
|
||||
|
||||
it 'successfully creates a note' do
|
||||
expect { subject }.to change(AccountModerationNote, :count).by(1)
|
||||
expect(response).to redirect_to admin_account_path(target_account.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the content is too short' do
|
||||
let(:params) { { account_moderation_note: { target_account_id: target_account.id, content: '' } } }
|
||||
|
||||
it 'fails to create a note' do
|
||||
expect { subject }.to_not change(AccountModerationNote, :count)
|
||||
expect(response).to render_template 'admin/accounts/show'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the content is too long' do
|
||||
let(:params) { { account_moderation_note: { target_account_id: target_account.id, content: 'test' * AccountModerationNote::CONTENT_SIZE_LIMIT } } }
|
||||
|
||||
it 'fails to create a note' do
|
||||
expect { subject }.to_not change(AccountModerationNote, :count)
|
||||
expect(response).to render_template 'admin/accounts/show'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
subject { delete :destroy, params: { id: note.id } }
|
||||
|
||||
let!(:note) { Fabricate(:account_moderation_note, account: account, target_account: target_account) }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
it 'destroys note' do
|
||||
expect { subject }.to change(AccountModerationNote, :count).by(-1)
|
||||
expect(response).to redirect_to admin_account_path(target_account.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,57 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::CustomEmojisController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
before do
|
||||
Fabricate(:custom_emoji)
|
||||
end
|
||||
|
||||
it 'renders index page' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status 200
|
||||
expect(response).to render_template :index
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #new' do
|
||||
it 'renders new page' do
|
||||
get :new
|
||||
|
||||
expect(response).to have_http_status 200
|
||||
expect(response).to render_template :new
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
subject { post :create, params: { custom_emoji: params } }
|
||||
|
||||
let(:image) { fixture_file_upload(Rails.root.join('spec', 'fixtures', 'files', 'emojo.png'), 'image/png') }
|
||||
|
||||
context 'when parameter is valid' do
|
||||
let(:params) { { shortcode: 'test', image: image } }
|
||||
|
||||
it 'creates custom emoji' do
|
||||
expect { subject }.to change(CustomEmoji, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when parameter is invalid' do
|
||||
let(:params) { { shortcode: 't', image: image } }
|
||||
|
||||
it 'renders new' do
|
||||
expect(subject).to render_template :new
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,49 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::DomainAllowsController do
|
||||
render_views
|
||||
|
||||
before do
|
||||
sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #new' do
|
||||
it 'assigns a new domain allow' do
|
||||
get :new
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'blocks the domain when succeeded to save' do
|
||||
post :create, params: { domain_allow: { domain: 'example.com' } }
|
||||
|
||||
expect(flash[:notice]).to eq I18n.t('admin.domain_allows.created_msg')
|
||||
expect(response).to redirect_to(admin_instances_path)
|
||||
end
|
||||
|
||||
it 'renders new when failed to save' do
|
||||
Fabricate(:domain_allow, domain: 'example.com')
|
||||
|
||||
post :create, params: { domain_allow: { domain: 'example.com' } }
|
||||
|
||||
expect(response).to render_template :new
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
it 'disallows the domain' do
|
||||
service = instance_double(UnallowDomainService, call: true)
|
||||
allow(UnallowDomainService).to receive(:new).and_return(service)
|
||||
domain_allow = Fabricate(:domain_allow)
|
||||
delete :destroy, params: { id: domain_allow.id }
|
||||
|
||||
expect(service).to have_received(:call).with(domain_allow)
|
||||
expect(flash[:notice]).to eq I18n.t('admin.domain_allows.destroyed_msg')
|
||||
expect(response).to redirect_to(admin_instances_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -32,15 +32,16 @@ RSpec.describe Admin::ExportDomainAllowsController do
|
||||
it 'allows imported domains' do
|
||||
post :import, params: { admin_import: { data: fixture_file_upload('domain_allows.csv') } }
|
||||
|
||||
expect(response).to redirect_to(admin_instances_path)
|
||||
expect(response)
|
||||
.to redirect_to(admin_instances_path)
|
||||
|
||||
# Header should not be imported
|
||||
expect(DomainAllow.where(domain: '#domain').present?).to be(false)
|
||||
|
||||
# Domains should now be added
|
||||
get :export, params: { format: :csv }
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.body).to eq(domain_allows_csv_file)
|
||||
# Header row should not be imported, but domains should
|
||||
expect(DomainAllow)
|
||||
.to_not exist(domain: '#domain')
|
||||
expect(DomainAllow)
|
||||
.to exist(domain: 'good.domain')
|
||||
expect(DomainAllow)
|
||||
.to exist(domain: 'better.domain')
|
||||
end
|
||||
|
||||
it 'displays error on no file selected' do
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::IpBlocksController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #new' do
|
||||
it 'returns http success and renders view' do
|
||||
get :new
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to render_template(:new)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
context 'with valid data' do
|
||||
it 'creates a new ip block and redirects' do
|
||||
expect do
|
||||
post :create, params: { ip_block: { ip: '1.1.1.1', severity: 'no_access', expires_in: 1.day.to_i.to_s } }
|
||||
end.to change(IpBlock, :count).by(1)
|
||||
|
||||
expect(response).to redirect_to(admin_ip_blocks_path)
|
||||
expect(flash.notice).to match(I18n.t('admin.ip_blocks.created_msg'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid data' do
|
||||
it 'does not create new a ip block and renders new' do
|
||||
expect do
|
||||
post :create, params: { ip_block: { ip: '1.1.1.1' } }
|
||||
end.to_not change(IpBlock, :count)
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to render_template(:new)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::TermsOfService::DistributionsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:terms_of_service) { Fabricate(:terms_of_service, notification_sent_at: nil) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'returns http success' do
|
||||
post :create, params: { terms_of_service_id: terms_of_service.id }
|
||||
|
||||
expect(response).to redirect_to(admin_terms_of_service_index_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,66 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::TermsOfService::DraftsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
subject { put :update, params: params }
|
||||
|
||||
let!(:terms) { Fabricate :terms_of_service, published_at: nil }
|
||||
|
||||
context 'with publishing params' do
|
||||
let(:params) { { terms_of_service: { text: 'new' }, action_type: 'publish' } }
|
||||
|
||||
it 'publishes the record' do
|
||||
expect { subject }
|
||||
.to change(Admin::ActionLog, :count).by(1)
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(admin_terms_of_service_index_path)
|
||||
expect(terms.reload.published_at)
|
||||
.to_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'with non publishing params' do
|
||||
let(:params) { { terms_of_service: { text: 'new' }, action_type: 'save_draft' } }
|
||||
|
||||
it 'updates but does not publish the record' do
|
||||
expect { subject }
|
||||
.to_not change(Admin::ActionLog, :count)
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(admin_terms_of_service_draft_path)
|
||||
expect(terms.reload.published_at)
|
||||
.to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid params' do
|
||||
let(:params) { { terms_of_service: { text: '' }, action_type: 'save_draft' } }
|
||||
|
||||
it 'does not update the record' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,65 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::TermsOfService::GeneratesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
subject { post :create, params: params }
|
||||
|
||||
context 'with valid params' do
|
||||
let(:params) do
|
||||
{
|
||||
terms_of_service_generator: {
|
||||
admin_email: 'test@host.example',
|
||||
arbitration_address: '123 Main Street',
|
||||
arbitration_website: 'https://host.example',
|
||||
dmca_address: '123 DMCA Ave',
|
||||
dmca_email: 'dmca@host.example',
|
||||
domain: 'host.example',
|
||||
jurisdiction: 'Europe',
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
it 'saves new record' do
|
||||
expect { subject }
|
||||
.to change(TermsOfService, :count).by(1)
|
||||
expect(response)
|
||||
.to redirect_to(admin_terms_of_service_draft_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid params' do
|
||||
let(:params) do
|
||||
{
|
||||
terms_of_service_generator: {
|
||||
admin_email: 'what the',
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
it 'does not save new record' do
|
||||
expect { subject }
|
||||
.to_not change(TermsOfService, :count)
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::TermsOfService::HistoriesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::TermsOfService::PreviewsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:terms_of_service) { Fabricate(:terms_of_service, notification_sent_at: nil) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show, params: { terms_of_service_id: terms_of_service.id }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::TermsOfService::TestsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:terms_of_service) { Fabricate(:terms_of_service, notification_sent_at: nil) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'returns http success' do
|
||||
post :create, params: { terms_of_service_id: terms_of_service.id }
|
||||
|
||||
expect(response).to redirect_to(admin_terms_of_service_preview_path(terms_of_service))
|
||||
end
|
||||
end
|
||||
end
|
||||
21
spec/controllers/admin/terms_of_service_controller_spec.rb
Normal file
21
spec/controllers/admin/terms_of_service_controller_spec.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::TermsOfServiceController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,117 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::WebhooksController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #new' do
|
||||
it 'returns http success and renders view' do
|
||||
get :new
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to render_template(:new)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'creates a new webhook record with valid data' do
|
||||
expect do
|
||||
post :create, params: { webhook: { url: 'https://example.com/hook', events: ['account.approved'] } }
|
||||
end.to change(Webhook, :count).by(1)
|
||||
|
||||
expect(response).to be_redirect
|
||||
end
|
||||
|
||||
it 'does not create a new webhook record with invalid data' do
|
||||
expect do
|
||||
post :create, params: { webhook: { url: 'https://example.com/hook', events: [] } }
|
||||
end.to_not change(Webhook, :count)
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to render_template(:new)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an existing record' do
|
||||
let!(:webhook) { Fabricate(:webhook, events: ['account.created', 'report.created']) }
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success and renders view' do
|
||||
get :show, params: { id: webhook.id }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to render_template(:show)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #edit' do
|
||||
it 'returns http success and renders view' do
|
||||
get :edit, params: { id: webhook.id }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to render_template(:edit)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
it 'updates the record with valid data' do
|
||||
put :update, params: { id: webhook.id, webhook: { url: 'https://example.com/new/location' } }
|
||||
|
||||
expect(webhook.reload.url).to match(%r{new/location})
|
||||
expect(response).to redirect_to(admin_webhook_path(webhook))
|
||||
end
|
||||
|
||||
it 'does not update the record with invalid data' do
|
||||
expect do
|
||||
put :update, params: { id: webhook.id, webhook: { url: '' } }
|
||||
end.to_not change(webhook, :url)
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to render_template(:edit)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #enable' do
|
||||
it 'enables the webhook' do
|
||||
post :enable, params: { id: webhook.id }
|
||||
|
||||
expect(webhook.reload).to be_enabled
|
||||
expect(response).to redirect_to(admin_webhook_path(webhook))
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #disable' do
|
||||
it 'disables the webhook' do
|
||||
post :disable, params: { id: webhook.id }
|
||||
|
||||
expect(webhook.reload).to_not be_enabled
|
||||
expect(response).to redirect_to(admin_webhook_path(webhook))
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
it 'destroys the record' do
|
||||
expect do
|
||||
delete :destroy, params: { id: webhook.id }
|
||||
end.to change(Webhook, :count).by(-1)
|
||||
|
||||
expect(response).to redirect_to(admin_webhooks_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4,7 +4,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountControllerConcern do
|
||||
controller(ApplicationController) do
|
||||
include AccountControllerConcern
|
||||
include AccountControllerConcern # rubocop:disable RSpec/DescribedClass
|
||||
|
||||
def success
|
||||
render plain: @account.username # rubocop:disable RSpec/InstanceVariable
|
||||
|
||||
@@ -4,7 +4,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::RateLimitHeaders do
|
||||
controller(ApplicationController) do
|
||||
include Api::RateLimitHeaders
|
||||
include Api::RateLimitHeaders # rubocop:disable RSpec/DescribedClass
|
||||
|
||||
def show
|
||||
head 200
|
||||
|
||||
@@ -4,7 +4,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe ChallengableConcern do
|
||||
controller(ApplicationController) do
|
||||
include ChallengableConcern
|
||||
include ChallengableConcern # rubocop:disable RSpec/DescribedClass
|
||||
|
||||
before_action :require_challenge!
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe Localized do
|
||||
controller(ApplicationController) do
|
||||
include Localized
|
||||
include Localized # rubocop:disable RSpec/DescribedClass
|
||||
|
||||
def success
|
||||
render plain: I18n.locale, status: 200
|
||||
|
||||
@@ -4,7 +4,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe PreloadingConcern do
|
||||
controller(ApplicationController) do
|
||||
include PreloadingConcern
|
||||
include PreloadingConcern # rubocop:disable RSpec/DescribedClass
|
||||
|
||||
def empty_array
|
||||
render plain: preload_collection([], Status).size
|
||||
|
||||
@@ -4,7 +4,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::ExportControllerConcern do
|
||||
controller(ApplicationController) do
|
||||
include Settings::ExportControllerConcern
|
||||
include Settings::ExportControllerConcern # rubocop:disable RSpec/DescribedClass
|
||||
|
||||
def index
|
||||
send_export_file
|
||||
|
||||
@@ -4,7 +4,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe UserTrackingConcern do
|
||||
controller(ApplicationController) do
|
||||
include UserTrackingConcern
|
||||
include UserTrackingConcern # rubocop:disable RSpec/DescribedClass
|
||||
|
||||
def show
|
||||
render plain: 'show'
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe FiltersController do
|
||||
render_views
|
||||
|
||||
describe 'GET #index' do
|
||||
context 'with signed out user' do
|
||||
before do
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'redirects' do
|
||||
expect(response).to be_redirect
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a signed in user' do
|
||||
before do
|
||||
sign_in(Fabricate(:user))
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,29 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::LoginActivitiesController do
|
||||
render_views
|
||||
|
||||
let!(:user) { Fabricate(:user) }
|
||||
let!(:login_activity) { Fabricate :login_activity, user: user }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
before do
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns http success with private cache control headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
expect(response.body)
|
||||
.to include(login_activity.user_agent)
|
||||
.and include(login_activity.authentication_method)
|
||||
.and include(login_activity.ip.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,35 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::Preferences::AppearanceController do
|
||||
render_views
|
||||
|
||||
let!(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success with private cache control headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
subject { put :update, params: { user: { settings_attributes: { skin: 'contrast' } } } }
|
||||
|
||||
it 'redirects correctly' do
|
||||
expect { subject }
|
||||
.to change { user.reload.settings.skin }.to('contrast')
|
||||
|
||||
expect(response).to redirect_to(settings_preferences_appearance_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,43 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::Preferences::NotificationsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success with private cache control headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
it 'updates notifications settings' do
|
||||
user.settings.update('notification_emails.follow': false)
|
||||
user.save
|
||||
|
||||
put :update, params: {
|
||||
user: {
|
||||
settings_attributes: {
|
||||
'notification_emails.follow': '1',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expect(response).to redirect_to(settings_preferences_notifications_path)
|
||||
user.reload
|
||||
expect(user.settings['notification_emails.follow']).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,54 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::Preferences::OtherController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, chosen_languages: []) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success with private cache control headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
it 'updates the user record' do
|
||||
put :update, params: { user: { locale: 'en', chosen_languages: ['es', 'fr', ''] } }
|
||||
|
||||
expect(response).to redirect_to(settings_preferences_other_path)
|
||||
user.reload
|
||||
expect(user.locale).to eq 'en'
|
||||
expect(user.chosen_languages).to eq %w(es fr)
|
||||
end
|
||||
|
||||
it 'updates user settings' do
|
||||
user.settings.update('web.reblog_modal': false, 'web.delete_modal': true)
|
||||
user.save
|
||||
|
||||
put :update, params: {
|
||||
user: {
|
||||
settings_attributes: {
|
||||
'web.reblog_modal': '1',
|
||||
'web.delete_modal': '0',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expect(response).to redirect_to(settings_preferences_other_path)
|
||||
user.reload
|
||||
expect(user.settings['web.reblog_modal']).to be true
|
||||
expect(user.settings['web.delete_modal']).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,51 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::ProfilesController do
|
||||
render_views
|
||||
|
||||
let!(:user) { Fabricate(:user) }
|
||||
let(:account) { user.account }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success with private cache control headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
before do
|
||||
user.account.update(display_name: 'Old name')
|
||||
end
|
||||
|
||||
it 'updates the user profile' do
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
|
||||
put :update, params: { account: { display_name: 'New name' } }
|
||||
expect(account.reload.display_name).to eq 'New name'
|
||||
expect(response).to redirect_to(settings_profile_path)
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update with new profile image' do
|
||||
it 'updates profile image' do
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
|
||||
expect(account.avatar.instance.avatar_file_name).to be_nil
|
||||
|
||||
put :update, params: { account: { avatar: fixture_file_upload('avatar.gif', 'image/gif') } }
|
||||
expect(response).to redirect_to(settings_profile_path)
|
||||
expect(account.reload.avatar.instance.avatar_file_name).to_not be_nil
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,29 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::VerificationsController do
|
||||
render_views
|
||||
|
||||
let!(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success with private cache control headers', :aggregate_failures do
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
.and have_attributes(
|
||||
headers: include(
|
||||
'Cache-Control' => 'private, no-store'
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,43 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe StatusesCleanupController do
|
||||
render_views
|
||||
|
||||
let!(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
before do
|
||||
put :update, params: { account_statuses_cleanup_policy: { enabled: true, min_status_age: 2.weeks.seconds, keep_direct: false, keep_polls: true } }
|
||||
end
|
||||
|
||||
it 'updates the account status cleanup policy' do
|
||||
expect(user.account.statuses_cleanup_policy.enabled).to be true
|
||||
expect(user.account.statuses_cleanup_policy.keep_direct).to be false
|
||||
expect(user.account.statuses_cleanup_policy.keep_polls).to be true
|
||||
end
|
||||
|
||||
it 'redirects' do
|
||||
expect(response).to redirect_to(statuses_cleanup_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -527,213 +527,4 @@ RSpec.describe StatusesController do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #activity' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:status) { Fabricate(:status, account: account) }
|
||||
|
||||
context 'when account is permanently suspended' do
|
||||
before do
|
||||
account.suspend!
|
||||
account.deletion_request.destroy
|
||||
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http gone' do
|
||||
expect(response).to have_http_status(410)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account is temporarily suspended' do
|
||||
before do
|
||||
account.suspend!
|
||||
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is public' do
|
||||
before do
|
||||
status.update(visibility: :public)
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is private' do
|
||||
before do
|
||||
status.update(visibility: :private)
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http not_found' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is direct' do
|
||||
before do
|
||||
status.update(visibility: :direct)
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http not_found' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when signed-in' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
context 'when status is public' do
|
||||
before do
|
||||
status.update(visibility: :public)
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is private' do
|
||||
before do
|
||||
status.update(visibility: :private)
|
||||
end
|
||||
|
||||
context 'when user is authorized to see it' do
|
||||
before do
|
||||
user.account.follow!(account)
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not authorized to see it' do
|
||||
before do
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http not_found' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is direct' do
|
||||
before do
|
||||
status.update(visibility: :direct)
|
||||
end
|
||||
|
||||
context 'when user is authorized to see it' do
|
||||
before do
|
||||
Fabricate(:mention, account: user.account, status: status)
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not authorized to see it' do
|
||||
before do
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http not_found' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with signature' do
|
||||
let(:remote_account) { Fabricate(:account, domain: 'example.com') }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:signed_request_actor).and_return(remote_account)
|
||||
end
|
||||
|
||||
context 'when status is public' do
|
||||
before do
|
||||
status.update(visibility: :public)
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is private' do
|
||||
before do
|
||||
status.update(visibility: :private)
|
||||
end
|
||||
|
||||
context 'when user is authorized to see it' do
|
||||
before do
|
||||
remote_account.follow!(account)
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not authorized to see it' do
|
||||
before do
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http not_found' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is direct' do
|
||||
before do
|
||||
status.update(visibility: :direct)
|
||||
end
|
||||
|
||||
context 'when user is authorized to see it' do
|
||||
before do
|
||||
Fabricate(:mention, account: remote_account, status: status)
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not authorized to see it' do
|
||||
before do
|
||||
get :activity, params: { account_username: account.username, id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http not_found' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:setting) do
|
||||
var 'var'
|
||||
var { sequence(:var) { |n| "var_#{n}" } }
|
||||
end
|
||||
|
||||
5
spec/fabricators/status_edit_fabricator.rb
Normal file
5
spec/fabricators/status_edit_fabricator.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:status_edit) do
|
||||
status { Fabricate.build(:status) }
|
||||
end
|
||||
5
spec/fabricators/tag_trend_fabricator.rb
Normal file
5
spec/fabricators/tag_trend_fabricator.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:tag_trend) do
|
||||
tag
|
||||
end
|
||||
8
spec/fabricators/terms_of_service_fabricator.rb
Normal file
8
spec/fabricators/terms_of_service_fabricator.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:terms_of_service) do
|
||||
text { Faker::Lorem.paragraph }
|
||||
changelog { Faker::Lorem.paragraph }
|
||||
published_at { Time.zone.now }
|
||||
notification_sent_at { Time.zone.now }
|
||||
end
|
||||
@@ -160,10 +160,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
context 'when fetching' do
|
||||
subject { described_class.new(json, sender) }
|
||||
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
|
||||
context 'when object publication date is below ISO8601 range' do
|
||||
let(:object_json) do
|
||||
{
|
||||
@@ -175,6 +171,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status with a valid creation date', :aggregate_failures do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -195,6 +193,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status with a valid creation date', :aggregate_failures do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -216,6 +216,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status with appropriate creation and edition dates', :aggregate_failures do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -239,17 +241,13 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
it 'creates status and does not mark it as edited' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.text).to eq 'Lorem ipsum'
|
||||
end
|
||||
|
||||
it 'does not mark status as edited' do
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.edited?).to be false
|
||||
end
|
||||
end
|
||||
@@ -264,7 +262,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'does not create a status' do
|
||||
expect(sender.statuses.count).to be_zero
|
||||
expect { subject.perform }.to_not change(sender.statuses, :count)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -278,6 +276,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -285,6 +285,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'missing to/cc defaults to direct privacy' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -303,6 +305,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -321,6 +325,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -339,6 +345,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -357,6 +365,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -375,6 +385,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -393,6 +405,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -411,6 +425,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -433,6 +449,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -452,15 +470,13 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
it 'creates status with a silent mention' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.visibility).to eq 'limited'
|
||||
end
|
||||
|
||||
it 'creates silent mention' do
|
||||
status = sender.statuses.first
|
||||
expect(status.mentions.first).to be_silent
|
||||
end
|
||||
end
|
||||
@@ -483,6 +499,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status with limited visibility' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -507,6 +525,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status with direct visibility' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -528,6 +548,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -548,6 +570,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -576,6 +600,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -598,6 +624,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
expect(status).to_not be_nil
|
||||
end
|
||||
@@ -625,6 +653,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status with correctly-ordered media attachments' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -651,6 +681,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -676,6 +708,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -701,6 +735,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -724,6 +760,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
expect(status).to_not be_nil
|
||||
end
|
||||
@@ -746,6 +784,42 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.tags.map(&:name)).to include('test')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with featured hashtags' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
type: 'Note',
|
||||
content: 'Lorem ipsum',
|
||||
to: 'https://www.w3.org/ns/activitystreams#Public',
|
||||
tag: [
|
||||
{
|
||||
type: 'Hashtag',
|
||||
href: 'http://example.com/blah',
|
||||
name: '#test',
|
||||
},
|
||||
],
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
sender.featured_tags.create!(name: 'test')
|
||||
end
|
||||
|
||||
it 'creates status and updates featured tag' do
|
||||
expect { subject.perform }
|
||||
.to change(sender.statuses, :count).by(1)
|
||||
.and change { sender.featured_tags.first.reload.statuses_count }.by(1)
|
||||
.and change { sender.featured_tags.first.reload.last_status_at }.from(nil).to(be_within(0.1).of(Time.now.utc))
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -769,6 +843,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
expect(status).to_not be_nil
|
||||
end
|
||||
@@ -791,6 +867,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
expect(status).to_not be_nil
|
||||
end
|
||||
@@ -815,6 +893,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -841,6 +921,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@@ -866,6 +948,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
expect(status).to_not be_nil
|
||||
end
|
||||
@@ -887,6 +971,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
expect(status).to_not be_nil
|
||||
end
|
||||
@@ -917,13 +1003,13 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
it 'creates status with a poll' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
expect(status).to_not be_nil
|
||||
expect(status.poll).to_not be_nil
|
||||
end
|
||||
|
||||
it 'creates a poll' do
|
||||
poll = sender.polls.first
|
||||
expect(poll).to_not be_nil
|
||||
expect(poll.status).to_not be_nil
|
||||
@@ -946,6 +1032,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'adds a vote to the poll with correct uri' do
|
||||
expect { subject.perform }.to change(poll.votes, :count).by(1)
|
||||
|
||||
vote = poll.votes.first
|
||||
expect(vote).to_not be_nil
|
||||
expect(vote.uri).to eq object_json[:id]
|
||||
@@ -955,9 +1043,9 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
|
||||
context 'when a vote to an expired local poll' do
|
||||
let(:poll) do
|
||||
poll = Fabricate.build(:poll, options: %w(Yellow Blue), expires_at: 1.day.ago)
|
||||
poll.save(validate: false)
|
||||
poll
|
||||
travel_to 2.days.ago do
|
||||
Fabricate(:poll, options: %w(Yellow Blue), expires_at: 1.day.from_now)
|
||||
end
|
||||
end
|
||||
let!(:local_status) { Fabricate(:status, poll: poll) }
|
||||
|
||||
@@ -971,6 +1059,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'does not add a vote to the poll' do
|
||||
expect { subject.perform }.to_not change(poll.votes, :count)
|
||||
|
||||
expect(poll.votes.first).to be_nil
|
||||
end
|
||||
end
|
||||
@@ -995,6 +1085,8 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
|
||||
it 'uses the counts from the created object' do
|
||||
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||
|
||||
status = sender.statuses.first
|
||||
expect(status.untrusted_favourites_count).to eq 50
|
||||
expect(status.untrusted_reblogs_count).to eq 100
|
||||
|
||||
@@ -37,15 +37,15 @@ RSpec.describe Sanitize::Config do
|
||||
end
|
||||
|
||||
it 'keeps a with href' do
|
||||
expect(Sanitize.fragment('<a href="http://example.com">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
|
||||
expect(Sanitize.fragment('<a href="http://example.com">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener" target="_blank">Test</a>'
|
||||
end
|
||||
|
||||
it 'keeps a with translate="no"' do
|
||||
expect(Sanitize.fragment('<a href="http://example.com" translate="no">Test</a>', subject)).to eq '<a href="http://example.com" translate="no" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
|
||||
expect(Sanitize.fragment('<a href="http://example.com" translate="no">Test</a>', subject)).to eq '<a href="http://example.com" translate="no" rel="nofollow noopener" target="_blank">Test</a>'
|
||||
end
|
||||
|
||||
it 'removes "translate" attribute with invalid value' do
|
||||
expect(Sanitize.fragment('<a href="http://example.com" translate="foo">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
|
||||
expect(Sanitize.fragment('<a href="http://example.com" translate="foo">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener" target="_blank">Test</a>'
|
||||
end
|
||||
|
||||
it 'removes a with unparsable href' do
|
||||
@@ -53,7 +53,7 @@ RSpec.describe Sanitize::Config do
|
||||
end
|
||||
|
||||
it 'keeps a with supported scheme and no host' do
|
||||
expect(Sanitize.fragment('<a href="dweb:/a/foo">Test</a>', subject)).to eq '<a href="dweb:/a/foo" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
|
||||
expect(Sanitize.fragment('<a href="dweb:/a/foo">Test</a>', subject)).to eq '<a href="dweb:/a/foo" rel="nofollow noopener" target="_blank">Test</a>'
|
||||
end
|
||||
|
||||
it 'keeps title in abbr' do
|
||||
|
||||
@@ -50,7 +50,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given a stand-alone google URL' do
|
||||
context 'when given a stand-alone Google URL' do
|
||||
let(:text) { 'http://google.com' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@@ -280,6 +280,26 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given a lengthy URL' do
|
||||
let(:text) { 'lorem https://prepitaph.org/wip/web-dovespair/ ipsum' }
|
||||
|
||||
it 'truncates the URL' do
|
||||
expect(subject).to include '<span class="invisible">https://</span>'
|
||||
expect(subject).to include '<span class="ellipsis">prepitaph.org/wip/web-dovespai</span>'
|
||||
expect(subject).to include '<span class="invisible">r/</span>'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given a sufficiently short URL' do
|
||||
let(:text) { 'lorem https://prepitaph.org/wip/web-devspair/ ipsum' }
|
||||
|
||||
it 'does not truncate the URL' do
|
||||
expect(subject).to include '<span class="invisible">https://</span>'
|
||||
expect(subject).to include '<span class="">prepitaph.org/wip/web-devspair/</span>'
|
||||
expect(subject).to include '<span class="invisible"></span>'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given text containing a hashtag' do
|
||||
let(:text) { '#hashtag' }
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ RSpec.describe AdminMailer do
|
||||
before do
|
||||
PreviewCardTrend.create!(preview_card: link)
|
||||
StatusTrend.create!(status: status, account: Fabricate(:account))
|
||||
TagTrend.create!(tag: tag)
|
||||
recipient.user.update(locale: :en)
|
||||
end
|
||||
|
||||
|
||||
@@ -98,4 +98,9 @@ class UserMailerPreview < ActionMailer::Preview
|
||||
def failed_2fa
|
||||
UserMailer.failed_2fa(User.first, '127.0.0.1', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0', Time.now.utc)
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/user_mailer/terms_of_service_changed
|
||||
def terms_of_service_changed
|
||||
UserMailer.terms_of_service_changed(User.first, TermsOfService.live.first)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,17 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe UserMailer do
|
||||
shared_examples 'delivery to memorialized user' do
|
||||
context 'when the account is memorialized' do
|
||||
before { receiver.account.update(memorial: true) }
|
||||
|
||||
it 'does not deliver mail' do
|
||||
emails = capture_emails { mail.deliver_now }
|
||||
expect(emails).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:receiver) { Fabricate(:user) }
|
||||
|
||||
describe '#confirmation_instructions' do
|
||||
@@ -21,6 +32,7 @@ RSpec.describe UserMailer do
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.confirmation_instructions.subject',
|
||||
instance: Rails.configuration.x.local_domain
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#reconfirmation_instructions' do
|
||||
@@ -39,6 +51,7 @@ RSpec.describe UserMailer do
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.confirmation_instructions.subject',
|
||||
instance: Rails.configuration.x.local_domain
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#reset_password_instructions' do
|
||||
@@ -55,6 +68,7 @@ RSpec.describe UserMailer do
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.reset_password_instructions.subject'
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#password_change' do
|
||||
@@ -70,6 +84,7 @@ RSpec.describe UserMailer do
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.password_change.subject'
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#email_changed' do
|
||||
@@ -85,6 +100,7 @@ RSpec.describe UserMailer do
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.email_changed.subject'
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#warning' do
|
||||
@@ -115,6 +131,7 @@ RSpec.describe UserMailer do
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.webauthn_credential.deleted.subject'
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#suspicious_sign_in' do
|
||||
@@ -186,6 +203,8 @@ RSpec.describe UserMailer do
|
||||
.and(have_subject(I18n.t('devise.mailer.two_factor_enabled.subject')))
|
||||
.and(have_body_text(I18n.t('devise.mailer.two_factor_enabled.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#two_factor_disabled' do
|
||||
@@ -197,6 +216,8 @@ RSpec.describe UserMailer do
|
||||
.and(have_subject(I18n.t('devise.mailer.two_factor_disabled.subject')))
|
||||
.and(have_body_text(I18n.t('devise.mailer.two_factor_disabled.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#webauthn_enabled' do
|
||||
@@ -208,6 +229,8 @@ RSpec.describe UserMailer do
|
||||
.and(have_subject(I18n.t('devise.mailer.webauthn_enabled.subject')))
|
||||
.and(have_body_text(I18n.t('devise.mailer.webauthn_enabled.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#webauthn_disabled' do
|
||||
@@ -219,6 +242,8 @@ RSpec.describe UserMailer do
|
||||
.and(have_subject(I18n.t('devise.mailer.webauthn_disabled.subject')))
|
||||
.and(have_body_text(I18n.t('devise.mailer.webauthn_disabled.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#two_factor_recovery_codes_changed' do
|
||||
@@ -230,6 +255,8 @@ RSpec.describe UserMailer do
|
||||
.and(have_subject(I18n.t('devise.mailer.two_factor_recovery_codes_changed.subject')))
|
||||
.and(have_body_text(I18n.t('devise.mailer.two_factor_recovery_codes_changed.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#webauthn_credential_added' do
|
||||
@@ -242,6 +269,8 @@ RSpec.describe UserMailer do
|
||||
.and(have_subject(I18n.t('devise.mailer.webauthn_credential.added.subject')))
|
||||
.and(have_body_text(I18n.t('devise.mailer.webauthn_credential.added.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#welcome' do
|
||||
@@ -259,6 +288,8 @@ RSpec.describe UserMailer do
|
||||
.and(have_subject(I18n.t('user_mailer.welcome.subject')))
|
||||
.and(have_body_text(I18n.t('user_mailer.welcome.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#backup_ready' do
|
||||
@@ -271,5 +302,19 @@ RSpec.describe UserMailer do
|
||||
.and(have_subject(I18n.t('user_mailer.backup_ready.subject')))
|
||||
.and(have_body_text(I18n.t('user_mailer.backup_ready.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#terms_of_service_changed' do
|
||||
let(:terms) { Fabricate :terms_of_service }
|
||||
let(:mail) { described_class.terms_of_service_changed(receiver, terms) }
|
||||
|
||||
it 'renders terms_of_service_changed mail' do
|
||||
expect(mail)
|
||||
.to be_present
|
||||
.and(have_subject(I18n.t('user_mailer.terms_of_service_changed.subject')))
|
||||
.and(have_body_text(I18n.t('user_mailer.terms_of_service_changed.changelog')))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
33
spec/models/account_pin_spec.rb
Normal file
33
spec/models/account_pin_spec.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountPin do
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:account).required }
|
||||
it { is_expected.to belong_to(:target_account).required }
|
||||
end
|
||||
|
||||
describe 'Validations' do
|
||||
describe 'the follow relationship' do
|
||||
subject { Fabricate.build :account_pin, account: account }
|
||||
|
||||
let(:account) { Fabricate :account }
|
||||
let(:target_account) { Fabricate :account }
|
||||
|
||||
context 'when account is following target account' do
|
||||
before { account.follow!(target_account) }
|
||||
|
||||
it { is_expected.to allow_value(target_account).for(:target_account).against(:base) }
|
||||
end
|
||||
|
||||
context 'when account is not following target account' do
|
||||
it { is_expected.to_not allow_value(target_account).for(:target_account).against(:base).with_message(not_following_message) }
|
||||
|
||||
def not_following_message
|
||||
I18n.t('accounts.pin_errors.following')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -129,8 +129,8 @@ RSpec.describe AccountStatusesCleanupPolicy do
|
||||
let(:account_statuses_cleanup_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) }
|
||||
|
||||
it 'records the given id' do
|
||||
account_statuses_cleanup_policy.record_last_inspected(42)
|
||||
expect(account_statuses_cleanup_policy.last_inspected).to eq 42
|
||||
expect { account_statuses_cleanup_policy.record_last_inspected(42) }
|
||||
.to change(account_statuses_cleanup_policy, :last_inspected).from(nil).to(42)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -153,8 +153,8 @@ RSpec.describe AccountStatusesCleanupPolicy do
|
||||
end
|
||||
|
||||
it 'does not change the recorded id' do
|
||||
subject
|
||||
expect(account_statuses_cleanup_policy.last_inspected).to eq 42
|
||||
expect { subject }
|
||||
.to_not change(account_statuses_cleanup_policy, :last_inspected).from(42)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -164,8 +164,8 @@ RSpec.describe AccountStatusesCleanupPolicy do
|
||||
end
|
||||
|
||||
it 'records the older id' do
|
||||
subject
|
||||
expect(account_statuses_cleanup_policy.last_inspected).to eq 10
|
||||
expect { subject }
|
||||
.to change(account_statuses_cleanup_policy, :last_inspected).from(42).to(10)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -179,8 +179,8 @@ RSpec.describe AccountStatusesCleanupPolicy do
|
||||
end
|
||||
|
||||
it 'does not change the recorded id' do
|
||||
subject
|
||||
expect(account_statuses_cleanup_policy.last_inspected).to eq 42
|
||||
expect { subject }
|
||||
.to_not change(account_statuses_cleanup_policy, :last_inspected).from(42)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -190,8 +190,8 @@ RSpec.describe AccountStatusesCleanupPolicy do
|
||||
end
|
||||
|
||||
it 'records the older id' do
|
||||
subject
|
||||
expect(account_statuses_cleanup_policy.last_inspected).to eq 10
|
||||
expect { subject }
|
||||
.to change(account_statuses_cleanup_policy, :last_inspected).from(42).to(10)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -205,8 +205,8 @@ RSpec.describe AccountStatusesCleanupPolicy do
|
||||
end
|
||||
|
||||
it 'does not change the recorded id' do
|
||||
subject
|
||||
expect(account_statuses_cleanup_policy.last_inspected).to eq 42
|
||||
expect { subject }
|
||||
.to_not change(account_statuses_cleanup_policy, :last_inspected).from(42)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -216,8 +216,8 @@ RSpec.describe AccountStatusesCleanupPolicy do
|
||||
end
|
||||
|
||||
it 'records the older id' do
|
||||
subject
|
||||
expect(account_statuses_cleanup_policy.last_inspected).to eq 10
|
||||
expect { subject }
|
||||
.to change(account_statuses_cleanup_policy, :last_inspected).from(42).to(10)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -227,8 +227,8 @@ RSpec.describe AccountStatusesCleanupPolicy do
|
||||
let(:status) { Fabricate(:status, account: account) }
|
||||
|
||||
it 'does not change the recorded id' do
|
||||
subject
|
||||
expect(account_statuses_cleanup_policy.last_inspected).to eq 42
|
||||
expect { subject }
|
||||
.to_not change(account_statuses_cleanup_policy, :last_inspected).from(42)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,23 +3,14 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe CustomFilter do
|
||||
include_examples 'Expireable'
|
||||
|
||||
describe 'Validations' do
|
||||
it { is_expected.to validate_presence_of(:title) }
|
||||
it { is_expected.to validate_presence_of(:context) }
|
||||
|
||||
it 'requires non-empty of context' do
|
||||
record = described_class.new(context: [])
|
||||
record.valid?
|
||||
|
||||
expect(record).to model_have_error_on_field(:context)
|
||||
end
|
||||
|
||||
it 'requires valid context value' do
|
||||
record = described_class.new(context: ['invalid'])
|
||||
record.valid?
|
||||
|
||||
expect(record).to model_have_error_on_field(:context)
|
||||
end
|
||||
it { is_expected.to_not allow_values([], %w(invalid)).for(:context) }
|
||||
it { is_expected.to allow_values(%w(home)).for(:context) }
|
||||
end
|
||||
|
||||
describe 'Normalizations' do
|
||||
@@ -27,4 +18,28 @@ RSpec.describe CustomFilter do
|
||||
it { is_expected.to normalize(:context).from(['home', 'notifications', 'public ', '']).to(%w(home notifications public)) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expires_in' do
|
||||
subject { custom_filter.expires_in }
|
||||
|
||||
let(:custom_filter) { Fabricate.build(:custom_filter, expires_at: expires_at) }
|
||||
|
||||
context 'when expires_at is nil' do
|
||||
let(:expires_at) { nil }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when expires is beyond the end of the range' do
|
||||
let(:expires_at) { described_class::EXPIRATION_DURATIONS.last.from_now + 2.days }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when expires is before the start of the range' do
|
||||
let(:expires_at) { described_class::EXPIRATION_DURATIONS.first.from_now - 10.minutes }
|
||||
|
||||
it { is_expected.to eq(described_class::EXPIRATION_DURATIONS.first) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -61,10 +61,7 @@ RSpec.describe Form::Import do
|
||||
let(:import_type) { 'following' }
|
||||
let(:import_file) { 'boop.ogg' }
|
||||
|
||||
it 'has errors' do
|
||||
# NOTE: not testing more specific error because we don't know the string to match
|
||||
expect(subject).to model_have_error_on_field(:data)
|
||||
end
|
||||
it { is_expected.to_not allow_value(data).for(:data) }
|
||||
end
|
||||
|
||||
context 'when importing more follows than allowed' do
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Invite do
|
||||
include_examples 'Expireable'
|
||||
|
||||
describe '#valid_for_use?' do
|
||||
it 'returns true when there are no limitations' do
|
||||
invite = Fabricate(:invite, max_uses: nil, expires_at: nil)
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe IpBlock do
|
||||
include_examples 'Expireable'
|
||||
|
||||
describe 'Validations' do
|
||||
subject { Fabricate.build :ip_block }
|
||||
|
||||
|
||||
@@ -3,8 +3,14 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Mention do
|
||||
describe 'validations' do
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:account).required }
|
||||
it { is_expected.to belong_to(:status).required }
|
||||
end
|
||||
|
||||
describe 'Validations' do
|
||||
subject { Fabricate.build :mention }
|
||||
|
||||
it { is_expected.to validate_uniqueness_of(:account_id).scoped_to(:status_id) }
|
||||
end
|
||||
end
|
||||
|
||||
18
spec/models/mute_spec.rb
Normal file
18
spec/models/mute_spec.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Mute do
|
||||
include_examples 'Expireable'
|
||||
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:account).required }
|
||||
it { is_expected.to belong_to(:target_account).required }
|
||||
end
|
||||
|
||||
describe 'Validations' do
|
||||
subject { Fabricate.build :mute }
|
||||
|
||||
it { is_expected.to validate_uniqueness_of(:account_id).scoped_to(:target_account_id) }
|
||||
end
|
||||
end
|
||||
@@ -3,32 +3,7 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Poll do
|
||||
describe 'Scopes' do
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:attached_poll) { Fabricate(:poll, status: status) }
|
||||
let(:not_attached_poll) do
|
||||
Fabricate(:poll).tap do |poll|
|
||||
poll.status = nil
|
||||
poll.save(validate: false)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.attached' do
|
||||
it 'finds the correct records' do
|
||||
results = described_class.attached
|
||||
|
||||
expect(results).to eq([attached_poll])
|
||||
end
|
||||
end
|
||||
|
||||
describe '.unattached' do
|
||||
it 'finds the correct records' do
|
||||
results = described_class.unattached
|
||||
|
||||
expect(results).to eq([not_attached_poll])
|
||||
end
|
||||
end
|
||||
end
|
||||
include_examples 'Expireable'
|
||||
|
||||
describe '#reset_votes!' do
|
||||
let(:poll) { Fabricate :poll, cached_tallies: [2, 3], votes_count: 5, voters_count: 5 }
|
||||
|
||||
@@ -105,35 +105,64 @@ RSpec.describe Report do
|
||||
describe 'history' do
|
||||
subject(:action_logs) { report.history }
|
||||
|
||||
let(:report) { Fabricate(:report, target_account_id: target_account.id, status_ids: [status.id], created_at: 3.days.ago, updated_at: 1.day.ago) }
|
||||
let(:report) { Fabricate(:report, target_account_id: target_account.id, status_ids: [status.id]) }
|
||||
let(:target_account) { Fabricate(:account) }
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:account_warning) { Fabricate(:account_warning, report_id: report.id) }
|
||||
|
||||
before do
|
||||
Fabricate(:action_log, target_type: 'Report', account_id: target_account.id, target_id: report.id, created_at: 2.days.ago)
|
||||
Fabricate(:action_log, target_type: 'Account', account_id: target_account.id, target_id: report.target_account_id, created_at: 2.days.ago)
|
||||
Fabricate(:action_log, target_type: 'Status', account_id: target_account.id, target_id: status.id, created_at: 2.days.ago)
|
||||
Fabricate(:action_log, target_type: 'AccountWarning', account_id: target_account.id, target_id: account_warning.id, created_at: 2.days.ago)
|
||||
end
|
||||
let!(:matched_type_account_warning) { Fabricate(:action_log, target_type: 'AccountWarning', target_id: account_warning.id) }
|
||||
let!(:matched_type_account) { Fabricate(:action_log, target_type: 'Account', target_id: report.target_account_id) }
|
||||
let!(:matched_type_report) { Fabricate(:action_log, target_type: 'Report', target_id: report.id) }
|
||||
let!(:matched_type_status) { Fabricate(:action_log, target_type: 'Status', target_id: status.id) }
|
||||
|
||||
let!(:unmatched_type_account_warning) { Fabricate(:action_log, target_type: 'AccountWarning') }
|
||||
let!(:unmatched_type_account) { Fabricate(:action_log, target_type: 'Account') }
|
||||
let!(:unmatched_type_report) { Fabricate(:action_log, target_type: 'Report') }
|
||||
let!(:unmatched_type_status) { Fabricate(:action_log, target_type: 'Status') }
|
||||
|
||||
it 'returns expected logs' do
|
||||
expect(action_logs)
|
||||
.to have_attributes(count: 4)
|
||||
.and include(have_attributes(target_type: 'Account'))
|
||||
.and include(have_attributes(target_type: 'AccountWarning'))
|
||||
.and include(have_attributes(target_type: 'Report'))
|
||||
.and include(have_attributes(target_type: 'Status'))
|
||||
.and include(matched_type_account_warning)
|
||||
.and include(matched_type_account)
|
||||
.and include(matched_type_report)
|
||||
.and include(matched_type_status)
|
||||
.and not_include(unmatched_type_account_warning)
|
||||
.and not_include(unmatched_type_account)
|
||||
.and not_include(unmatched_type_report)
|
||||
.and not_include(unmatched_type_status)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
describe '#unresolved_siblings?' do
|
||||
subject { Fabricate :report }
|
||||
|
||||
context 'when the target account has other unresolved reports' do
|
||||
before { Fabricate :report, action_taken_at: nil, target_account: subject.target_account }
|
||||
|
||||
it { is_expected.to be_unresolved_siblings }
|
||||
end
|
||||
|
||||
context 'when the target account has a resolved report' do
|
||||
before { Fabricate :report, action_taken_at: 3.days.ago, target_account: subject.target_account }
|
||||
|
||||
it { is_expected.to_not be_unresolved_siblings }
|
||||
end
|
||||
|
||||
context 'when the target account has no other reports' do
|
||||
before { described_class.where(target_account: subject.target_account).destroy_all }
|
||||
|
||||
it { is_expected.to_not be_unresolved_siblings }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Validations' do
|
||||
let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
|
||||
|
||||
it 'is invalid if comment is longer than character limit and reporter is local' do
|
||||
report = Fabricate.build(:report, comment: comment_over_limit)
|
||||
expect(report.valid?).to be false
|
||||
expect(report).to model_have_error_on_field(:comment)
|
||||
report = Fabricate.build(:report)
|
||||
|
||||
expect(report).to_not allow_value(comment_over_limit).for(:comment)
|
||||
end
|
||||
|
||||
it 'is valid if comment is longer than character limit and reporter is not local' do
|
||||
@@ -142,16 +171,16 @@ RSpec.describe Report do
|
||||
end
|
||||
|
||||
it 'is invalid if it references invalid rules' do
|
||||
report = Fabricate.build(:report, category: :violation, rule_ids: [-1])
|
||||
expect(report.valid?).to be false
|
||||
expect(report).to model_have_error_on_field(:rule_ids)
|
||||
report = Fabricate.build(:report, category: :violation)
|
||||
|
||||
expect(report).to_not allow_value([-1]).for(:rule_ids)
|
||||
end
|
||||
|
||||
it 'is invalid if it references rules but category is not "violation"' do
|
||||
rule = Fabricate(:rule)
|
||||
report = Fabricate.build(:report, category: :spam, rule_ids: rule.id)
|
||||
expect(report.valid?).to be false
|
||||
expect(report).to model_have_error_on_field(:rule_ids)
|
||||
report = Fabricate.build(:report, category: :spam)
|
||||
|
||||
expect(report).to_not allow_value(rule.id).for(:rule_ids)
|
||||
end
|
||||
|
||||
def comment_over_limit
|
||||
|
||||
@@ -5,7 +5,39 @@ require 'rails_helper'
|
||||
RSpec.describe Tag do
|
||||
include_examples 'Reviewable'
|
||||
|
||||
describe 'validations' do
|
||||
describe 'Validations' do
|
||||
describe 'name' do
|
||||
context 'with a new record' do
|
||||
subject { Fabricate.build :tag, name: 'original' }
|
||||
|
||||
it { is_expected.to allow_value('changed').for(:name) }
|
||||
end
|
||||
|
||||
context 'with an existing record' do
|
||||
subject { Fabricate :tag, name: 'original' }
|
||||
|
||||
it { is_expected.to_not allow_value('changed').for(:name).with_message(previous_name_error_message) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'display_name' do
|
||||
context 'with a new record' do
|
||||
subject { Fabricate.build :tag, name: 'original', display_name: 'OriginalDisplayName' }
|
||||
|
||||
it { is_expected.to allow_value('ChangedDisplayName').for(:display_name) }
|
||||
end
|
||||
|
||||
context 'with an existing record' do
|
||||
subject { Fabricate :tag, name: 'original', display_name: 'OriginalDisplayName' }
|
||||
|
||||
it { is_expected.to_not allow_value('ChangedDisplayName').for(:display_name).with_message(previous_name_error_message) }
|
||||
end
|
||||
end
|
||||
|
||||
def previous_name_error_message
|
||||
I18n.t('tags.does_not_match_previous_name')
|
||||
end
|
||||
|
||||
it 'invalid with #' do
|
||||
expect(described_class.new(name: '#hello_world')).to_not be_valid
|
||||
end
|
||||
|
||||
11
spec/models/tag_trend_spec.rb
Normal file
11
spec/models/tag_trend_spec.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe TagTrend do
|
||||
include_examples 'RankedTrend'
|
||||
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:tag).required }
|
||||
end
|
||||
end
|
||||
27
spec/models/terms_of_service_spec.rb
Normal file
27
spec/models/terms_of_service_spec.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe TermsOfService do
|
||||
describe '#scope_for_notification' do
|
||||
subject { terms_of_service.scope_for_notification }
|
||||
|
||||
let(:published_at) { Time.now.utc }
|
||||
let(:terms_of_service) { Fabricate(:terms_of_service, published_at: published_at) }
|
||||
let(:user_before) { Fabricate(:user, created_at: published_at - 2.days) }
|
||||
let(:user_before_unconfirmed) { Fabricate(:user, created_at: published_at - 2.days, confirmed_at: nil) }
|
||||
let(:user_before_suspended) { Fabricate(:user, created_at: published_at - 2.days) }
|
||||
let(:user_after) { Fabricate(:user, created_at: published_at + 1.hour) }
|
||||
|
||||
before do
|
||||
user_before_suspended.account.suspend!
|
||||
user_before_unconfirmed
|
||||
user_before
|
||||
user_after
|
||||
end
|
||||
|
||||
it 'includes only users created before the terms of service were published' do
|
||||
expect(subject.pluck(:id)).to match_array(user_before.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -61,10 +61,10 @@ RSpec.describe Trends::Tags do
|
||||
|
||||
it 'decays scores' do
|
||||
subject.refresh(yesterday + 12.hours)
|
||||
original_score = subject.score(tag_ocs.id)
|
||||
original_score = TagTrend.find_by(tag: tag_ocs).score
|
||||
expect(original_score).to eq 144.0
|
||||
subject.refresh(yesterday + 12.hours + subject.options[:max_score_halflife])
|
||||
decayed_score = subject.score(tag_ocs.id)
|
||||
decayed_score = TagTrend.find_by(tag: tag_ocs).score
|
||||
expect(decayed_score).to be <= original_score / 2
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,6 +18,14 @@ RSpec.describe UserRole do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'position' do
|
||||
subject { Fabricate.build :user_role }
|
||||
|
||||
let(:limit) { described_class::POSITION_LIMIT }
|
||||
|
||||
it { is_expected.to validate_numericality_of(:position).is_in(-limit..limit) }
|
||||
end
|
||||
|
||||
describe 'color' do
|
||||
it { is_expected.to allow_values('#112233', '#aabbcc', '').for(:color) }
|
||||
it { is_expected.to_not allow_values('x', '112233445566', '#xxyyzz').for(:color) }
|
||||
|
||||
73
spec/policies/terms_of_service_policy_spec.rb
Normal file
73
spec/policies/terms_of_service_policy_spec.rb
Normal file
@@ -0,0 +1,73 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe TermsOfServicePolicy do
|
||||
subject { described_class }
|
||||
|
||||
let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
|
||||
let(:john) { Fabricate(:account) }
|
||||
|
||||
permissions :index?, :create? do
|
||||
it { is_expected.to permit(admin, TermsOfService) }
|
||||
it { is_expected.to_not permit(john, TermsOfService) }
|
||||
end
|
||||
|
||||
permissions :update?, :destroy? do
|
||||
let(:terms) { Fabricate(:terms_of_service, published_at: published) }
|
||||
|
||||
context 'with an unpublished terms' do
|
||||
let(:published) { nil }
|
||||
|
||||
it { is_expected.to permit(admin, terms) }
|
||||
it { is_expected.to_not permit(john, terms) }
|
||||
end
|
||||
|
||||
context 'with a published terms' do
|
||||
let(:published) { 5.days.ago }
|
||||
|
||||
it { is_expected.to_not permit(admin, terms) }
|
||||
it { is_expected.to_not permit(john, terms) }
|
||||
end
|
||||
end
|
||||
|
||||
permissions :distribute? do
|
||||
let(:terms) { Fabricate(:terms_of_service, published_at: published, notification_sent_at: notification) }
|
||||
|
||||
context 'with notification already sent' do
|
||||
let(:notification) { 3.days.ago }
|
||||
|
||||
context 'with published true' do
|
||||
let(:published) { 5.days.ago }
|
||||
|
||||
it { is_expected.to_not permit(admin, terms) }
|
||||
it { is_expected.to_not permit(john, terms) }
|
||||
end
|
||||
|
||||
context 'with published false' do
|
||||
let(:published) { nil }
|
||||
|
||||
it { is_expected.to_not permit(admin, terms) }
|
||||
it { is_expected.to_not permit(john, terms) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with notification not yet sent' do
|
||||
let(:notification) { nil }
|
||||
|
||||
context 'with published true' do
|
||||
let(:published) { 5.days.ago }
|
||||
|
||||
it { is_expected.to permit(admin, terms) }
|
||||
it { is_expected.to_not permit(john, terms) }
|
||||
end
|
||||
|
||||
context 'with published false' do
|
||||
let(:published) { nil }
|
||||
|
||||
it { is_expected.to_not permit(admin, terms) }
|
||||
it { is_expected.to_not permit(john, terms) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/requests/api/v1/instances/terms_of_services_spec.rb
Normal file
24
spec/requests/api/v1/instances/terms_of_services_spec.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Terms of Service' do
|
||||
describe 'GET /api/v1/instance/terms_of_service' do
|
||||
before do
|
||||
Fabricate(:terms_of_service)
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get api_v1_instance_terms_of_service_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
|
||||
expect(response.parsed_body)
|
||||
.to be_present
|
||||
.and include(:content)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -55,6 +55,9 @@ RSpec.describe 'Instances' do
|
||||
max_characters: StatusLengthValidator::MAX_CHARS,
|
||||
max_media_attachments: Status::MEDIA_ATTACHMENTS_LIMIT
|
||||
),
|
||||
media_attachments: include(
|
||||
description_limit: MediaAttachment::MAX_DESCRIPTION_LENGTH
|
||||
),
|
||||
polls: include(
|
||||
max_options: PollValidator::MAX_OPTIONS
|
||||
)
|
||||
|
||||
@@ -10,8 +10,14 @@ RSpec.describe 'Custom CSS' do
|
||||
it 'returns empty stylesheet' do
|
||||
get '/custom.css'
|
||||
|
||||
expect(response.content_type).to include('text/css')
|
||||
expect(response.body.presence).to be_nil
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
.and have_cacheable_headers
|
||||
.and have_attributes(
|
||||
content_type: match('text/css')
|
||||
)
|
||||
expect(response.body.presence)
|
||||
.to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,8 +29,14 @@ RSpec.describe 'Custom CSS' do
|
||||
it 'returns stylesheet from settings' do
|
||||
get '/custom.css'
|
||||
|
||||
expect(response.content_type).to include('text/css')
|
||||
expect(response.body.strip).to eq(expected_css)
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
.and have_cacheable_headers
|
||||
.and have_attributes(
|
||||
content_type: match('text/css')
|
||||
)
|
||||
expect(response.body.strip)
|
||||
.to eq(expected_css)
|
||||
end
|
||||
|
||||
def expected_css
|
||||
@@ -44,8 +56,14 @@ RSpec.describe 'Custom CSS' do
|
||||
it 'returns stylesheet from settings' do
|
||||
get '/custom.css'
|
||||
|
||||
expect(response.content_type).to include('text/css')
|
||||
expect(response.body.strip).to eq(expected_css)
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
.and have_cacheable_headers
|
||||
.and have_attributes(
|
||||
content_type: match('text/css')
|
||||
)
|
||||
expect(response.body.strip)
|
||||
.to eq(expected_css)
|
||||
end
|
||||
|
||||
def expected_css
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Custom stylesheets' do
|
||||
describe 'GET /custom.css' do
|
||||
before { get '/custom.css' }
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
.and have_cacheable_headers
|
||||
.and have_attributes(
|
||||
content_type: match('text/css')
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
16
spec/requests/filters_spec.rb
Normal file
16
spec/requests/filters_spec.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Filters' do
|
||||
describe 'GET /filters' do
|
||||
context 'with signed out user' do
|
||||
it 'redirects to sign in page' do
|
||||
get filters_path
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(new_user_session_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
218
spec/requests/statuses/activity_spec.rb
Normal file
218
spec/requests/statuses/activity_spec.rb
Normal file
@@ -0,0 +1,218 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Status Activity' do
|
||||
describe 'GET /users/:account_username/statuses/:id/activity' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:status) { Fabricate(:status, account: account) }
|
||||
|
||||
context 'when signed out' do
|
||||
subject { get activity_account_status_path(account.username, status) }
|
||||
|
||||
context 'when account is permanently suspended' do
|
||||
before do
|
||||
account.suspend!
|
||||
account.deletion_request.destroy
|
||||
end
|
||||
|
||||
it 'returns http gone' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(410)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account is temporarily suspended' do
|
||||
before { account.suspend! }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is public' do
|
||||
before { status.update(visibility: :public) }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(:success)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/activity+json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is private' do
|
||||
before { status.update(visibility: :private) }
|
||||
|
||||
it 'returns http not_found' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is direct' do
|
||||
before { status.update(visibility: :direct) }
|
||||
|
||||
it 'returns http not_found' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when signed in' do
|
||||
subject { get activity_account_status_path(account.username, status) }
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
before { sign_in(user) }
|
||||
|
||||
context 'when status is public' do
|
||||
before { status.update(visibility: :public) }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(:success)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/activity+json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is private' do
|
||||
before { status.update(visibility: :private) }
|
||||
|
||||
context 'when user is authorized to see it' do
|
||||
before { user.account.follow!(account) }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/activity+json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not authorized to see it' do
|
||||
it 'returns http not_found' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is direct' do
|
||||
before { status.update(visibility: :direct) }
|
||||
|
||||
context 'when user is authorized to see it' do
|
||||
before { Fabricate(:mention, account: user.account, status: status) }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/activity+json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not authorized to see it' do
|
||||
it 'returns http not_found' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with signature' do
|
||||
subject { get activity_account_status_path(account.username, status), headers: nil, sign_with: remote_account }
|
||||
|
||||
let(:remote_account) { Fabricate(:account, domain: 'example.com') }
|
||||
|
||||
context 'when status is public' do
|
||||
before { status.update(visibility: :public) }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(:success)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/activity+json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is private' do
|
||||
before { status.update(visibility: :private) }
|
||||
|
||||
context 'when user is authorized to see it' do
|
||||
before { remote_account.follow!(account) }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/activity+json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not authorized to see it' do
|
||||
it 'returns http not_found' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is direct' do
|
||||
before { status.update(visibility: :direct) }
|
||||
|
||||
context 'when user is authorized to see it' do
|
||||
before { Fabricate(:mention, account: remote_account, status: status) }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/activity+json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not authorized to see it' do
|
||||
it 'returns http not_found' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -7,6 +7,29 @@ RSpec.describe 'Tags' do
|
||||
context 'when tag exists' do
|
||||
let(:tag) { Fabricate :tag }
|
||||
|
||||
context 'with HTML format' do
|
||||
before { get tag_path(tag) }
|
||||
|
||||
it 'returns page with links to alternate resources' do
|
||||
expect(rss_links.first[:href])
|
||||
.to eq(tag_url(tag))
|
||||
expect(activity_json_links.first[:href])
|
||||
.to eq(tag_url(tag))
|
||||
end
|
||||
|
||||
def rss_links
|
||||
alternate_links.css('[type="application/rss+xml"]')
|
||||
end
|
||||
|
||||
def activity_json_links
|
||||
alternate_links.css('[type="application/activity+json"]')
|
||||
end
|
||||
|
||||
def alternate_links
|
||||
response.parsed_body.css('link[rel=alternate]')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with JSON format' do
|
||||
before { get tag_path(tag, format: :json) }
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActivityPub::AcceptFollowSerializer do
|
||||
subject { serialized_record_json(record, described_class, adapter: ActivityPub::Adapter) }
|
||||
|
||||
describe 'serializing an object' do
|
||||
let(:record) { Fabricate :follow_request }
|
||||
|
||||
it 'returns expected attributes' do
|
||||
expect(subject.deep_symbolize_keys)
|
||||
.to include(
|
||||
actor: eq(ActivityPub::TagManager.instance.uri_for(record.target_account)),
|
||||
id: match("#accepts/follows/#{record.id}"),
|
||||
object: include(type: 'Follow'),
|
||||
type: 'Accept'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActivityPub::RejectFollowSerializer do
|
||||
subject { serialized_record_json(record, described_class, adapter: ActivityPub::Adapter) }
|
||||
|
||||
describe 'serializing an object' do
|
||||
let(:record) { Fabricate :follow_request }
|
||||
|
||||
it 'returns expected attributes' do
|
||||
expect(subject.deep_symbolize_keys)
|
||||
.to include(
|
||||
actor: eq(ActivityPub::TagManager.instance.uri_for(record.target_account)),
|
||||
id: match("#rejects/follows/#{record.id}"),
|
||||
object: include(type: 'Follow'),
|
||||
type: 'Reject'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,13 +5,14 @@ require 'rails_helper'
|
||||
RSpec.describe REST::AccountRelationshipSeveranceEventSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
let(:record) { Fabricate.build :account_relationship_severance_event, id: 123 }
|
||||
let(:record) { Fabricate.build :account_relationship_severance_event, id: 123, created_at: DateTime.new(2024, 11, 28, 16, 20, 0) }
|
||||
|
||||
describe 'serialization' do
|
||||
it 'returns expected values' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'id' => be_a(String).and(eq('123'))
|
||||
'id' => be_a(String).and(eq('123')),
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::AccountSerializer::FieldSerializer do
|
||||
subject { serialized_record_json(field, described_class) }
|
||||
|
||||
let(:default_datetime) { DateTime.new(2024, 11, 28, 16, 20, 0) }
|
||||
let(:account) { Fabricate.build :account }
|
||||
|
||||
context 'when verified_at is populated' do
|
||||
let(:field) { Account::Field.new(account, 'name' => 'Foo', 'value' => 'Bar', 'verified_at' => default_datetime) }
|
||||
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'verified_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,6 +5,7 @@ require 'rails_helper'
|
||||
RSpec.describe REST::AccountSerializer do
|
||||
subject { serialized_record_json(account, described_class) }
|
||||
|
||||
let(:default_datetime) { DateTime.new(2024, 11, 28, 16, 20, 0) }
|
||||
let(:role) { Fabricate(:user_role, name: 'Role', highlighted: true) }
|
||||
let(:user) { Fabricate(:user, role: role) }
|
||||
let(:account) { user.account }
|
||||
@@ -44,4 +45,27 @@ RSpec.describe REST::AccountSerializer do
|
||||
expect(subject['memorial']).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when created_at is populated' do
|
||||
before do
|
||||
account.account_stat.update!(created_at: default_datetime)
|
||||
end
|
||||
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when last_status_at is populated' do
|
||||
before do
|
||||
account.account_stat.update!(last_status_at: default_datetime)
|
||||
end
|
||||
|
||||
it 'is serialized as yyyy-mm-dd' do
|
||||
expect(subject['last_status_at']).to eq('2024-11-28')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,8 @@ RSpec.describe REST::AccountWarningSerializer do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'id' => be_a(String).and(eq('123')),
|
||||
'status_ids' => be_a(Array).and(eq(['456', '789']))
|
||||
'status_ids' => be_a(Array).and(eq(['456', '789'])),
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,17 @@ require 'rails_helper'
|
||||
RSpec.describe REST::Admin::AccountSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
context 'when created_at is populated' do
|
||||
let(:record) { Fabricate :account, user: Fabricate(:user) }
|
||||
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'created_by_application_id' do
|
||||
context 'when account is application-created' do
|
||||
let(:record) { Fabricate :account, user: Fabricate(:user, created_by_application: application) }
|
||||
|
||||
@@ -11,8 +11,10 @@ RSpec.describe REST::Admin::CohortSerializer do
|
||||
it 'returns expected values' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'data' => be_a(Array),
|
||||
'period' => /2024-01-01/
|
||||
'data' => be_a(Array).and(
|
||||
all(include('date' => match_api_datetime_format))
|
||||
),
|
||||
'period' => match(/2024-01-01/).and(match_api_datetime_format)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
18
spec/serializers/rest/admin/domain_allow_serializer_spec.rb
Normal file
18
spec/serializers/rest/admin/domain_allow_serializer_spec.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::Admin::DomainAllowSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
let(:record) { Fabricate(:domain_allow) }
|
||||
|
||||
context 'when created_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
18
spec/serializers/rest/admin/domain_block_serializer_spec.rb
Normal file
18
spec/serializers/rest/admin/domain_block_serializer_spec.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::Admin::DomainBlockSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
let(:record) { Fabricate(:domain_block) }
|
||||
|
||||
context 'when created_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::Admin::EmailDomainBlockSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
let(:record) { Fabricate(:email_domain_block) }
|
||||
|
||||
context 'when created_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
19
spec/serializers/rest/admin/ip_block_serializer_spec.rb
Normal file
19
spec/serializers/rest/admin/ip_block_serializer_spec.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::Admin::IpBlockSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
context 'when timestamps are populated' do
|
||||
let(:record) { Fabricate(:ip_block, expires_at: DateTime.new(2024, 11, 28, 16, 20, 0)) }
|
||||
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format,
|
||||
'expires_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
18
spec/serializers/rest/admin/ip_serializer_spec.rb
Normal file
18
spec/serializers/rest/admin/ip_serializer_spec.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::Admin::IpSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
let(:record) { UserIp.new(used_at: 3.days.ago) }
|
||||
|
||||
context 'when used_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'used_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
23
spec/serializers/rest/admin/measure_serializer_spec.rb
Normal file
23
spec/serializers/rest/admin/measure_serializer_spec.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::Admin::MeasureSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:params) { ActionController::Parameters.new({ instance_accounts: [123] }) }
|
||||
let(:record) { Admin::Metrics::Measure::ActiveUsersMeasure.new(start_at, end_at, params) }
|
||||
|
||||
context 'when start_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'data' => all(
|
||||
include('date' => match_api_datetime_format)
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
19
spec/serializers/rest/admin/report_serializer_spec.rb
Normal file
19
spec/serializers/rest/admin/report_serializer_spec.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::Admin::ReportSerializer do
|
||||
subject { serialized_record_json(report, described_class) }
|
||||
|
||||
context 'with timestamps' do
|
||||
let(:report) { Fabricate(:report, action_taken_at: 3.days.ago) }
|
||||
|
||||
it 'is serialized as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'action_taken_at' => match_api_datetime_format,
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
31
spec/serializers/rest/announcement_serializer_spec.rb
Normal file
31
spec/serializers/rest/announcement_serializer_spec.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::AnnouncementSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
announcement,
|
||||
described_class,
|
||||
options: {
|
||||
scope: current_user,
|
||||
scope_name: :current_user,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
let(:current_user) { Fabricate(:user) }
|
||||
let(:announcement) { Fabricate(:announcement, starts_at: 10.days.ago, published_at: 10.days.ago, ends_at: 5.days.from_now) }
|
||||
|
||||
context 'when date fields are populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'starts_at' => match_api_datetime_format,
|
||||
'ends_at' => match_api_datetime_format,
|
||||
'published_at' => match_api_datetime_format,
|
||||
'updated_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
18
spec/serializers/rest/annual_report_event_serializer_spec.rb
Normal file
18
spec/serializers/rest/annual_report_event_serializer_spec.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::AnnualReportEventSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
describe 'serializing an object' do
|
||||
let(:record) { Fabricate.build :generated_annual_report, year: 2024 }
|
||||
|
||||
it 'returns expected attributes' do
|
||||
expect(subject.deep_symbolize_keys)
|
||||
.to include(
|
||||
year: '2024'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,9 +5,11 @@ require 'rails_helper'
|
||||
RSpec.describe REST::ExtendedDescriptionSerializer do
|
||||
subject { serialized_record_json(record, described_class) }
|
||||
|
||||
let(:default_datetime) { DateTime.new(2024, 11, 28, 16, 20, 0) }
|
||||
|
||||
describe 'serialization' do
|
||||
context 'with text present' do
|
||||
let(:record) { ExtendedDescription.new text: 'Hello world', updated_at: Date.new(2024, 1, 1) }
|
||||
let(:record) { ExtendedDescription.new text: 'Hello world', updated_at: default_datetime }
|
||||
|
||||
it 'returns expected values' do
|
||||
expect(subject)
|
||||
@@ -15,19 +17,19 @@ RSpec.describe REST::ExtendedDescriptionSerializer do
|
||||
'content' => eq(<<~HTML),
|
||||
<p>Hello world</p>
|
||||
HTML
|
||||
'updated_at' => eq('2024-01-01')
|
||||
'updated_at' => eq('2024-11-28T16:20:00+00:00')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with text missing' do
|
||||
let(:record) { ExtendedDescription.new text: nil, updated_at: Date.new(2024, 1, 1) }
|
||||
let(:record) { ExtendedDescription.new text: nil, updated_at: default_datetime }
|
||||
|
||||
it 'returns expected values' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'content' => eq(''),
|
||||
'updated_at' => eq('2024-01-01')
|
||||
'updated_at' => eq('2024-11-28T16:20:00+00:00')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
24
spec/serializers/rest/featured_tag_serializer_spec.rb
Normal file
24
spec/serializers/rest/featured_tag_serializer_spec.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::FeaturedTagSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
featured_tag,
|
||||
described_class
|
||||
)
|
||||
end
|
||||
|
||||
let(:featured_tag) { Fabricate :featured_tag }
|
||||
|
||||
context 'when last_status_at is populated' do
|
||||
before do
|
||||
featured_tag.increment(DateTime.new(2024, 11, 28, 16, 20, 0))
|
||||
end
|
||||
|
||||
it 'is serialized as yyyy-mm-dd' do
|
||||
expect(subject['last_status_at']).to eq('2024-11-28')
|
||||
end
|
||||
end
|
||||
end
|
||||
23
spec/serializers/rest/filter_serializer_spec.rb
Normal file
23
spec/serializers/rest/filter_serializer_spec.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::FilterSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
filter,
|
||||
described_class
|
||||
)
|
||||
end
|
||||
|
||||
let(:filter) { Fabricate.build :custom_filter, expires_at: DateTime.new(2024, 11, 28, 16, 20, 0) }
|
||||
|
||||
context 'when expires_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'expires_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
23
spec/serializers/rest/marker_serializer_spec.rb
Normal file
23
spec/serializers/rest/marker_serializer_spec.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::MarkerSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
marker,
|
||||
described_class
|
||||
)
|
||||
end
|
||||
|
||||
let(:marker) { Fabricate :marker }
|
||||
|
||||
context 'when updated_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'updated_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
45
spec/serializers/rest/muted_account_serializer_spec.rb
Normal file
45
spec/serializers/rest/muted_account_serializer_spec.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::MutedAccountSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
mutee,
|
||||
described_class,
|
||||
options: {
|
||||
scope: current_user,
|
||||
scope_name: :current_user,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
let(:current_user) { Fabricate(:user) }
|
||||
let(:account) { current_user.account }
|
||||
let(:mutee) { Fabricate(:account, username: 'mutee') }
|
||||
|
||||
context 'when mute_expires_at is populated and non-nil' do
|
||||
before do
|
||||
account.follow!(mutee)
|
||||
account.mute!(mutee, duration: 1.day)
|
||||
end
|
||||
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'mute_expires_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when mute has no duration' do
|
||||
before do
|
||||
account.follow!(mutee)
|
||||
account.mute!(mutee)
|
||||
end
|
||||
|
||||
it 'has a nil mute_expires_at' do
|
||||
expect(subject['mute_expires_at']).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
23
spec/serializers/rest/notification_group_serializer_spec.rb
Normal file
23
spec/serializers/rest/notification_group_serializer_spec.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::NotificationGroupSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
notification_group,
|
||||
described_class
|
||||
)
|
||||
end
|
||||
|
||||
let(:notification_group) { NotificationGroup.new pagination_data: { latest_notification_at: 3.days.ago }, notification: Fabricate(:notification), sample_accounts: [] }
|
||||
|
||||
context 'when latest_page_notification_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'latest_page_notification_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::NotificationRequestSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
notification_request,
|
||||
described_class,
|
||||
options: {
|
||||
scope: current_user,
|
||||
scope_name: :current_user,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
let(:current_user) { Fabricate(:user) }
|
||||
let(:notification_request) { Fabricate :notification_request }
|
||||
|
||||
context 'when timestampts are populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format,
|
||||
'updated_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
23
spec/serializers/rest/notification_serializer_spec.rb
Normal file
23
spec/serializers/rest/notification_serializer_spec.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::NotificationSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
notification,
|
||||
described_class
|
||||
)
|
||||
end
|
||||
|
||||
let(:notification) { Fabricate :notification }
|
||||
|
||||
context 'when created_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
28
spec/serializers/rest/poll_serializer_spec.rb
Normal file
28
spec/serializers/rest/poll_serializer_spec.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::PollSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
poll,
|
||||
described_class,
|
||||
options: {
|
||||
scope: current_user,
|
||||
scope_name: :current_user,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
let(:current_user) { Fabricate(:user) }
|
||||
let(:poll) { Fabricate.build :poll, expires_at: 5.days.from_now }
|
||||
|
||||
context 'when expires_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'expires_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
41
spec/serializers/rest/preview_card_serializer_spec.rb
Normal file
41
spec/serializers/rest/preview_card_serializer_spec.rb
Normal file
@@ -0,0 +1,41 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::PreviewCardSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
preview_card,
|
||||
described_class
|
||||
)
|
||||
end
|
||||
|
||||
context 'when preview card does not have author data' do
|
||||
let(:preview_card) { Fabricate.build :preview_card }
|
||||
|
||||
it 'includes empty authors array' do
|
||||
expect(subject.deep_symbolize_keys)
|
||||
.to include(
|
||||
authors: be_an(Array).and(be_empty)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when preview card has author data' do
|
||||
let(:preview_card) { Fabricate.build :preview_card, author_name: 'Name', author_url: 'https://host.example/123' }
|
||||
|
||||
it 'includes populated authors array' do
|
||||
expect(subject.deep_symbolize_keys)
|
||||
.to include(
|
||||
authors: be_an(Array).and(
|
||||
contain_exactly(
|
||||
include(
|
||||
name: 'Name',
|
||||
url: 'https://host.example/123'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/serializers/rest/report_serializer_spec.rb
Normal file
24
spec/serializers/rest/report_serializer_spec.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::ReportSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
report,
|
||||
described_class
|
||||
)
|
||||
end
|
||||
|
||||
context 'with timestamps' do
|
||||
let(:report) { Fabricate(:report, action_taken_at: 3.days.ago) }
|
||||
|
||||
it 'is serialized as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format,
|
||||
'action_taken_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/serializers/rest/scheduled_status_serializer_spec.rb
Normal file
24
spec/serializers/rest/scheduled_status_serializer_spec.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::ScheduledStatusSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
scheduled_status,
|
||||
described_class
|
||||
)
|
||||
end
|
||||
|
||||
let(:scheduled_status) { Fabricate.build(:scheduled_status, scheduled_at: 4.minutes.from_now, params: { application_id: 123 }) }
|
||||
|
||||
describe 'serialization' do
|
||||
it 'returns expected values and removes application_id from params' do
|
||||
expect(subject.deep_symbolize_keys)
|
||||
.to include(
|
||||
scheduled_at: be_a(String).and(match_api_datetime_format),
|
||||
params: not_include(:application_id)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
23
spec/serializers/rest/status_edit_serializer_spec.rb
Normal file
23
spec/serializers/rest/status_edit_serializer_spec.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe REST::StatusEditSerializer do
|
||||
subject do
|
||||
serialized_record_json(
|
||||
status_edit,
|
||||
described_class
|
||||
)
|
||||
end
|
||||
|
||||
let(:status_edit) { Fabricate(:status_edit) }
|
||||
|
||||
context 'when created_at is populated' do
|
||||
it 'parses as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -51,5 +51,25 @@ RSpec.describe REST::StatusSerializer do
|
||||
expect(subject['favourites_count']).to eq(40)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with created_at' do
|
||||
it 'is serialized as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'created_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when edited_at is populated' do
|
||||
let(:status) { Fabricate.build :status, edited_at: 3.days.ago }
|
||||
|
||||
it 'is serialized as RFC 3339 datetime' do
|
||||
expect(subject)
|
||||
.to include(
|
||||
'edited_at' => match_api_datetime_format
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||
subject { described_class.new }
|
||||
|
||||
let!(:status) { Fabricate(:status, text: 'Hello world', account: Fabricate(:account, domain: 'example.com')) }
|
||||
let(:bogus_mention) { 'https://example.com/users/erroringuser' }
|
||||
let(:payload) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
@@ -17,6 +18,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||
tag: [
|
||||
{ type: 'Hashtag', name: 'hoge' },
|
||||
{ type: 'Mention', href: ActivityPub::TagManager.instance.uri_for(alice) },
|
||||
{ type: 'Mention', href: bogus_mention },
|
||||
],
|
||||
}
|
||||
end
|
||||
@@ -30,19 +32,21 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||
let(:media_attachments) { [] }
|
||||
|
||||
before do
|
||||
mentions.each { |a| Fabricate(:mention, status: status, account: a) }
|
||||
mentions.each { |(account, silent)| Fabricate(:mention, status: status, account: account, silent: silent) }
|
||||
tags.each { |t| status.tags << t }
|
||||
media_attachments.each { |m| status.media_attachments << m }
|
||||
stub_request(:get, bogus_mention).to_raise(HTTP::ConnectionError)
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
it 'updates text and content warning' do
|
||||
it 'updates text and content warning, and schedules re-fetching broken mention' do
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload)
|
||||
.to have_attributes(
|
||||
text: eq('Hello universe'),
|
||||
spoiler_text: eq('Show more')
|
||||
)
|
||||
expect(MentionResolveWorker).to have_enqueued_sidekiq_job(status.id, bogus_mention, anything)
|
||||
end
|
||||
|
||||
context 'when the changes are only in sanitized-out HTML' do
|
||||
@@ -252,16 +256,22 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||
updated: '2021-09-08T22:39:25Z',
|
||||
tag: [
|
||||
{ type: 'Hashtag', name: 'foo' },
|
||||
{ type: 'Hashtag', name: 'bar' },
|
||||
],
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
subject.call(status, json, json)
|
||||
status.account.featured_tags.create!(name: 'bar')
|
||||
status.account.featured_tags.create!(name: 'test')
|
||||
end
|
||||
|
||||
it 'updates tags' do
|
||||
expect(status.tags.reload.map(&:name)).to eq %w(foo)
|
||||
it 'updates tags and featured tags' do
|
||||
expect { subject.call(status, json, json) }
|
||||
.to change { status.tags.reload.pluck(:name) }.from(%w(test foo)).to(%w(foo bar))
|
||||
.and change { status.account.featured_tags.find_by(name: 'test').statuses_count }.by(-1)
|
||||
.and change { status.account.featured_tags.find_by(name: 'bar').statuses_count }.by(1)
|
||||
.and change { status.account.featured_tags.find_by(name: 'bar').last_status_at }.from(nil).to(be_within(0.1).of(Time.now.utc))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -276,7 +286,19 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||
end
|
||||
|
||||
context 'when originally with mentions' do
|
||||
let(:mentions) { [alice, bob] }
|
||||
let(:mentions) { [[alice, false], [bob, false]] }
|
||||
|
||||
before do
|
||||
subject.call(status, json, json)
|
||||
end
|
||||
|
||||
it 'updates mentions' do
|
||||
expect(status.active_mentions.reload.map(&:account_id)).to eq [alice.id]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when originally with silent mentions' do
|
||||
let(:mentions) { [[alice, true], [bob, true]] }
|
||||
|
||||
before do
|
||||
subject.call(status, json, json)
|
||||
|
||||
@@ -70,7 +70,7 @@ RSpec.describe PostStatusService do
|
||||
subject.call(account, text: 'Hi future!', scheduled_at: invalid_scheduled_time)
|
||||
end.to raise_error(
|
||||
ActiveRecord::RecordInvalid,
|
||||
'Validation failed: Scheduled at The scheduled date must be in the future'
|
||||
'Validation failed: Scheduled at date must be in the future'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -46,7 +46,7 @@ RSpec.describe ReblogService do
|
||||
Status
|
||||
.where(id: reblog_of_id)
|
||||
.where(text: 'discard-status-text')
|
||||
.update_all(deleted_at: Time.now.utc)
|
||||
.touch_all(:deleted_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -150,6 +150,14 @@ RSpec.describe UpdateStatusService do
|
||||
.to eq [bob.id]
|
||||
expect(status.mentions.pluck(:account_id))
|
||||
.to contain_exactly(alice.id, bob.id)
|
||||
|
||||
# Going back when a mention was switched to silence should still be possible
|
||||
subject.call(status, status.account_id, text: 'Hello @alice')
|
||||
|
||||
expect(status.active_mentions.pluck(:account_id))
|
||||
.to eq [alice.id]
|
||||
expect(status.mentions.pluck(:account_id))
|
||||
.to contain_exactly(alice.id, bob.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
110
spec/support/examples/models/concerns/expireable.rb
Normal file
110
spec/support/examples/models/concerns/expireable.rb
Normal file
@@ -0,0 +1,110 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.shared_examples 'Expireable' do
|
||||
subject { described_class.new(expires_at: expires_at) }
|
||||
|
||||
let(:expires_at) { nil }
|
||||
|
||||
describe 'Scopes' do
|
||||
let!(:expired_record) do
|
||||
travel_to 2.days.ago do
|
||||
Fabricate factory_name, expires_at: 1.day.from_now
|
||||
end
|
||||
end
|
||||
let!(:un_expired_record) { Fabricate factory_name, expires_at: 10.days.from_now }
|
||||
|
||||
describe '.expired' do
|
||||
it 'returns expired records' do
|
||||
expect(described_class.expired)
|
||||
.to include(expired_record)
|
||||
.and not_include(un_expired_record)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expires_in' do
|
||||
context 'when expires at is nil' do
|
||||
let(:expires_at) { nil }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(subject.expires_in)
|
||||
.to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expires_in=' do
|
||||
let(:record) { Fabricate.build factory_name }
|
||||
|
||||
context 'when set to nil' do
|
||||
it 'sets expires_at to nil' do
|
||||
record.expires_in = nil
|
||||
expect(record.expires_at)
|
||||
.to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when set to empty' do
|
||||
it 'sets expires_at to nil' do
|
||||
record.expires_in = ''
|
||||
expect(record.expires_at)
|
||||
.to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when set to a value' do
|
||||
it 'sets expires_at to expected future time' do
|
||||
record.expires_in = 60
|
||||
expect(record.expires_at)
|
||||
.to be_within(0.1).of(60.seconds.from_now)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expired?' do
|
||||
context 'when expires_at is nil' do
|
||||
let(:expires_at) { nil }
|
||||
|
||||
it { is_expected.to_not be_expired }
|
||||
end
|
||||
|
||||
context 'when expires_at is in the past' do
|
||||
let(:expires_at) { 5.days.ago }
|
||||
|
||||
it { is_expected.to be_expired }
|
||||
end
|
||||
|
||||
context 'when expires_at is in the future' do
|
||||
let(:expires_at) { 5.days.from_now }
|
||||
|
||||
it { is_expected.to_not be_expired }
|
||||
end
|
||||
|
||||
describe '#expire!' do
|
||||
subject { Fabricate factory_name }
|
||||
|
||||
it 'updates the timestamp' do
|
||||
expect { subject.expire! }
|
||||
.to change(subject, :expires_at)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expires?' do
|
||||
context 'when value is missing' do
|
||||
let(:expires_at) { nil }
|
||||
|
||||
it { is_expected.to_not be_expires }
|
||||
end
|
||||
|
||||
context 'when value is present' do
|
||||
let(:expires_at) { 3.days.from_now }
|
||||
|
||||
it { is_expected.to be_expires }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def factory_name
|
||||
described_class.name.underscore.to_sym
|
||||
end
|
||||
end
|
||||
8
spec/support/matchers/api_datetime_format.rb
Normal file
8
spec/support/matchers/api_datetime_format.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec::Matchers.define :match_api_datetime_format do
|
||||
match(notify_expectation_failures: true) do |value|
|
||||
expect { DateTime.rfc3339(value) }
|
||||
.to_not raise_error
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user