Merge branch 'kb_development' into upstream-20231021
This commit is contained in:
commit
b992e673c7
25 changed files with 667 additions and 114 deletions
|
@ -246,6 +246,207 @@ RSpec.describe Account do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#allow_emoji_reaction?' do
|
||||
let(:policy) { :allow }
|
||||
let(:reactioned) { Fabricate(:user, settings: { emoji_reaction_policy: policy }).account }
|
||||
let(:followee) { Fabricate(:account) }
|
||||
let(:follower) { Fabricate(:account) }
|
||||
let(:mutual) { Fabricate(:account) }
|
||||
let(:anyone) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
follower.follow!(reactioned)
|
||||
reactioned.follow!(followee)
|
||||
mutual.follow!(reactioned)
|
||||
reactioned.follow!(mutual)
|
||||
end
|
||||
|
||||
context 'when policy is arrow' do
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be true
|
||||
end
|
||||
|
||||
it 'allows followee' do
|
||||
expect(reactioned.allow_emoji_reaction?(followee)).to be true
|
||||
end
|
||||
|
||||
it 'allows follower' do
|
||||
expect(reactioned.allow_emoji_reaction?(follower)).to be true
|
||||
end
|
||||
|
||||
it 'allows mutual' do
|
||||
expect(reactioned.allow_emoji_reaction?(mutual)).to be true
|
||||
end
|
||||
|
||||
it 'allows self' do
|
||||
expect(reactioned.allow_emoji_reaction?(reactioned)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when policy is following_only' do
|
||||
let(:policy) { :following_only }
|
||||
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be false
|
||||
end
|
||||
|
||||
it 'allows followee' do
|
||||
expect(reactioned.allow_emoji_reaction?(followee)).to be true
|
||||
end
|
||||
|
||||
it 'allows follower' do
|
||||
expect(reactioned.allow_emoji_reaction?(follower)).to be false
|
||||
end
|
||||
|
||||
it 'allows mutual' do
|
||||
expect(reactioned.allow_emoji_reaction?(mutual)).to be true
|
||||
end
|
||||
|
||||
it 'allows self' do
|
||||
expect(reactioned.allow_emoji_reaction?(reactioned)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when policy is followers_only' do
|
||||
let(:policy) { :followers_only }
|
||||
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be false
|
||||
end
|
||||
|
||||
it 'allows followee' do
|
||||
expect(reactioned.allow_emoji_reaction?(followee)).to be false
|
||||
end
|
||||
|
||||
it 'allows follower' do
|
||||
expect(reactioned.allow_emoji_reaction?(follower)).to be true
|
||||
end
|
||||
|
||||
it 'allows mutual' do
|
||||
expect(reactioned.allow_emoji_reaction?(mutual)).to be true
|
||||
end
|
||||
|
||||
it 'allows self' do
|
||||
expect(reactioned.allow_emoji_reaction?(reactioned)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when policy is mutuals_only' do
|
||||
let(:policy) { :mutuals_only }
|
||||
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be false
|
||||
end
|
||||
|
||||
it 'allows followee' do
|
||||
expect(reactioned.allow_emoji_reaction?(followee)).to be false
|
||||
end
|
||||
|
||||
it 'allows follower' do
|
||||
expect(reactioned.allow_emoji_reaction?(follower)).to be false
|
||||
end
|
||||
|
||||
it 'allows mutual' do
|
||||
expect(reactioned.allow_emoji_reaction?(mutual)).to be true
|
||||
end
|
||||
|
||||
it 'allows self' do
|
||||
expect(reactioned.allow_emoji_reaction?(reactioned)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when policy is outside_only' do
|
||||
let(:policy) { :outside_only }
|
||||
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be false
|
||||
end
|
||||
|
||||
it 'allows followee' do
|
||||
expect(reactioned.allow_emoji_reaction?(followee)).to be true
|
||||
end
|
||||
|
||||
it 'allows follower' do
|
||||
expect(reactioned.allow_emoji_reaction?(follower)).to be true
|
||||
end
|
||||
|
||||
it 'allows mutual' do
|
||||
expect(reactioned.allow_emoji_reaction?(mutual)).to be true
|
||||
end
|
||||
|
||||
it 'allows self' do
|
||||
expect(reactioned.allow_emoji_reaction?(reactioned)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when policy is block' do
|
||||
let(:policy) { :block }
|
||||
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be false
|
||||
end
|
||||
|
||||
it 'allows followee' do
|
||||
expect(reactioned.allow_emoji_reaction?(followee)).to be false
|
||||
end
|
||||
|
||||
it 'allows follower' do
|
||||
expect(reactioned.allow_emoji_reaction?(follower)).to be false
|
||||
end
|
||||
|
||||
it 'allows mutual' do
|
||||
expect(reactioned.allow_emoji_reaction?(mutual)).to be false
|
||||
end
|
||||
|
||||
it 'allows self' do
|
||||
expect(reactioned.allow_emoji_reaction?(reactioned)).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when reactioned is remote user' do
|
||||
let(:reactioned) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor', settings: { emoji_reaction_policy: :following_only }) }
|
||||
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be false
|
||||
end
|
||||
|
||||
it 'allows followee' do
|
||||
expect(reactioned.allow_emoji_reaction?(followee)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when reactor is remote user' do
|
||||
let(:anyone) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor/anyone') }
|
||||
let(:policy) { :following_only }
|
||||
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be false
|
||||
end
|
||||
|
||||
it 'allows followee' do
|
||||
expect(reactioned.allow_emoji_reaction?(followee)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when both are remote user' do
|
||||
let(:reactioned) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor', settings: { emoji_reaction_policy: policy }) }
|
||||
let(:anyone) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor/anyone') }
|
||||
let(:followee) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar/actor/followee') }
|
||||
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be true
|
||||
end
|
||||
|
||||
context 'with blocking' do
|
||||
let(:policy) { :block }
|
||||
|
||||
it 'allows anyone' do
|
||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#favourited?' do
|
||||
subject { Fabricate(:account) }
|
||||
|
||||
|
|
|
@ -9,19 +9,24 @@ end
|
|||
RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do
|
||||
subject { described_class.new }
|
||||
|
||||
let!(:status) { Fabricate(:status, text: 'Hello world', account: Fabricate(:account, domain: 'example.com')) }
|
||||
let(:thread) { nil }
|
||||
let!(:status) { Fabricate(:status, text: 'Hello world', account: Fabricate(:account, domain: 'example.com'), thread: thread) }
|
||||
let(:json_tags) do
|
||||
[
|
||||
{ type: 'Hashtag', name: 'hoge' },
|
||||
{ type: 'Mention', href: ActivityPub::TagManager.instance.uri_for(alice) },
|
||||
]
|
||||
end
|
||||
let(:content) { 'Hello universe' }
|
||||
let(:payload) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: 'foo',
|
||||
type: 'Note',
|
||||
summary: 'Show more',
|
||||
content: 'Hello universe',
|
||||
content: content,
|
||||
updated: '2021-09-08T22:39:25Z',
|
||||
tag: [
|
||||
{ type: 'Hashtag', name: 'hoge' },
|
||||
{ type: 'Mention', href: ActivityPub::TagManager.instance.uri_for(alice) },
|
||||
],
|
||||
tag: json_tags,
|
||||
}
|
||||
end
|
||||
let(:json) { Oj.load(Oj.dump(payload)) }
|
||||
|
@ -462,5 +467,161 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do
|
|||
subject.call(status, json, json)
|
||||
expect(status.reload.edited_at.to_s).to eq '2021-09-08 22:39:25 UTC'
|
||||
end
|
||||
|
||||
describe 'ng word is set' do
|
||||
let(:json_tags) { [] }
|
||||
|
||||
context 'when hit ng words' do
|
||||
let(:content) { 'ng word test' }
|
||||
|
||||
it 'update status' do
|
||||
Form::AdminSettings.new(ng_words: 'test').save
|
||||
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to_not eq content
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not hit ng words' do
|
||||
let(:content) { 'ng word aiueo' }
|
||||
|
||||
it 'update status' do
|
||||
Form::AdminSettings.new(ng_words: 'test').save
|
||||
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to eq content
|
||||
end
|
||||
end
|
||||
|
||||
context 'when hit ng words for mention' do
|
||||
let(:json_tags) do
|
||||
[
|
||||
{ type: 'Mention', href: ActivityPub::TagManager.instance.uri_for(alice) },
|
||||
]
|
||||
end
|
||||
let(:content) { 'ng word test' }
|
||||
|
||||
it 'update status' do
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
||||
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to_not eq content
|
||||
expect(status.mentioned_accounts.pluck(:id)).to_not include alice.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'when hit ng words for mention but local posts are not checked' do
|
||||
let(:json_tags) do
|
||||
[
|
||||
{ type: 'Mention', href: ActivityPub::TagManager.instance.uri_for(alice) },
|
||||
]
|
||||
end
|
||||
let(:content) { 'ng word test' }
|
||||
|
||||
it 'update status' do
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '0').save
|
||||
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to_not eq content
|
||||
expect(status.mentioned_accounts.pluck(:id)).to_not include alice.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'when hit ng words for mention to follower' do
|
||||
let(:json_tags) do
|
||||
[
|
||||
{ type: 'Mention', href: ActivityPub::TagManager.instance.uri_for(alice) },
|
||||
]
|
||||
end
|
||||
let(:content) { 'ng word test' }
|
||||
|
||||
before do
|
||||
alice.follow!(status.account)
|
||||
end
|
||||
|
||||
it 'update status' do
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test').save
|
||||
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to eq content
|
||||
expect(status.mentioned_accounts.pluck(:id)).to include alice.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'when hit ng words for reply' do
|
||||
let(:json_tags) do
|
||||
[
|
||||
{ type: 'Mention', href: ActivityPub::TagManager.instance.uri_for(alice) },
|
||||
]
|
||||
end
|
||||
let(:content) { 'ng word test' }
|
||||
let(:thread) { Fabricate(:status, account: alice) }
|
||||
|
||||
it 'update status' do
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test').save
|
||||
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to_not eq content
|
||||
expect(status.mentioned_accounts.pluck(:id)).to_not include alice.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'when hit ng words for reply to follower' do
|
||||
let(:json_tags) do
|
||||
[
|
||||
{ type: 'Mention', href: ActivityPub::TagManager.instance.uri_for(alice) },
|
||||
]
|
||||
end
|
||||
let(:content) { 'ng word test' }
|
||||
let(:thread) { Fabricate(:status, account: alice) }
|
||||
|
||||
before do
|
||||
alice.follow!(status.account)
|
||||
end
|
||||
|
||||
it 'update status' do
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test').save
|
||||
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to eq content
|
||||
expect(status.mentioned_accounts.pluck(:id)).to include alice.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using hashtag under limit' do
|
||||
let(:json_tags) do
|
||||
[
|
||||
{ type: 'Hashtag', name: 'a' },
|
||||
{ type: 'Hashtag', name: 'b' },
|
||||
]
|
||||
end
|
||||
let(:content) { 'ohagi is good' }
|
||||
|
||||
it 'update status' do
|
||||
Form::AdminSettings.new(post_hash_tags_max: 2).save
|
||||
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to eq content
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using hashtag over limit' do
|
||||
let(:json_tags) do
|
||||
[
|
||||
{ type: 'Hashtag', name: 'a' },
|
||||
{ type: 'Hashtag', name: 'b' },
|
||||
{ type: 'Hashtag', name: 'c' },
|
||||
]
|
||||
end
|
||||
let(:content) { 'ohagi is good' }
|
||||
|
||||
it 'update status' do
|
||||
Form::AdminSettings.new(post_hash_tags_max: 2).save
|
||||
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to_not eq content
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,6 +9,8 @@ RSpec.describe BackupService, type: :service do
|
|||
let!(:attachment) { Fabricate(:media_attachment, account: user.account) }
|
||||
let!(:status) { Fabricate(:status, account: user.account, text: 'Hello', visibility: :public, media_attachments: [attachment]) }
|
||||
let!(:private_status) { Fabricate(:status, account: user.account, text: 'secret', visibility: :private) }
|
||||
let!(:limited_status) { Fabricate(:status, account: user.account, text: 'sec mutual', visibility: :limited, limited_scope: :mutual) }
|
||||
let!(:reblog_status) { Fabricate(:status, account: user.account, reblog_of_id: Fabricate(:status).id) }
|
||||
let!(:favourite) { Fabricate(:favourite, account: user.account) }
|
||||
let!(:bookmark) { Fabricate(:bookmark, account: user.account) }
|
||||
let!(:backup) { Fabricate(:backup, user: user) }
|
||||
|
@ -60,10 +62,12 @@ RSpec.describe BackupService, type: :service do
|
|||
aggregate_failures do
|
||||
expect(json['@context']).to_not be_nil
|
||||
expect(json['type']).to eq 'OrderedCollection'
|
||||
expect(json['totalItems']).to eq 2
|
||||
expect(json['totalItems']).to eq 4
|
||||
expect(json['orderedItems'][0]['@context']).to be_nil
|
||||
expect(json['orderedItems'][0]).to include_create_item(status)
|
||||
expect(json['orderedItems'][1]).to include_create_item(private_status)
|
||||
expect(json['orderedItems'][2]).to include_create_item(limited_status)
|
||||
expect(json['orderedItems'][3]).to include_announce_item(reblog_status)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -98,4 +102,11 @@ RSpec.describe BackupService, type: :service do
|
|||
}),
|
||||
})
|
||||
end
|
||||
|
||||
def include_announce_item(status)
|
||||
include({
|
||||
'type' => 'Announce',
|
||||
'object' => ActivityPub::TagManager.instance.uri_for(status.reblog),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -510,6 +510,26 @@ RSpec.describe PostStatusService, type: :service do
|
|||
expect(status).to be_persisted
|
||||
expect(status.text).to eq text
|
||||
end
|
||||
|
||||
it 'using hashtag under limit' do
|
||||
account = Fabricate(:account)
|
||||
text = '#a #b'
|
||||
Form::AdminSettings.new(post_hash_tags_max: 2).save
|
||||
|
||||
status = subject.call(account, text: text)
|
||||
|
||||
expect(status).to be_persisted
|
||||
expect(status.tags.count).to eq 2
|
||||
expect(status.text).to eq text
|
||||
end
|
||||
|
||||
it 'using hashtag over limit' do
|
||||
account = Fabricate(:account)
|
||||
text = '#a #b #c'
|
||||
Form::AdminSettings.new(post_hash_tags_max: 2).save
|
||||
|
||||
expect { subject.call(account, text: text) }.to raise_error Mastodon::ValidationError
|
||||
end
|
||||
end
|
||||
|
||||
def create_status_with_options(**options)
|
||||
|
|
|
@ -218,4 +218,103 @@ RSpec.describe UpdateStatusService, type: :service do
|
|||
subject.call(status, status.account_id, text: 'Bar')
|
||||
expect(ActivityPub::DistributionWorker).to have_received(:perform_async)
|
||||
end
|
||||
|
||||
describe 'ng word is set' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:status) { PostStatusService.new.call(account, text: 'ohagi') }
|
||||
|
||||
it 'hit ng words' do
|
||||
text = 'ng word test'
|
||||
Form::AdminSettings.new(ng_words: 'test').save
|
||||
|
||||
expect { subject.call(status, status.account_id, text: text) }.to raise_error(Mastodon::ValidationError)
|
||||
end
|
||||
|
||||
it 'not hit ng words' do
|
||||
text = 'ng word aiueo'
|
||||
Form::AdminSettings.new(ng_words: 'test').save
|
||||
|
||||
status2 = subject.call(status, status.account_id, text: text)
|
||||
|
||||
expect(status2).to be_persisted
|
||||
expect(status2.text).to eq text
|
||||
end
|
||||
|
||||
it 'hit ng words for mention' do
|
||||
Fabricate(:account, username: 'ohagi', domain: nil)
|
||||
text = 'ng word test @ohagi'
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
||||
|
||||
expect { subject.call(status, status.account_id, text: text) }.to raise_error(Mastodon::ValidationError)
|
||||
expect(status.reload.text).to_not eq text
|
||||
expect(status.mentioned_accounts.pluck(:username)).to_not include 'ohagi'
|
||||
end
|
||||
|
||||
it 'hit ng words for mention but local posts are not checked' do
|
||||
Fabricate(:account, username: 'ohagi', domain: nil)
|
||||
text = 'ng word test @ohagi'
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '0').save
|
||||
|
||||
status2 = subject.call(status, status.account_id, text: text)
|
||||
|
||||
expect(status2).to be_persisted
|
||||
expect(status2.text).to eq text
|
||||
end
|
||||
|
||||
it 'hit ng words for mention to follower' do
|
||||
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
||||
mentioned.follow!(account)
|
||||
text = 'ng word test @ohagi'
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
||||
|
||||
status2 = subject.call(status, status.account_id, text: text)
|
||||
|
||||
expect(status2).to be_persisted
|
||||
expect(status2.text).to eq text
|
||||
end
|
||||
|
||||
it 'hit ng words for reply' do
|
||||
text = 'ng word test'
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
||||
|
||||
status = PostStatusService.new.call(account, text: 'hello', thread: Fabricate(:status))
|
||||
|
||||
expect { subject.call(status, status.account_id, text: text) }.to raise_error(Mastodon::ValidationError)
|
||||
expect(status.reload.text).to_not eq text
|
||||
end
|
||||
|
||||
it 'hit ng words for reply to follower' do
|
||||
mentioned = Fabricate(:account, username: 'ohagi', domain: nil)
|
||||
mentioned.follow!(account)
|
||||
text = 'ng word test'
|
||||
Form::AdminSettings.new(ng_words_for_stranger_mention: 'test', stranger_mention_from_local_ng: '1').save
|
||||
|
||||
status = PostStatusService.new.call(account, text: 'hello', thread: Fabricate(:status, account: mentioned))
|
||||
|
||||
status = subject.call(status, status.account_id, text: text)
|
||||
|
||||
expect(status).to be_persisted
|
||||
expect(status.text).to eq text
|
||||
end
|
||||
|
||||
it 'using hashtag under limit' do
|
||||
text = '#a #b'
|
||||
Form::AdminSettings.new(post_hash_tags_max: 2).save
|
||||
|
||||
subject.call(status, status.account_id, text: text)
|
||||
|
||||
expect(status.reload.tags.count).to eq 2
|
||||
expect(status.text).to eq text
|
||||
end
|
||||
|
||||
it 'using hashtag over limit' do
|
||||
text = '#a #b #c'
|
||||
Form::AdminSettings.new(post_hash_tags_max: 2).save
|
||||
|
||||
expect { subject.call(status, status.account_id, text: text) }.to raise_error Mastodon::ValidationError
|
||||
|
||||
expect(status.reload.tags.count).to eq 0
|
||||
expect(status.text).to_not eq text
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue