Add coverage for `Tag.recently_used` scope (#28850)
This commit is contained in:
parent
defe5f4076
commit
b0207d7757
|
@ -39,6 +39,8 @@ class Tag < ApplicationRecord
|
||||||
HASHTAG_NAME_RE = /\A(#{HASHTAG_NAME_PAT})\z/i
|
HASHTAG_NAME_RE = /\A(#{HASHTAG_NAME_PAT})\z/i
|
||||||
HASHTAG_INVALID_CHARS_RE = /[^[:alnum:]\u0E47-\u0E4E#{HASHTAG_SEPARATORS}]/
|
HASHTAG_INVALID_CHARS_RE = /[^[:alnum:]\u0E47-\u0E4E#{HASHTAG_SEPARATORS}]/
|
||||||
|
|
||||||
|
RECENT_STATUS_LIMIT = 1000
|
||||||
|
|
||||||
validates :name, presence: true, format: { with: HASHTAG_NAME_RE }
|
validates :name, presence: true, format: { with: HASHTAG_NAME_RE }
|
||||||
validates :display_name, format: { with: HASHTAG_NAME_RE }
|
validates :display_name, format: { with: HASHTAG_NAME_RE }
|
||||||
validate :validate_name_change, if: -> { !new_record? && name_changed? }
|
validate :validate_name_change, if: -> { !new_record? && name_changed? }
|
||||||
|
@ -53,7 +55,7 @@ class Tag < ApplicationRecord
|
||||||
scope :not_trendable, -> { where(trendable: false) }
|
scope :not_trendable, -> { where(trendable: false) }
|
||||||
scope :recently_used, lambda { |account|
|
scope :recently_used, lambda { |account|
|
||||||
joins(:statuses)
|
joins(:statuses)
|
||||||
.where(statuses: { id: account.statuses.select(:id).limit(1000) })
|
.where(statuses: { id: account.statuses.select(:id).limit(RECENT_STATUS_LIMIT) })
|
||||||
.group(:id).order(Arel.sql('count(*) desc'))
|
.group(:id).order(Arel.sql('count(*) desc'))
|
||||||
}
|
}
|
||||||
scope :matches_name, ->(term) { where(arel_table[:name].lower.matches(arel_table.lower("#{sanitize_sql_like(Tag.normalize(term))}%"), nil, true)) } # Search with case-sensitive to use B-tree index
|
scope :matches_name, ->(term) { where(arel_table[:name].lower.matches(arel_table.lower("#{sanitize_sql_like(Tag.normalize(term))}%"), nil, true)) } # Search with case-sensitive to use B-tree index
|
||||||
|
|
|
@ -100,6 +100,38 @@ RSpec.describe Tag do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.recently_used' do
|
||||||
|
let(:account) { Fabricate(:account) }
|
||||||
|
let(:other_person_status) { Fabricate(:status) }
|
||||||
|
let(:out_of_range) { Fabricate(:status, account: account) }
|
||||||
|
let(:older_in_range) { Fabricate(:status, account: account) }
|
||||||
|
let(:newer_in_range) { Fabricate(:status, account: account) }
|
||||||
|
let(:unused_tag) { Fabricate(:tag) }
|
||||||
|
let(:used_tag_one) { Fabricate(:tag) }
|
||||||
|
let(:used_tag_two) { Fabricate(:tag) }
|
||||||
|
let(:used_tag_on_out_of_range) { Fabricate(:tag) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_const 'Tag::RECENT_STATUS_LIMIT', 2
|
||||||
|
|
||||||
|
other_person_status.tags << used_tag_one
|
||||||
|
|
||||||
|
out_of_range.tags << used_tag_on_out_of_range
|
||||||
|
|
||||||
|
older_in_range.tags << used_tag_one
|
||||||
|
older_in_range.tags << used_tag_two
|
||||||
|
|
||||||
|
newer_in_range.tags << used_tag_one
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns tags used by account within last X statuses ordered most used first' do
|
||||||
|
results = described_class.recently_used(account)
|
||||||
|
|
||||||
|
expect(results)
|
||||||
|
.to eq([used_tag_one, used_tag_two])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '.find_normalized' do
|
describe '.find_normalized' do
|
||||||
it 'returns tag for a multibyte case-insensitive name' do
|
it 'returns tag for a multibyte case-insensitive name' do
|
||||||
upcase_string = 'abcABCabcABCやゆよ'
|
upcase_string = 'abcABCabcABCやゆよ'
|
||||||
|
|
Loading…
Reference in New Issue