diff --git a/app/models/status.rb b/app/models/status.rb index 1bc4c633d3..db3072571b 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -276,7 +276,11 @@ class Status < ApplicationRecord def marked_local_only? # match both with and without U+FE0F (the emoji variation selector) - /👁\ufe0f?\z/.match?(content) + /#{local_only_emoji}\ufe0f?\z/.match?(content) + end + + def local_only_emoji + '👁' end private @@ -305,7 +309,7 @@ class Status < ApplicationRecord end def set_locality - if account.domain.nil? + if account.domain.nil? && !attribute_changed?(:local_only) self.local_only = marked_local_only? end end diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index c6701018e5..5b0adb769a 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -197,6 +197,43 @@ RSpec.describe Status, type: :model do end end + describe 'on create' do + let(:local_account) { Fabricate(:account, username: 'local', domain: nil) } + let(:remote_account) { Fabricate(:account, username: 'remote', domain: 'example.com') } + + subject { Status.new } + + describe 'on a status that ends with the local-only emoji' do + before do + subject.text = 'A toot ' + subject.local_only_emoji + end + + context 'if the status originates from this instance' do + before do + subject.account = local_account + end + + it 'is marked local-only' do + subject.save! + + expect(subject).to be_local_only + end + end + + context 'if the status is remote' do + before do + subject.account = remote_account + end + + it 'is not marked local-only' do + subject.save! + + expect(subject).to_not be_local_only + end + end + end + end + describe '.mutes_map' do let(:status) { Fabricate(:status) } let(:account) { Fabricate(:account) } @@ -570,6 +607,27 @@ RSpec.describe Status, type: :model do results = Status.as_tag_timeline(tag) expect(results).to include(status) end + + context 'on a local-only status' do + let(:tag) { Fabricate(:tag) } + let(:status) { Fabricate(:status, local_only: true, tags: [tag]) } + + context 'if account is nil' do + let(:account) { nil } + + it 'filters the local-only status out of the result set' do + expect(Status.as_tag_timeline(tag, account)).not_to include(status) + end + end + + context 'if account is not nil and local' do + let(:account) { Fabricate(:account, domain: nil) } + + it 'keeps the local-only status in the result set' do + expect(Status.as_tag_timeline(tag, account)).to include(status) + end + end + end end describe '.permitted_for' do