]> cat aescling's git repositories - mastodon.git/commitdiff
Merge branch 'main' into glitch-soc/merge-upstream
authorClaire <claire.github-309c@sitedethib.com>
Sun, 23 Jan 2022 17:13:55 +0000 (18:13 +0100)
committerClaire <claire.github-309c@sitedethib.com>
Sun, 23 Jan 2022 17:24:01 +0000 (18:24 +0100)
Conflicts:
- `spec/models/status_spec.rb`:
  Upstream added tests too close to glitch-soc-specific tests.
  Kept both tests.

1  2 
app/controllers/auth/registrations_controller.rb
app/controllers/auth/sessions_controller.rb
app/helpers/application_helper.rb
app/javascript/mastodon/features/compose/components/compose_form.js
app/models/account.rb
app/models/status.rb
app/models/user.rb
app/views/layouts/public.html.haml
app/views/statuses/_simple_status.html.haml
db/schema.rb
spec/models/status_spec.rb

Simple merge
Simple merge
index d57026354e3876578b76b55533b06215b7c00f27,47671c0f529abd841f78dba811c335f26750def5..9bb2b3746e519810f397378de194c9fce12ed1fd
@@@ -108,14 -104,9 +108,11 @@@ class Status < ApplicationRecor
      end
    }
    scope :tagged_with_none, ->(tag_ids) {
-     Array(tag_ids).reduce(self) do |result, id|
-       result.joins("LEFT OUTER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}")
-             .where("t#{id}.tag_id IS NULL")
-     end
+     where('NOT EXISTS (SELECT * FROM statuses_tags forbidden WHERE forbidden.status_id = statuses.id AND forbidden.tag_id IN (?))', tag_ids)
    }
  
 +  scope :not_local_only, -> { where(local_only: [false, nil]) }
 +
    cache_associated :application,
                     :media_attachments,
                     :conversation,
Simple merge
Simple merge
diff --cc db/schema.rb
Simple merge
index c1375ea944eedfa5c26e8c17423b67944d09c8f5,653575778b21c5258891e4ee4ba0db294c509a1f..25c98d508cebdd40af746b1e469d4c50e195ec4e
@@@ -304,56 -267,87 +304,137 @@@ RSpec.describe Status, type: :model d
      end
    end
  
 +  describe '.as_direct_timeline' do
 +    let(:account) { Fabricate(:account) }
 +    let(:followed) { Fabricate(:account) }
 +    let(:not_followed) { Fabricate(:account) }
 +
 +    before do
 +      Fabricate(:follow, account: account, target_account: followed)
 +
 +      @self_public_status = Fabricate(:status, account: account, visibility: :public)
 +      @self_direct_status = Fabricate(:status, account: account, visibility: :direct)
 +      @followed_public_status = Fabricate(:status, account: followed, visibility: :public)
 +      @followed_direct_status = Fabricate(:status, account: followed, visibility: :direct)
 +      @not_followed_direct_status = Fabricate(:status, account: not_followed, visibility: :direct)
 +
 +      @results = Status.as_direct_timeline(account)
 +    end
 +
 +    it 'does not include public statuses from self' do
 +      expect(@results).to_not include(@self_public_status)
 +    end
 +
 +    it 'includes direct statuses from self' do
 +      expect(@results).to include(@self_direct_status)
 +    end
 +
 +    it 'does not include public statuses from followed' do
 +      expect(@results).to_not include(@followed_public_status)
 +    end
 +
 +    it 'does not include direct statuses not mentioning recipient from followed' do
 +      expect(@results).to_not include(@followed_direct_status)
 +    end
 +
 +    it 'does not include direct statuses not mentioning recipient from non-followed' do
 +      expect(@results).to_not include(@not_followed_direct_status)
 +    end
 +
 +    it 'includes direct statuses mentioning recipient from followed' do
 +      Fabricate(:mention, account: account, status: @followed_direct_status)
 +      results2 = Status.as_direct_timeline(account)
 +      expect(results2).to include(@followed_direct_status)
 +    end
 +
 +    it 'includes direct statuses mentioning recipient from non-followed' do
 +      Fabricate(:mention, account: account, status: @not_followed_direct_status)
 +      results2 = Status.as_direct_timeline(account)
 +      expect(results2).to include(@not_followed_direct_status)
 +    end
 +  end
 +
+   describe '.tagged_with' do
+     let(:tag1)     { Fabricate(:tag) }
+     let(:tag2)     { Fabricate(:tag) }
+     let(:tag3)     { Fabricate(:tag) }
+     let!(:status1) { Fabricate(:status, tags: [tag1]) }
+     let!(:status2) { Fabricate(:status, tags: [tag2]) }
+     let!(:status3) { Fabricate(:status, tags: [tag3]) }
+     let!(:status4) { Fabricate(:status, tags: []) }
+     let!(:status5) { Fabricate(:status, tags: [tag1, tag2, tag3]) }
+     context 'when given one tag' do
+       it 'returns the expected statuses' do
+         expect(Status.tagged_with([tag1.id]).reorder(:id).pluck(:id).uniq).to eq [status1.id, status5.id]
+         expect(Status.tagged_with([tag2.id]).reorder(:id).pluck(:id).uniq).to eq [status2.id, status5.id]
+         expect(Status.tagged_with([tag3.id]).reorder(:id).pluck(:id).uniq).to eq [status3.id, status5.id]
+       end
+     end
+     context 'when given multiple tags' do
+       it 'returns the expected statuses' do
+         expect(Status.tagged_with([tag1.id, tag2.id]).reorder(:id).pluck(:id).uniq).to eq [status1.id, status2.id, status5.id]
+         expect(Status.tagged_with([tag1.id, tag3.id]).reorder(:id).pluck(:id).uniq).to eq [status1.id, status3.id, status5.id]
+         expect(Status.tagged_with([tag2.id, tag3.id]).reorder(:id).pluck(:id).uniq).to eq [status2.id, status3.id, status5.id]
+       end
+     end
+   end
+   describe '.tagged_with_all' do
+     let(:tag1)     { Fabricate(:tag) }
+     let(:tag2)     { Fabricate(:tag) }
+     let(:tag3)     { Fabricate(:tag) }
+     let!(:status1) { Fabricate(:status, tags: [tag1]) }
+     let!(:status2) { Fabricate(:status, tags: [tag2]) }
+     let!(:status3) { Fabricate(:status, tags: [tag3]) }
+     let!(:status4) { Fabricate(:status, tags: []) }
+     let!(:status5) { Fabricate(:status, tags: [tag1, tag2]) }
+     context 'when given one tag' do
+       it 'returns the expected statuses' do
+         expect(Status.tagged_with_all([tag1.id]).reorder(:id).pluck(:id).uniq).to eq [status1.id, status5.id]
+         expect(Status.tagged_with_all([tag2.id]).reorder(:id).pluck(:id).uniq).to eq [status2.id, status5.id]
+         expect(Status.tagged_with_all([tag3.id]).reorder(:id).pluck(:id).uniq).to eq [status3.id]
+       end
+     end
+     context 'when given multiple tags' do
+       it 'returns the expected statuses' do
+         expect(Status.tagged_with_all([tag1.id, tag2.id]).reorder(:id).pluck(:id).uniq).to eq [status5.id]
+         expect(Status.tagged_with_all([tag1.id, tag3.id]).reorder(:id).pluck(:id).uniq).to eq []
+         expect(Status.tagged_with_all([tag2.id, tag3.id]).reorder(:id).pluck(:id).uniq).to eq []
+       end
+     end
+   end
+   describe '.tagged_with_none' do
+     let(:tag1)     { Fabricate(:tag) }
+     let(:tag2)     { Fabricate(:tag) }
+     let(:tag3)     { Fabricate(:tag) }
+     let!(:status1) { Fabricate(:status, tags: [tag1]) }
+     let!(:status2) { Fabricate(:status, tags: [tag2]) }
+     let!(:status3) { Fabricate(:status, tags: [tag3]) }
+     let!(:status4) { Fabricate(:status, tags: []) }
+     let!(:status5) { Fabricate(:status, tags: [tag1, tag2, tag3]) }
+     context 'when given one tag' do
+       it 'returns the expected statuses' do
+         expect(Status.tagged_with_none([tag1.id]).reorder(:id).pluck(:id).uniq).to eq [status2.id, status3.id, status4.id]
+         expect(Status.tagged_with_none([tag2.id]).reorder(:id).pluck(:id).uniq).to eq [status1.id, status3.id, status4.id]
+         expect(Status.tagged_with_none([tag3.id]).reorder(:id).pluck(:id).uniq).to eq [status1.id, status2.id, status4.id]
+       end
+     end
+     context 'when given multiple tags' do
+       it 'returns the expected statuses' do
+         expect(Status.tagged_with_none([tag1.id, tag2.id]).reorder(:id).pluck(:id).uniq).to eq [status3.id, status4.id]
+         expect(Status.tagged_with_none([tag1.id, tag3.id]).reorder(:id).pluck(:id).uniq).to eq [status2.id, status4.id]
+         expect(Status.tagged_with_none([tag2.id, tag3.id]).reorder(:id).pluck(:id).uniq).to eq [status1.id, status4.id]
+       end
+     end
+   end
    describe '.permitted_for' do
      subject { described_class.permitted_for(target_account, account).pluck(:visibility) }