Skip to content

Commit

Permalink
Add completed #12in23 badge (#6557)
Browse files Browse the repository at this point in the history
* Add completed #12in23 badge

* Make completed 12in23 badge legendary
  • Loading branch information
ErikSchierboom authored Nov 30, 2023
1 parent 9f09199 commit d4abc42
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 2 deletions.
2 changes: 1 addition & 1 deletion app/commands/solution/publish.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,6 @@ def update_num_published_solutions_on_exercise!
BADGES = %i[functional_february mechanical_march analytical_april
mind_shifting_may summer_of_sexps jurassic_july
apps_august slimline_september object_oriented_october
nibbly_november december_diversions].freeze
nibbly_november december_diversions completed_12_in_23].freeze
private_constant :BADGES
end
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ class User::Challenges::FeaturedExercisesProgress12In23
NOVEMBER_TRACKS = %w[x86-64-assembly mips wasm].freeze
NOVEMBER_EXERCISES = %w[pop-count grains resistor-color rotational-cipher nucleotide-count].freeze

DECEMBER_TRACKS = %w[cfml groovy lua vimscript wren].freeze
DECEMBER_EXERCISES = %w[all-your-base flatten-array queen-attack dnd-character run-length-encoding].freeze

def call
exercises = self.class.featured_exercises.filter_map do |exercise_slug, track_slugs|
next { slug: exercise_slug, earned_for: nil, track_slugs: } unless solutions.key?(exercise_slug)
Expand Down Expand Up @@ -66,7 +69,8 @@ def self.featured_exercises
AUGUST_EXERCISES.map { |e| [e, AUGUST_TRACKS] } +
SEPTEMBER_EXERCISES.map { |e| [e, SEPTEMBER_TRACKS] } +
OCTOBER_EXERCISES.map { |e| [e, OCTOBER_TRACKS] } +
NOVEMBER_EXERCISES.map { |e| [e, NOVEMBER_TRACKS] }
NOVEMBER_EXERCISES.map { |e| [e, NOVEMBER_TRACKS] } +
DECEMBER_EXERCISES.map { |e| [e, DECEMBER_TRACKS] }
).to_h
end

Expand Down
13 changes: 13 additions & 0 deletions app/images/icons/badge-completed-12-in-23.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions app/models/badges/completed_12_in_23_badge.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Badges
class Completed12In23Badge < Badge
seed "Completed #12in23 Challenge",
:legendary,
'badge-completed-12-in-23',
'Completed and published all featured exercises in the #12in23 challenge'

def award_to?(user)
return false unless participant?(user)

User::Challenges::FeaturedExercisesProgress12In23.(user).all? do |exercise_progress|
exercise_progress[:earned_for].present?
end
end

def send_email_on_acquisition? = true

def participant?(user) = user.challenges.where(challenge_id: User::Challenge::CHALLENGE_12_IN_23).exists?
end
end
36 changes: 36 additions & 0 deletions test/commands/solution/publish_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,42 @@ class Solution::PublishTest < ActiveSupport::TestCase
assert_includes user.reload.badges.map(&:class), Badges::DecemberDiversionsBadge
end

test "awards completed 12 in 23 badge when published all featured exercises" do
travel_to Time.utc(2023, 12, 25)

user = create :user
create :user_challenge, user:, challenge_id: '12in23'

User::Challenges::FeaturedExercisesProgress12In23.featured_exercises.values.flatten.uniq.each do |track_slug|
track = create(:track, slug: track_slug)
create(:user_track, user:, track:)
end

User::Challenges::FeaturedExercisesProgress12In23.featured_exercises.to_a[0..-2].each do |(exercise_slug, track_slugs)|
track = Track.for!(track_slugs.sample)
exercise = create(:practice_exercise, track:, slug: exercise_slug)
create(:practice_solution, :published, user:, track:, exercise:)
end

# Sanity check: don't award badge when not yet published all exercises
perform_enqueued_jobs
refute_includes user.reload.badges.map(&:class), Badges::Completed12In23Badge

exercise_slug, track_slugs = User::Challenges::FeaturedExercisesProgress12In23.featured_exercises.to_a.last
track = Track.for!(track_slugs.sample)
exercise = create(:practice_exercise, track:, slug: exercise_slug)
create(:practice_solution, :completed, user:, track:, exercise:)

perform_enqueued_jobs
refute_includes user.reload.badges.map(&:class), Badges::Completed12In23Badge

perform_enqueued_jobs do
Solution::Publish.(user.solutions.last, user.solutions.last.user_track, 1)
end

assert_includes user.reload.badges.map(&:class), Badges::Completed12In23Badge
end

test "solution snippet updated to published iteration's snippet when single iteration is published" do
solution = create :practice_solution, snippet: 'my snippet'
create :user_track, user: solution.user, track: solution.track
Expand Down
1 change: 1 addition & 0 deletions test/factories/badges.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
discourser chatterbox mind_shifting_may lifetime_insider insider
summer_of_sexps jurassic_july apps_august slimline_september
object_oriented_october nibbly_november december_diversions
completed_12_in_23
].each do |type|
factory "#{type}_badge", class: "Badges::#{type.to_s.camelize}Badge" do
end
Expand Down
48 changes: 48 additions & 0 deletions test/models/badges/completed_12_in_23_badge_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require "test_helper"

class Badge::Completed12In23BadgeTest < ActiveSupport::TestCase
test "attributes" do
badge = create :completed_12_in_23_badge
assert_equal "Completed #12in23 Challenge", badge.name
assert_equal :legendary, badge.rarity
assert_equal :'badge-completed-12-in-23', badge.icon # rubocop:disable Naming/VariableNumber
assert_equal 'Completed and published all featured exercises in the #12in23 challenge', badge.description
assert badge.send_email_on_acquisition?
assert_nil badge.notification_key
end

test "award_to?" do
user = create :user
badge = create :completed_12_in_23_badge
other_user = create :user

refute badge.award_to?(user.reload)

create :user_challenge, user:, challenge_id: '12in23'
refute badge.award_to?(user.reload)

User::Challenges::FeaturedExercisesProgress12In23.featured_exercises.values.flatten.uniq.each do |track_slug|
create(:track, slug: track_slug)
end

User::Challenges::FeaturedExercisesProgress12In23.featured_exercises.each do |exercise_slug, track_slugs|
track = Track.for!(track_slugs.sample)
exercise = create(:practice_exercise, track:, slug: exercise_slug)
create(:practice_solution, :published, user:, track:, exercise:,
published_at: Time.utc(2023, SecureRandom.rand(1..12), SecureRandom.rand(1..28)))
end

assert badge.award_to?(user.reload)

last_solution = user.solutions.last

# Sanity check: only published solutions count
last_solution.update(published_iteration_id: nil, published_at: nil)
refute badge.award_to?(user.reload)

# Sanity check: other user's solutions don't count
create(:practice_solution, :published, user: other_user, track: last_solution.track, exercise: last_solution.exercise,
published_at: Time.utc(2023, SecureRandom.rand(1..12), SecureRandom.rand(1..28)))
refute badge.award_to?(user.reload)
end
end

0 comments on commit d4abc42

Please sign in to comment.