Wellness badge query+service refactor (#17592)
* Query +service slight refactor * 33 week comment
This commit is contained in:
parent
6d6287d93f
commit
bf4d34fe9c
4 changed files with 69 additions and 53 deletions
|
|
@ -2,8 +2,8 @@
|
|||
# [
|
||||
# {
|
||||
# "user_id"=>11,
|
||||
# "serialized_weeks_ago"=>"1,16,20",
|
||||
# "serialized_comment_counts"=>"2,2,1"
|
||||
# "serialized_weeks_ago"=>"0,1,16,20",
|
||||
# "serialized_comment_counts"=>"2,2,1,3"
|
||||
# },
|
||||
# ...
|
||||
# ]
|
||||
|
|
@ -33,19 +33,19 @@ module Comments
|
|||
SELECT user_id,
|
||||
COUNT(user_id) AS number_of_comments_with_positive_reaction,
|
||||
/* Get the number of weeks, since today for posts */
|
||||
(trunc((extract(epoch FROM (current_timestamp- created_at))) / 604800) + 1) AS weeks_ago
|
||||
trunc((extract(epoch FROM (current_timestamp- created_at))) / 604800) AS weeks_ago
|
||||
FROM comments
|
||||
INNER JOIN
|
||||
(
|
||||
SELECT DISTINCT reactable_id
|
||||
FROM reactions
|
||||
WHERE reactable_type = 'Comment'
|
||||
AND created_at > (now() - interval '224' day)
|
||||
AND created_at > (now() - interval '231' day)
|
||||
EXCEPT
|
||||
SELECT DISTINCT reactable_id
|
||||
FROM reactions
|
||||
WHERE reactable_type = 'Comment'
|
||||
AND created_at > (now() - interval '224' day)
|
||||
AND created_at > (now() - interval '231' day)
|
||||
AND category IN ('thumbsdown', 'vomit')) AS negative_reactions
|
||||
ON comments.id = negative_reactions.reactable_id
|
||||
INNER JOIN
|
||||
|
|
@ -53,13 +53,14 @@ module Comments
|
|||
SELECT count(id) AS number_of_comments,
|
||||
user_id AS comment_counts_user_id
|
||||
FROM comments
|
||||
WHERE created_at >= (now() - interval '7' day)
|
||||
/* This interval filters week 1 (what we care about) */
|
||||
WHERE created_at >= (now() - interval '14' day)
|
||||
AND created_at <= (now() - interval '7' day)
|
||||
GROUP BY user_id) AS comment_counts
|
||||
ON comments.user_id = comment_counts_user_id
|
||||
AND comment_counts.number_of_comments > 1
|
||||
/* Don’t select anything older than 224 days ago, or 32 weeks ago */
|
||||
WHERE created_at > (now() - interval '224' day)
|
||||
AND created_at < (now() - interval '3' day)
|
||||
/* Don’t select anything older than 231 days ago, or 33 weeks ago */
|
||||
WHERE created_at > (now() - interval '231' day)
|
||||
GROUP BY user_id, weeks_ago) AS user_comment_counts_by_week
|
||||
GROUP BY user_id
|
||||
SQL
|
||||
|
|
|
|||
|
|
@ -13,13 +13,16 @@ module Badges
|
|||
|
||||
# `weeks_ago` can have values like the following:
|
||||
# - [1,2,10,11,12]
|
||||
# - [5]
|
||||
# - [1,2,3,4,5,6,7,8]
|
||||
# - [0,5]
|
||||
# - [0,1,2,3,4,5,6,7,8]
|
||||
# - [1,4,17]
|
||||
# We only care for active streak (starting at 1) so we need to filter
|
||||
# these to check how far back the (continuous) streak goes
|
||||
week_streak = 0
|
||||
weeks_ago.each_with_index do |week, index|
|
||||
# Week 0 are comments that exist but aren't at least 1 week old yet
|
||||
next if week.zero?
|
||||
|
||||
# Must have 2 or more non-flagged comments posted on that week
|
||||
next unless comment_counts[index] > 1
|
||||
|
||||
|
|
|
|||
|
|
@ -15,38 +15,43 @@ RSpec.describe Comments::CommunityWellnessQuery, type: :query do
|
|||
# don't meet the query criteria: min 2 comments in a week within last 32 weeks
|
||||
before do
|
||||
# User 3 - only one comment
|
||||
create_comment_time_ago(user3.id, 5.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user3.id, 8.days.ago, commentable: articles.sample)
|
||||
|
||||
# User 4 - has 3 comments but doesn't meet criteria bc comments are too old
|
||||
create_comment_time_ago(user4.id, 226.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user4.id, 227.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user4.id, 227.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user4.id, 233.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user4.id, 237.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user4.id, 239.days.ago, commentable: articles.sample)
|
||||
end
|
||||
|
||||
context "when multiple users match criteria" do
|
||||
before do
|
||||
# User 1 - week 1
|
||||
# User 1 - week 0
|
||||
create_comment_time_ago(user1.id, 5.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user1.id, 6.days.ago, commentable: articles.sample)
|
||||
# User 1 - week 2
|
||||
# User 1 - week 1
|
||||
create_comment_time_ago(user1.id, 8.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user1.id, 11.days.ago, commentable: articles.sample)
|
||||
|
||||
# User 2 - week 1
|
||||
create_comment_time_ago(user2.id, 4.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 6.days.ago, commentable: articles.sample)
|
||||
# User 1 - week 2
|
||||
create_comment_time_ago(user1.id, 15.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user1.id, 15.days.ago, commentable: articles.sample)
|
||||
|
||||
# User 2 - week 0
|
||||
create_comment_time_ago(user2.id, 1.day.ago, commentable: articles.sample)
|
||||
# User 2 - week 1
|
||||
create_comment_time_ago(user2.id, 9.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 13.days.ago, commentable: articles.sample)
|
||||
# User 1 - week 3
|
||||
create_comment_time_ago(user2.id, 17.days.ago, commentable: articles.sample)
|
||||
# User 2 - week 2
|
||||
create_comment_time_ago(user2.id, 17.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 18.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 18.days.ago, commentable: articles.sample)
|
||||
# User 2 - week 3
|
||||
create_comment_time_ago(user2.id, 22.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 23.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 23.days.ago, commentable: articles.sample)
|
||||
|
||||
# User 5 - has 2 comments in the first week but too early to award because
|
||||
# comments must be 3 days old or more to give mods time to flag before award
|
||||
create_comment_time_ago(user5.id, 2.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user5.id, 6.days.ago, commentable: articles.sample)
|
||||
# User 5 - week 1
|
||||
create_comment_time_ago(user5.id, 8.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user5.id, 10.days.ago, commentable: articles.sample)
|
||||
end
|
||||
|
||||
it "returns the correct data structure (array of hashes w/ correct keys)" do
|
||||
|
|
@ -69,40 +74,46 @@ RSpec.describe Comments::CommunityWellnessQuery, type: :query do
|
|||
expect(result_user_ids).to contain_exactly(user1.id, user2.id, user5.id)
|
||||
|
||||
index1 = result.index { |hash| hash["user_id"] == user1.id }
|
||||
expect(result[index1]["serialized_weeks_ago"]).to eq("1,2")
|
||||
expect(result[index1]["serialized_comment_counts"]).to eq("2,2")
|
||||
expect(result[index1]["serialized_weeks_ago"]).to eq("0,1,2")
|
||||
expect(result[index1]["serialized_comment_counts"]).to eq("2,2,2")
|
||||
|
||||
index2 = result.index { |hash| hash["user_id"] == user2.id }
|
||||
expect(result[index2]["serialized_weeks_ago"]).to eq("1,2,3")
|
||||
expect(result[index2]["serialized_comment_counts"]).to eq("2,2,3")
|
||||
expect(result[index2]["serialized_weeks_ago"]).to eq("0,1,2,3")
|
||||
expect(result[index2]["serialized_comment_counts"]).to eq("1,2,3,3")
|
||||
|
||||
# user5 will still appear in the query because it has 2 comments in the
|
||||
# week but the count will reflect only those that are 3+ days old
|
||||
# user5 will still appear in the query despite not having any comments in
|
||||
# week 0, because we start counting at week 1 to award the badge
|
||||
index5 = result.index { |hash| hash["user_id"] == user5.id }
|
||||
expect(result[index5]["serialized_weeks_ago"]).to eq("1")
|
||||
expect(result[index5]["serialized_comment_counts"]).to eq("1")
|
||||
expect(result[index5]["serialized_comment_counts"]).to eq("2")
|
||||
end
|
||||
end
|
||||
|
||||
context "when users match criteria but mod reaction reduces their comment counts" do
|
||||
before do
|
||||
# User 1 - week 1
|
||||
create_comment_time_ago(user1.id, 5.days.ago, commentable: articles.sample, flagged_by: mod)
|
||||
# User 1 - week 0
|
||||
create_comment_time_ago(user1.id, 5.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user1.id, 6.days.ago, commentable: articles.sample)
|
||||
# User 1 - week 2
|
||||
create_comment_time_ago(user1.id, 8.days.ago, commentable: articles.sample)
|
||||
# User 1 - week 1
|
||||
create_comment_time_ago(user1.id, 8.days.ago, commentable: articles.sample, flagged_by: mod)
|
||||
create_comment_time_ago(user1.id, 11.days.ago, commentable: articles.sample)
|
||||
|
||||
# User 2 - week 1
|
||||
create_comment_time_ago(user2.id, 4.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 6.days.ago, commentable: articles.sample)
|
||||
# User 1 - week 2
|
||||
create_comment_time_ago(user1.id, 15.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user1.id, 15.days.ago, commentable: articles.sample)
|
||||
|
||||
# User 2 - week 0
|
||||
create_comment_time_ago(user2.id, 1.day.ago, commentable: articles.sample)
|
||||
# User 2 - week 1
|
||||
create_comment_time_ago(user2.id, 9.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 13.days.ago, commentable: articles.sample, flagged_by: mod)
|
||||
# User 1 - week 3
|
||||
create_comment_time_ago(user2.id, 17.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 13.days.ago, commentable: articles.sample)
|
||||
# User 2 - week 2
|
||||
create_comment_time_ago(user2.id, 17.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 18.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 18.days.ago, commentable: articles.sample)
|
||||
# User 2 - week 3
|
||||
create_comment_time_ago(user2.id, 22.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 23.days.ago, commentable: articles.sample)
|
||||
create_comment_time_ago(user2.id, 23.days.ago, commentable: articles.sample, flagged_by: mod)
|
||||
end
|
||||
|
||||
it "matches the correct comment count for each week in result hash" do
|
||||
|
|
@ -112,16 +123,17 @@ RSpec.describe Comments::CommunityWellnessQuery, type: :query do
|
|||
# Result includes both users because they have > 1 comment per week
|
||||
expect(result_user_ids).to contain_exactly(user1.id, user2.id)
|
||||
|
||||
# user1 must have `1` in first week comment count because one of their 2
|
||||
# comments is flagged by a moderator
|
||||
# user1 must have `1` in first week (1) comment count because one out of
|
||||
# their two comments is flagged by a moderator
|
||||
index1 = result.index { |hash| hash["user_id"] == user1.id }
|
||||
expect(result[index1]["serialized_weeks_ago"]).to eq("1,2")
|
||||
expect(result[index1]["serialized_comment_counts"]).to eq("1,2")
|
||||
expect(result[index1]["serialized_weeks_ago"]).to eq("0,1,2")
|
||||
expect(result[index1]["serialized_comment_counts"]).to eq("2,1,2")
|
||||
|
||||
# Second
|
||||
# user1 must have `2` in third week (3) comment count because one out of
|
||||
# their three comments is flagged by a moderator
|
||||
index2 = result.index { |hash| hash["user_id"] == user2.id }
|
||||
expect(result[index2]["serialized_weeks_ago"]).to eq("1,2,3")
|
||||
expect(result[index2]["serialized_comment_counts"]).to eq("2,1,3")
|
||||
expect(result[index2]["serialized_weeks_ago"]).to eq("0,1,2,3")
|
||||
expect(result[index2]["serialized_comment_counts"]).to eq("1,2,3,2")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ RSpec.describe Badges::AwardCommunityWellness, type: :service do
|
|||
# Create 2 comments per-week to be tested, i.e. week 8 would create 2
|
||||
# comments on each of the 8 weeks (calculated on days_ago per week)
|
||||
reward_weeks[index].times do |week|
|
||||
days_ago = (5 + (week * 7)).days.ago
|
||||
days_ago = (8 + (week * 7)).days.ago
|
||||
create_comment_time_ago(users[index].id, days_ago, commentable: articles.sample)
|
||||
create_comment_time_ago(users[index].id, days_ago, commentable: articles.sample)
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue