Merge branch 'main' into glitch-soc/merge-upstream
Conflicts: - `app/controllers/settings/preferences_controller.rb`: Conflicts due to us having more user settings and upstream dropping `hide_network` (to replace it with an account attribute, properly migrated). Dropped `hide_network` like upstream. - `app/lib/user_settings_decorator.rb`: Conflicts due to us having more user settings and upstream dropping `hide_network` (to replace it with an account attribute, properly migrated). Dropped `hide_network` like upstream. - `app/models/status.rb`: Conflict because of slight change in how glitch-soc handles the scope to filter out local-only posts for anonymous viewers. Took upstream's changes and re-applied glitch-soc's change. - `app/models/user.rb`: Conflicts due to us having more user settings and upstream dropping `hide_network` (to replace it with an account attribute, properly migrated). Dropped `hide_network` like upstream. - `app/views/directories/index.html.haml`: Conflict because upstream redesigned that page while glitch-soc had a minor change to support hiding the number of followers. Ported glitch-soc's change on top of upstream's redesign. Additional changes: - `app/models/account_statuses_filter.rb`: See change to `app/models/status.rb`.
This commit is contained in:
@@ -5,7 +5,7 @@ RSpec.describe AccountsController, type: :controller do
|
||||
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
shared_examples 'cachable response' do
|
||||
shared_examples 'cacheable response' do
|
||||
it 'does not set cookies' do
|
||||
expect(response.cookies).to be_empty
|
||||
expect(response.headers['Set-Cookies']).to be nil
|
||||
@@ -374,7 +374,7 @@ RSpec.describe AccountsController, type: :controller do
|
||||
expect(response.media_type).to eq 'application/activity+json'
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
|
||||
it 'renders account' do
|
||||
json = body_as_json
|
||||
@@ -432,7 +432,7 @@ RSpec.describe AccountsController, type: :controller do
|
||||
expect(response.media_type).to eq 'application/activity+json'
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
|
||||
it 'renders account' do
|
||||
json = body_as_json
|
||||
@@ -499,7 +499,7 @@ RSpec.describe AccountsController, type: :controller do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
end
|
||||
|
||||
context do
|
||||
|
@@ -7,7 +7,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do
|
||||
let!(:private_pinned) { Fabricate(:status, account: account, text: 'secret private stuff', visibility: :private) }
|
||||
let(:remote_account) { nil }
|
||||
|
||||
shared_examples 'cachable response' do
|
||||
shared_examples 'cacheable response' do
|
||||
it 'does not set cookies' do
|
||||
expect(response.cookies).to be_empty
|
||||
expect(response.headers['Set-Cookies']).to be nil
|
||||
@@ -48,7 +48,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do
|
||||
expect(response.media_type).to eq 'application/activity+json'
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
|
||||
it 'returns orderedItems with pinned statuses' do
|
||||
expect(body[:orderedItems]).to be_an Array
|
||||
@@ -101,7 +101,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do
|
||||
expect(response.media_type).to eq 'application/activity+json'
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
|
||||
it 'returns orderedItems with pinned statuses' do
|
||||
json = body_as_json
|
||||
|
@@ -3,7 +3,7 @@ require 'rails_helper'
|
||||
RSpec.describe ActivityPub::OutboxesController, type: :controller do
|
||||
let!(:account) { Fabricate(:account) }
|
||||
|
||||
shared_examples 'cachable response' do
|
||||
shared_examples 'cacheable response' do
|
||||
it 'does not set cookies' do
|
||||
expect(response.cookies).to be_empty
|
||||
expect(response.headers['Set-Cookies']).to be nil
|
||||
@@ -53,7 +53,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
|
||||
expect(body[:totalItems]).to eq 4
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
|
||||
it 'does not have a Vary header' do
|
||||
expect(response.headers['Vary']).to be_nil
|
||||
@@ -98,7 +98,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
|
||||
expect(body[:orderedItems].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
|
||||
it 'returns Vary header with Signature' do
|
||||
expect(response.headers['Vary']).to include 'Signature'
|
||||
|
@@ -8,7 +8,7 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do
|
||||
let(:remote_reply_id) { 'https://foobar.com/statuses/1234' }
|
||||
let(:remote_querier) { nil }
|
||||
|
||||
shared_examples 'cachable response' do
|
||||
shared_examples 'cacheable response' do
|
||||
it 'does not set cookies' do
|
||||
expect(response.cookies).to be_empty
|
||||
expect(response.headers['Set-Cookies']).to be nil
|
||||
@@ -93,7 +93,7 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do
|
||||
expect(response.media_type).to eq 'application/activity+json'
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
|
||||
context 'without only_other_accounts' do
|
||||
it "returns items with thread author's replies" do
|
||||
|
@@ -31,7 +31,7 @@ describe Api::V1::Accounts::NotesController do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account note exceends allowed length' do
|
||||
context 'when account note exceeds allowed length' do
|
||||
let(:comment) { 'a' * 2_001 }
|
||||
|
||||
it 'returns 422' do
|
||||
|
@@ -140,7 +140,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'unsensitives account' do
|
||||
it 'unsensitizes account' do
|
||||
expect(account.reload.sensitized?).to be false
|
||||
end
|
||||
end
|
||||
|
@@ -56,7 +56,7 @@ RSpec.describe Api::V1::Statuses::FavouritedByAccountsController, type: :control
|
||||
Fabricate(:favourite, status: status)
|
||||
end
|
||||
|
||||
it 'returns http unautharized' do
|
||||
it 'returns http unauthorized' do
|
||||
get :index, params: { status_id: status.id }
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
@@ -56,7 +56,7 @@ RSpec.describe Api::V1::Statuses::RebloggedByAccountsController, type: :controll
|
||||
Fabricate(:status, reblog_of_id: status.id)
|
||||
end
|
||||
|
||||
it 'returns http unautharized' do
|
||||
it 'returns http unauthorized' do
|
||||
get :index, params: { status_id: status.id }
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
@@ -130,7 +130,7 @@ RSpec.describe Api::V1::StatusesController, type: :controller do
|
||||
let(:status) { Fabricate(:status, account: user.account, visibility: :private) }
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http unautharized' do
|
||||
it 'returns http unauthorized' do
|
||||
get :show, params: { id: status.id }
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
@@ -141,7 +141,7 @@ RSpec.describe Api::V1::StatusesController, type: :controller do
|
||||
Fabricate(:status, account: user.account, thread: status)
|
||||
end
|
||||
|
||||
it 'returns http unautharized' do
|
||||
it 'returns http unauthorized' do
|
||||
get :context, params: { id: status.id }
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
@@ -191,30 +191,30 @@ describe ApplicationController, type: :controller do
|
||||
controller do
|
||||
before_action :require_admin!
|
||||
|
||||
def sucesss
|
||||
def success
|
||||
head 200
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
routes.draw { get 'sucesss' => 'anonymous#sucesss' }
|
||||
routes.draw { get 'success' => 'anonymous#success' }
|
||||
end
|
||||
|
||||
it 'returns a 403 if current user is not admin' do
|
||||
sign_in(Fabricate(:user, admin: false))
|
||||
get 'sucesss'
|
||||
get 'success'
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
|
||||
it 'returns a 403 if current user is only a moderator' do
|
||||
sign_in(Fabricate(:user, moderator: true))
|
||||
get 'sucesss'
|
||||
get 'success'
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
|
||||
it 'does nothing if current user is admin' do
|
||||
sign_in(Fabricate(:user, admin: true))
|
||||
get 'sucesss'
|
||||
get 'success'
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
@@ -223,30 +223,30 @@ describe ApplicationController, type: :controller do
|
||||
controller do
|
||||
before_action :require_staff!
|
||||
|
||||
def sucesss
|
||||
def success
|
||||
head 200
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
routes.draw { get 'sucesss' => 'anonymous#sucesss' }
|
||||
routes.draw { get 'success' => 'anonymous#success' }
|
||||
end
|
||||
|
||||
it 'returns a 403 if current user is not admin or moderator' do
|
||||
sign_in(Fabricate(:user, admin: false, moderator: false))
|
||||
get 'sucesss'
|
||||
get 'success'
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
|
||||
it 'does nothing if current user is moderator' do
|
||||
sign_in(Fabricate(:user, moderator: true))
|
||||
get 'sucesss'
|
||||
get 'success'
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'does nothing if current user is admin' do
|
||||
sign_in(Fabricate(:user, admin: true))
|
||||
get 'sucesss'
|
||||
get 'success'
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
@@ -103,7 +103,7 @@ describe FollowerAccountsController do
|
||||
|
||||
context 'when account hides their network' do
|
||||
before do
|
||||
alice.user.settings.hide_network = true
|
||||
alice.update(hide_collections: true)
|
||||
end
|
||||
|
||||
it 'returns followers count' do
|
||||
|
@@ -103,7 +103,7 @@ describe FollowingAccountsController do
|
||||
|
||||
context 'when account hides their network' do
|
||||
before do
|
||||
alice.user.settings.hide_network = true
|
||||
alice.update(hide_collections: true)
|
||||
end
|
||||
|
||||
it 'returns followers count' do
|
||||
|
@@ -5,7 +5,7 @@ require 'rails_helper'
|
||||
describe StatusesController do
|
||||
render_views
|
||||
|
||||
shared_examples 'cachable response' do
|
||||
shared_examples 'cacheable response' do
|
||||
it 'does not set cookies' do
|
||||
expect(response.cookies).to be_empty
|
||||
expect(response.headers['Set-Cookies']).to be nil
|
||||
@@ -108,7 +108,7 @@ describe StatusesController do
|
||||
expect(response.headers['Vary']).to eq 'Accept'
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
|
||||
it 'returns Content-Type header' do
|
||||
expect(response.headers['Content-Type']).to include 'application/activity+json'
|
||||
@@ -496,7 +496,7 @@ describe StatusesController do
|
||||
expect(response.headers['Vary']).to eq 'Accept'
|
||||
end
|
||||
|
||||
it_behaves_like 'cachable response'
|
||||
it_behaves_like 'cacheable response'
|
||||
|
||||
it 'returns Content-Type header' do
|
||||
expect(response.headers['Content-Type']).to include 'application/activity+json'
|
||||
|
@@ -60,7 +60,7 @@ describe ApplicationHelper do
|
||||
end
|
||||
|
||||
describe 'favicon_path' do
|
||||
it 'returns /favicon.ico on production enviromnent' do
|
||||
it 'returns /favicon.ico on production environment' do
|
||||
expect(Rails.env).to receive(:production?).and_return(true)
|
||||
expect(helper.favicon_path).to eq '/favicon.ico'
|
||||
end
|
||||
|
@@ -6,7 +6,7 @@ RSpec.describe TagManager do
|
||||
|
||||
around do |example|
|
||||
original_local_domain = Rails.configuration.x.local_domain
|
||||
Rails.configuration.x.local_domain = 'domain.test'
|
||||
Rails.configuration.x.local_domain = 'domain.example.com'
|
||||
|
||||
example.run
|
||||
|
||||
@@ -18,11 +18,11 @@ RSpec.describe TagManager do
|
||||
end
|
||||
|
||||
it 'returns true if the slash-stripped string equals to local domain' do
|
||||
expect(TagManager.instance.local_domain?('DoMaIn.Test/')).to eq true
|
||||
expect(TagManager.instance.local_domain?('DoMaIn.Example.com/')).to eq true
|
||||
end
|
||||
|
||||
it 'returns false for irrelevant string' do
|
||||
expect(TagManager.instance.local_domain?('DoMaIn.Test!')).to eq false
|
||||
expect(TagManager.instance.local_domain?('DoMaIn.Example.com!')).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,7 +31,7 @@ RSpec.describe TagManager do
|
||||
|
||||
around do |example|
|
||||
original_web_domain = Rails.configuration.x.web_domain
|
||||
Rails.configuration.x.web_domain = 'domain.test'
|
||||
Rails.configuration.x.web_domain = 'domain.example.com'
|
||||
|
||||
example.run
|
||||
|
||||
@@ -43,11 +43,11 @@ RSpec.describe TagManager do
|
||||
end
|
||||
|
||||
it 'returns true if the slash-stripped string equals to web domain' do
|
||||
expect(TagManager.instance.web_domain?('DoMaIn.Test/')).to eq true
|
||||
expect(TagManager.instance.web_domain?('DoMaIn.Example.com/')).to eq true
|
||||
end
|
||||
|
||||
it 'returns false for string with irrelevant characters' do
|
||||
expect(TagManager.instance.web_domain?('DoMaIn.Test!')).to eq false
|
||||
expect(TagManager.instance.web_domain?('DoMaIn.Example.com!')).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -57,7 +57,7 @@ RSpec.describe TagManager do
|
||||
end
|
||||
|
||||
it 'returns normalized domain' do
|
||||
expect(TagManager.instance.normalize_domain('DoMaIn.Test/')).to eq 'domain.test'
|
||||
expect(TagManager.instance.normalize_domain('DoMaIn.Example.com/')).to eq 'domain.example.com'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -69,18 +69,18 @@ RSpec.describe TagManager do
|
||||
end
|
||||
|
||||
it 'returns true if the normalized string with port is local URL' do
|
||||
Rails.configuration.x.web_domain = 'domain.test:42'
|
||||
expect(TagManager.instance.local_url?('https://DoMaIn.Test:42/')).to eq true
|
||||
Rails.configuration.x.web_domain = 'domain.example.com:42'
|
||||
expect(TagManager.instance.local_url?('https://DoMaIn.Example.com:42/')).to eq true
|
||||
end
|
||||
|
||||
it 'returns true if the normalized string without port is local URL' do
|
||||
Rails.configuration.x.web_domain = 'domain.test'
|
||||
expect(TagManager.instance.local_url?('https://DoMaIn.Test/')).to eq true
|
||||
Rails.configuration.x.web_domain = 'domain.example.com'
|
||||
expect(TagManager.instance.local_url?('https://DoMaIn.Example.com/')).to eq true
|
||||
end
|
||||
|
||||
it 'returns false for string with irrelevant characters' do
|
||||
Rails.configuration.x.web_domain = 'domain.test'
|
||||
expect(TagManager.instance.local_url?('https://domainn.test/')).to eq false
|
||||
Rails.configuration.x.web_domain = 'domain.example.com'
|
||||
expect(TagManager.instance.local_url?('https://domain.example.net/')).to eq false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
229
spec/models/account_statuses_filter_spec.rb
Normal file
229
spec/models/account_statuses_filter_spec.rb
Normal file
@@ -0,0 +1,229 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountStatusesFilter do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:current_account) { nil }
|
||||
let(:params) { {} }
|
||||
|
||||
subject { described_class.new(account, current_account, params) }
|
||||
|
||||
def status!(visibility)
|
||||
Fabricate(:status, account: account, visibility: visibility)
|
||||
end
|
||||
|
||||
def status_with_tag!(visibility, tag)
|
||||
Fabricate(:status, account: account, visibility: visibility, tags: [tag])
|
||||
end
|
||||
|
||||
def status_with_parent!(visibility)
|
||||
Fabricate(:status, account: account, visibility: visibility, thread: Fabricate(:status))
|
||||
end
|
||||
|
||||
def status_with_reblog!(visibility)
|
||||
Fabricate(:status, account: account, visibility: visibility, reblog: Fabricate(:status))
|
||||
end
|
||||
|
||||
def status_with_mention!(visibility, mentioned_account = nil)
|
||||
Fabricate(:status, account: account, visibility: visibility).tap do |status|
|
||||
Fabricate(:mention, status: status, account: mentioned_account || Fabricate(:account))
|
||||
end
|
||||
end
|
||||
|
||||
def status_with_media_attachment!(visibility)
|
||||
Fabricate(:status, account: account, visibility: visibility).tap do |status|
|
||||
Fabricate(:media_attachment, account: account, status: status)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#results' do
|
||||
let(:tag) { Fabricate(:tag) }
|
||||
|
||||
before do
|
||||
status!(:public)
|
||||
status!(:unlisted)
|
||||
status!(:private)
|
||||
status_with_parent!(:public)
|
||||
status_with_reblog!(:public)
|
||||
status_with_tag!(:public, tag)
|
||||
status_with_mention!(:direct)
|
||||
status_with_media_attachment!(:public)
|
||||
end
|
||||
|
||||
shared_examples 'filter params' do
|
||||
context 'with only_media param' do
|
||||
let(:params) { { only_media: true } }
|
||||
|
||||
it 'returns only statuses with media' do
|
||||
expect(subject.results.all?(&:with_media?)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'with tagged param' do
|
||||
let(:params) { { tagged: tag.name } }
|
||||
|
||||
it 'returns only statuses with tag' do
|
||||
expect(subject.results.all? { |s| s.tags.include?(tag) }).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'with exclude_replies param' do
|
||||
let(:params) { { exclude_replies: true } }
|
||||
|
||||
it 'returns only statuses that are not replies' do
|
||||
expect(subject.results.none?(&:reply?)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'with exclude_reblogs param' do
|
||||
let(:params) { { exclude_reblogs: true } }
|
||||
|
||||
it 'returns only statuses that are not reblogs' do
|
||||
expect(subject.results.none?(&:reblog?)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when accessed anonymously' do
|
||||
let(:current_account) { nil }
|
||||
let(:direct_status) { nil }
|
||||
|
||||
it 'returns only public statuses' do
|
||||
expect(subject.results.pluck(:visibility).uniq).to match_array %w(unlisted public)
|
||||
end
|
||||
|
||||
it 'returns public replies' do
|
||||
expect(subject.results.pluck(:in_reply_to_id)).to_not be_empty
|
||||
end
|
||||
|
||||
it 'returns public reblogs' do
|
||||
expect(subject.results.pluck(:reblog_of_id)).to_not be_empty
|
||||
end
|
||||
|
||||
it_behaves_like 'filter params'
|
||||
end
|
||||
|
||||
context 'when accessed with a blocked account' do
|
||||
let(:current_account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
account.block!(current_account)
|
||||
end
|
||||
|
||||
it 'returns nothing' do
|
||||
expect(subject.results.to_a).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when accessed by self' do
|
||||
let(:current_account) { account }
|
||||
|
||||
it 'returns everything' do
|
||||
expect(subject.results.pluck(:visibility).uniq).to match_array %w(direct private unlisted public)
|
||||
end
|
||||
|
||||
it 'returns replies' do
|
||||
expect(subject.results.pluck(:in_reply_to_id)).to_not be_empty
|
||||
end
|
||||
|
||||
it 'returns reblogs' do
|
||||
expect(subject.results.pluck(:reblog_of_id)).to_not be_empty
|
||||
end
|
||||
|
||||
it_behaves_like 'filter params'
|
||||
end
|
||||
|
||||
context 'when accessed by a follower' do
|
||||
let(:current_account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
current_account.follow!(account)
|
||||
end
|
||||
|
||||
it 'returns private statuses' do
|
||||
expect(subject.results.pluck(:visibility).uniq).to match_array %w(private unlisted public)
|
||||
end
|
||||
|
||||
it 'returns replies' do
|
||||
expect(subject.results.pluck(:in_reply_to_id)).to_not be_empty
|
||||
end
|
||||
|
||||
it 'returns reblogs' do
|
||||
expect(subject.results.pluck(:reblog_of_id)).to_not be_empty
|
||||
end
|
||||
|
||||
context 'when there is a direct status mentioning the non-follower' do
|
||||
let!(:direct_status) { status_with_mention!(:direct, current_account) }
|
||||
|
||||
it 'returns the direct status' do
|
||||
expect(subject.results.pluck(:id)).to include(direct_status.id)
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'filter params'
|
||||
end
|
||||
|
||||
context 'when accessed by a non-follower' do
|
||||
let(:current_account) { Fabricate(:account) }
|
||||
|
||||
it 'returns only public statuses' do
|
||||
expect(subject.results.pluck(:visibility).uniq).to match_array %w(unlisted public)
|
||||
end
|
||||
|
||||
it 'returns public replies' do
|
||||
expect(subject.results.pluck(:in_reply_to_id)).to_not be_empty
|
||||
end
|
||||
|
||||
it 'returns public reblogs' do
|
||||
expect(subject.results.pluck(:reblog_of_id)).to_not be_empty
|
||||
end
|
||||
|
||||
context 'when there is a private status mentioning the non-follower' do
|
||||
let!(:private_status) { status_with_mention!(:private, current_account) }
|
||||
|
||||
it 'returns the private status' do
|
||||
expect(subject.results.pluck(:id)).to include(private_status.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when blocking a reblogged account' do
|
||||
let(:reblog) { status_with_reblog!('public') }
|
||||
|
||||
before do
|
||||
current_account.block!(reblog.reblog.account)
|
||||
end
|
||||
|
||||
it 'does not return reblog of blocked account' do
|
||||
expect(subject.results.pluck(:id)).to_not include(reblog.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when muting a reblogged account' do
|
||||
let(:reblog) { status_with_reblog!('public') }
|
||||
|
||||
before do
|
||||
current_account.mute!(reblog.reblog.account)
|
||||
end
|
||||
|
||||
it 'does not return reblog of muted account' do
|
||||
expect(subject.results.pluck(:id)).to_not include(reblog.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when blocked by a reblogged account' do
|
||||
let(:reblog) { status_with_reblog!('public') }
|
||||
|
||||
before do
|
||||
reblog.reblog.account.block!(current_account)
|
||||
end
|
||||
|
||||
it 'does not return reblog of blocked-by account' do
|
||||
expect(subject.results.pluck(:id)).to_not include(reblog.id)
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'filter params'
|
||||
end
|
||||
end
|
||||
end
|
@@ -119,7 +119,7 @@ describe Report do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'validatiions' do
|
||||
describe 'validations' do
|
||||
it 'has a valid fabricator' do
|
||||
report = Fabricate(:report)
|
||||
report.valid?
|
||||
|
@@ -435,59 +435,6 @@ RSpec.describe Status, type: :model do
|
||||
end
|
||||
end
|
||||
|
||||
describe '.permitted_for' do
|
||||
subject { described_class.permitted_for(target_account, account).pluck(:visibility) }
|
||||
|
||||
let(:target_account) { alice }
|
||||
let(:account) { bob }
|
||||
let!(:public_status) { Fabricate(:status, account: target_account, visibility: 'public') }
|
||||
let!(:unlisted_status) { Fabricate(:status, account: target_account, visibility: 'unlisted') }
|
||||
let!(:private_status) { Fabricate(:status, account: target_account, visibility: 'private') }
|
||||
|
||||
let!(:direct_status) do
|
||||
Fabricate(:status, account: target_account, visibility: 'direct').tap do |status|
|
||||
Fabricate(:mention, status: status, account: account)
|
||||
end
|
||||
end
|
||||
|
||||
let!(:other_direct_status) do
|
||||
Fabricate(:status, account: target_account, visibility: 'direct').tap do |status|
|
||||
Fabricate(:mention, status: status)
|
||||
end
|
||||
end
|
||||
|
||||
context 'given nil' do
|
||||
let(:account) { nil }
|
||||
let(:direct_status) { nil }
|
||||
it { is_expected.to eq(%w(unlisted public)) }
|
||||
end
|
||||
|
||||
context 'given blocked account' do
|
||||
before do
|
||||
target_account.block!(account)
|
||||
end
|
||||
|
||||
it { is_expected.to be_empty }
|
||||
end
|
||||
|
||||
context 'given same account' do
|
||||
let(:account) { target_account }
|
||||
it { is_expected.to eq(%w(direct direct private unlisted public)) }
|
||||
end
|
||||
|
||||
context 'given followed account' do
|
||||
before do
|
||||
account.follow!(target_account)
|
||||
end
|
||||
|
||||
it { is_expected.to eq(%w(direct private unlisted public)) }
|
||||
end
|
||||
|
||||
context 'given unfollowed account' do
|
||||
it { is_expected.to eq(%w(direct unlisted public)) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'before_validation' do
|
||||
it 'sets account being replied to correctly over intermediary nodes' do
|
||||
first_status = Fabricate(:status, account: bob)
|
||||
|
@@ -114,13 +114,13 @@ RSpec.describe UserPolicy do
|
||||
|
||||
permissions :promote? do
|
||||
context 'admin?' do
|
||||
context 'promoteable?' do
|
||||
context 'promotable?' do
|
||||
it 'permits' do
|
||||
expect(subject).to permit(admin, john.user)
|
||||
end
|
||||
end
|
||||
|
||||
context '!promoteable?' do
|
||||
context '!promotable?' do
|
||||
it 'denies' do
|
||||
expect(subject).to_not permit(admin, admin.user)
|
||||
end
|
||||
|
58
spec/presenters/familiar_followers_presenter_spec.rb
Normal file
58
spec/presenters/familiar_followers_presenter_spec.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe FamiliarFollowersPresenter do
|
||||
describe '#accounts' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:familiar_follower) { Fabricate(:account) }
|
||||
let(:requested_accounts) { Fabricate.times(2, :account) }
|
||||
|
||||
subject { described_class.new(requested_accounts, account.id) }
|
||||
|
||||
before do
|
||||
familiar_follower.follow!(requested_accounts.first)
|
||||
account.follow!(familiar_follower)
|
||||
end
|
||||
|
||||
it 'returns a result for each requested account' do
|
||||
expect(subject.accounts.map(&:id)).to eq requested_accounts.map(&:id)
|
||||
end
|
||||
|
||||
it 'returns followers you follow' do
|
||||
result = subject.accounts.first
|
||||
|
||||
expect(result).to_not be_nil
|
||||
expect(result.id).to eq requested_accounts.first.id
|
||||
expect(result.accounts).to match_array([familiar_follower])
|
||||
end
|
||||
|
||||
context 'when requested account hides followers' do
|
||||
before do
|
||||
requested_accounts.first.update(hide_collections: true)
|
||||
end
|
||||
|
||||
it 'does not return followers you follow' do
|
||||
result = subject.accounts.first
|
||||
|
||||
expect(result).to_not be_nil
|
||||
expect(result.id).to eq requested_accounts.first.id
|
||||
expect(result.accounts).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when familiar follower hides follows' do
|
||||
before do
|
||||
familiar_follower.update(hide_collections: true)
|
||||
end
|
||||
|
||||
it 'does not return followers you follow' do
|
||||
result = subject.accounts.first
|
||||
|
||||
expect(result).to_not be_nil
|
||||
expect(result.id).to eq requested_accounts.first.id
|
||||
expect(result.accounts).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -63,20 +63,20 @@ RSpec.describe UnsuspendAccountService, type: :service do
|
||||
describe 'unsuspending a remote account' do
|
||||
include_examples 'common behavior' do
|
||||
let!(:account) { Fabricate(:account, domain: 'bob.com', uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
|
||||
let!(:reslove_account_service) { double }
|
||||
let!(:resolve_account_service) { double }
|
||||
|
||||
before do
|
||||
allow(ResolveAccountService).to receive(:new).and_return(reslove_account_service)
|
||||
allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service)
|
||||
end
|
||||
|
||||
context 'when the account is not remotely suspended' do
|
||||
before do
|
||||
allow(reslove_account_service).to receive(:call).with(account).and_return(account)
|
||||
allow(resolve_account_service).to receive(:call).with(account).and_return(account)
|
||||
end
|
||||
|
||||
it 're-fetches the account' do
|
||||
subject.call
|
||||
expect(reslove_account_service).to have_received(:call).with(account)
|
||||
expect(resolve_account_service).to have_received(:call).with(account)
|
||||
end
|
||||
|
||||
it "merges back into local followers' feeds" do
|
||||
@@ -92,7 +92,7 @@ RSpec.describe UnsuspendAccountService, type: :service do
|
||||
|
||||
context 'when the account is remotely suspended' do
|
||||
before do
|
||||
allow(reslove_account_service).to receive(:call).with(account) do |account|
|
||||
allow(resolve_account_service).to receive(:call).with(account) do |account|
|
||||
account.suspend!(origin: :remote)
|
||||
account
|
||||
end
|
||||
@@ -100,7 +100,7 @@ RSpec.describe UnsuspendAccountService, type: :service do
|
||||
|
||||
it 're-fetches the account' do
|
||||
subject.call
|
||||
expect(reslove_account_service).to have_received(:call).with(account)
|
||||
expect(resolve_account_service).to have_received(:call).with(account)
|
||||
end
|
||||
|
||||
it "does not merge back into local followers' feeds" do
|
||||
@@ -116,12 +116,12 @@ RSpec.describe UnsuspendAccountService, type: :service do
|
||||
|
||||
context 'when the account is remotely deleted' do
|
||||
before do
|
||||
allow(reslove_account_service).to receive(:call).with(account).and_return(nil)
|
||||
allow(resolve_account_service).to receive(:call).with(account).and_return(nil)
|
||||
end
|
||||
|
||||
it 're-fetches the account' do
|
||||
subject.call
|
||||
expect(reslove_account_service).to have_received(:call).with(account)
|
||||
expect(resolve_account_service).to have_received(:call).with(account)
|
||||
end
|
||||
|
||||
it "does not merge back into local followers' feeds" do
|
||||
|
@@ -22,7 +22,7 @@ module ProfileStories
|
||||
def with_alice_as_local_user
|
||||
@alice_bio = '@alice and @bob are fictional characters commonly used as'\
|
||||
'placeholder names in #cryptology, as well as #science and'\
|
||||
'engineering 📖 literature. Not affilated with @pepe.'
|
||||
'engineering 📖 literature. Not affiliated with @pepe.'
|
||||
|
||||
@alice = Fabricate(
|
||||
:user,
|
||||
|
Reference in New Issue
Block a user