diff --git a/app/models/user_first.rb b/app/models/user_first.rb deleted file mode 100644 index 80e875b7e..000000000 --- a/app/models/user_first.rb +++ /dev/null @@ -1,19 +0,0 @@ -class UserFirst < ActiveRecord::Base - - def self.types - @types ||= Enum.new(used_emoji: 1, - mentioned_user: 2 #unused now - ) - end - - def self.create_for(user_id, type, post_id=nil) - # the usual case will be that it is already in table, don't try to insert - return false if UserFirst.exists?(user_id: user_id, first_type: types[type]) - - create!(user_id: user_id, first_type: types[type], post_id: post_id) - true - rescue PG::UniqueViolation, ActiveRecord::RecordNotUnique - # Violating the index just means the user already did it - false - end -end diff --git a/db/fixtures/006_badges.rb b/db/fixtures/006_badges.rb index 9de13c996..3f02e0fe6 100644 --- a/db/fixtures/006_badges.rb +++ b/db/fixtures/006_badges.rb @@ -379,7 +379,7 @@ Badge.seed do |b| b.multiple_grant = false b.target_posts = true b.show_posts = true - b.query = BadgeQueries.has_user_first(:used_emoji) + b.query = nil b.badge_grouping_id = BadgeGrouping::GettingStarted b.default_badge_grouping_id = BadgeGrouping::GettingStarted b.trigger = Badge::Trigger::PostProcessed diff --git a/db/migrate/20160407160756_remove_user_firsts.rb b/db/migrate/20160407160756_remove_user_firsts.rb new file mode 100644 index 000000000..2fda4c75f --- /dev/null +++ b/db/migrate/20160407160756_remove_user_firsts.rb @@ -0,0 +1,5 @@ +class RemoveUserFirsts < ActiveRecord::Migration + def up + drop_table :user_firsts + end +end diff --git a/lib/badge_queries.rb b/lib/badge_queries.rb index 8f32017b1..765c07375 100644 --- a/lib/badge_queries.rb +++ b/lib/badge_queries.rb @@ -246,13 +246,4 @@ SQL SQL end - def self.has_user_first(type) - <<SQL - SELECT uf.user_id, uf.post_id, uf.created_at AS granted_at - FROM user_firsts AS uf - WHERE (:backfill OR uf.user_id IN (:user_ids)) - AND uf.first_type = #{UserFirst.types[type]} -SQL - end - end diff --git a/lib/cooked_post_processor.rb b/lib/cooked_post_processor.rb index 6b730d719..d0f939ffa 100644 --- a/lib/cooked_post_processor.rb +++ b/lib/cooked_post_processor.rb @@ -28,7 +28,7 @@ class CookedPostProcessor post_process_oneboxes optimize_urls pull_hotlinked_images(bypass_bump) - create_firsts + grant_badges end end @@ -36,17 +36,11 @@ class CookedPostProcessor (@doc.css("img.emoji") - @doc.css(".quote img")).size > 0 end - def create_firsts + def grant_badges return unless Guardian.new.can_see?(@post) - created = false - if has_emoji? - created |= UserFirst.create_for(@post.user_id, :used_emoji, @post.id) - end - - if created - BadgeGranter.queue_badge_grant(Badge::Trigger::PostProcessed, user: @post.user) + BadgeGranter.grant(Badge.find(Badge::FirstEmoji), @post.user) end end diff --git a/spec/components/cooked_post_processor_spec.rb b/spec/components/cooked_post_processor_spec.rb index 800713400..b83a76658 100644 --- a/spec/components/cooked_post_processor_spec.rb +++ b/spec/components/cooked_post_processor_spec.rb @@ -478,4 +478,26 @@ describe CookedPostProcessor do end + context "grant badges" do + context "emoji inside a quote" do + let(:post) { Fabricate(:post, raw: "time to eat some sweet [quote]:candy:[/quote] mmmm") } + let(:cpp) { CookedPostProcessor.new(post) } + + it "doesn't award a badge when the emoji is in a quote" do + cpp.grant_badges + expect(post.user.user_badges.where(badge_id: Badge::FirstEmoji).exists?).to eq(false) + end + end + + context "emoji in the text" do + let(:post) { Fabricate(:post, raw: "time to eat some sweet :candy: mmmm") } + let(:cpp) { CookedPostProcessor.new(post) } + + it "awards a badge for using an emoji" do + cpp.grant_badges + expect(post.user.user_badges.where(badge_id: Badge::FirstEmoji).exists?).to eq(true) + end + end + end + end diff --git a/spec/models/user_firsts_spec.rb b/spec/models/user_firsts_spec.rb deleted file mode 100644 index c93d49103..000000000 --- a/spec/models/user_firsts_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -require 'rails_helper' - -describe UserFirst do - - let(:user) { Fabricate(:user) } - - context "#create_for" do - it "doesn't raise an error on duplicate" do - expect(UserFirst.create_for(user.id, :used_emoji)).to eq(true) - expect(UserFirst.create_for(user.id, :used_emoji)).to eq(false) - end - end - - context "emoji" do - it "logs a user first" do - post = PostCreator.create(user, title: "this topic is about candy", raw: "time to eat some sweet :candy: mmmm") - - uf = UserFirst.where(user_id: user.id, first_type: UserFirst.types[:used_emoji]).first - expect(uf).to be_present - expect(uf.post_id).to eq(post.id) - end - - it "doesn't log a user first when in a quote" do - PostCreator.create(user, - title: "this topic is about candy", - raw: "time to eat some sweet [quote]:candy:[/quote] mmmm") - - uf = UserFirst.where(user_id: user.id, first_type: UserFirst.types[:used_emoji]).first - expect(uf).to be_blank - end - - end - - context "privacy" do - let(:codinghorror) { Fabricate(:codinghorror) } - - it "doesn't create the userfirst on private posts" do - PostCreator.create(user, - archetype: Archetype.private_message, - target_usernames: ['codinghorror'], - title: "this topic is about candy", - raw: "time to eat some sweet :candy: mmmm") - - uf = UserFirst.where(user_id: user.id, first_type: UserFirst.types[:used_emoji]).first - expect(uf).to be_blank - end - end -end