Announcement reactions query spec improvement and refactor (#28768)
This commit is contained in:
		
							parent
							
								
									afb5e6cf46
								
							
						
					
					
						commit
						1b0cb3b54d
					
				| @ -75,22 +75,41 @@ class Announcement < ApplicationRecord | |||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def reactions(account = nil) |   def reactions(account = nil) | ||||||
|     records = begin |     grouped_ordered_announcement_reactions.select( | ||||||
|       scope = announcement_reactions.group(:announcement_id, :name, :custom_emoji_id).order(Arel.sql('MIN(created_at) ASC')) |       [:name, :custom_emoji_id, 'COUNT(*) as count'].tap do |values| | ||||||
| 
 |         values << value_for_reaction_me_column(account) | ||||||
|       if account.nil? |  | ||||||
|         scope.select('name, custom_emoji_id, count(*) as count, false as me') |  | ||||||
|       else |  | ||||||
|         scope.select("name, custom_emoji_id, count(*) as count, exists(select 1 from announcement_reactions r where r.account_id = #{account.id} and r.announcement_id = announcement_reactions.announcement_id and r.name = announcement_reactions.name) as me") |  | ||||||
|       end |       end | ||||||
|     end.to_a |     ).to_a.tap do |records| | ||||||
| 
 |       ActiveRecord::Associations::Preloader.new(records: records, associations: :custom_emoji).call | ||||||
|     ActiveRecord::Associations::Preloader.new(records: records, associations: :custom_emoji).call |     end | ||||||
|     records |  | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   private |   private | ||||||
| 
 | 
 | ||||||
|  |   def grouped_ordered_announcement_reactions | ||||||
|  |     announcement_reactions | ||||||
|  |       .group(:announcement_id, :name, :custom_emoji_id) | ||||||
|  |       .order( | ||||||
|  |         Arel.sql('MIN(created_at)').asc | ||||||
|  |       ) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def value_for_reaction_me_column(account) | ||||||
|  |     if account.nil? | ||||||
|  |       'FALSE AS me' | ||||||
|  |     else | ||||||
|  |       <<~SQL.squish | ||||||
|  |         EXISTS( | ||||||
|  |           SELECT 1 | ||||||
|  |           FROM announcement_reactions inner_reactions | ||||||
|  |           WHERE inner_reactions.account_id = #{account.id} | ||||||
|  |             AND inner_reactions.announcement_id = announcement_reactions.announcement_id | ||||||
|  |             AND inner_reactions.name = announcement_reactions.name | ||||||
|  |         ) AS me | ||||||
|  |       SQL | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   def set_published |   def set_published | ||||||
|     return unless scheduled_at.blank? || scheduled_at.past? |     return unless scheduled_at.blank? || scheduled_at.past? | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -115,26 +115,35 @@ describe Announcement do | |||||||
| 
 | 
 | ||||||
|   describe '#reactions' do |   describe '#reactions' do | ||||||
|     context 'with announcement_reactions present' do |     context 'with announcement_reactions present' do | ||||||
|  |       let(:account_reaction_emoji) { Fabricate :custom_emoji } | ||||||
|  |       let(:other_reaction_emoji) { Fabricate :custom_emoji } | ||||||
|       let!(:account) { Fabricate(:account) } |       let!(:account) { Fabricate(:account) } | ||||||
|       let!(:announcement) { Fabricate(:announcement) } |       let!(:announcement) { Fabricate(:announcement) } | ||||||
|       let!(:announcement_reaction) { Fabricate(:announcement_reaction, announcement: announcement, created_at: 10.days.ago) } |  | ||||||
|       let!(:announcement_reaction_account) { Fabricate(:announcement_reaction, announcement: announcement, created_at: 5.days.ago, account: account) } |  | ||||||
| 
 | 
 | ||||||
|       before do |       before do | ||||||
|         Fabricate(:announcement_reaction) |         Fabricate(:announcement_reaction, announcement: announcement, created_at: 10.days.ago, name: other_reaction_emoji.shortcode) | ||||||
|  |         Fabricate(:announcement_reaction, announcement: announcement, created_at: 5.days.ago, account: account, name: account_reaction_emoji.shortcode) | ||||||
|  |         Fabricate(:announcement_reaction) # For some other announcement | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       it 'returns the announcement reactions for the announcement' do |       it 'returns the announcement reactions for the announcement' do | ||||||
|         results = announcement.reactions |         results = announcement.reactions | ||||||
| 
 | 
 | ||||||
|         expect(results.first.name).to eq(announcement_reaction.name) |         expect(results).to have_attributes( | ||||||
|         expect(results.last.name).to eq(announcement_reaction_account.name) |           size: eq(2), | ||||||
|  |           first: have_attributes(name: other_reaction_emoji.shortcode, me: false), | ||||||
|  |           last: have_attributes(name: account_reaction_emoji.shortcode, me: false) | ||||||
|  |         ) | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       it 'returns the announcement reactions for the announcement limited to account' do |       it 'returns the announcement reactions for the announcement with `me` set correctly' do | ||||||
|         results = announcement.reactions(account) |         results = announcement.reactions(account) | ||||||
| 
 | 
 | ||||||
|         expect(results.first.name).to eq(announcement_reaction.name) |         expect(results).to have_attributes( | ||||||
|  |           size: eq(2), | ||||||
|  |           first: have_attributes(name: other_reaction_emoji.shortcode, me: false), | ||||||
|  |           last: have_attributes(name: account_reaction_emoji.shortcode, me: true) | ||||||
|  |         ) | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user