Configure badge credits by admins (#13145)

* Added credits_awarded to /admin/badges forms

* Award credits only if badge has them

* Removed information about credits and listings in the new badge email when not needed

* Specs for number of credits awarded for badges

* Added missing newline

* Fix typo

Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>

* Improve new_badge_email.text.erb

Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>

* Fixed number of credits in notification

* Added specs for number of credits in notifications

Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>
This commit is contained in:
Anna Buianova 2021-03-30 10:58:48 +03:00 committed by GitHub
parent 624c671fa4
commit 40b989ca62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 133 additions and 33 deletions

View file

@ -41,7 +41,7 @@ module Admin
private
def badge_params
params.require(:badge).permit(:title, :slug, :description, :badge_image)
params.require(:badge).permit(:title, :slug, :description, :badge_image, :credits_awarded)
end
end
end

View file

@ -48,6 +48,8 @@ class BadgeAchievement < ApplicationRecord
end
def award_credits
Credit.add_to(user, 5)
return if badge.credits_awarded.zero?
Credit.add_to(user, badge.credits_awarded)
end
end

View file

@ -35,7 +35,8 @@ module Notifications
badge: {
title: badge_achievement.badge.title,
description: badge_achievement.badge.description,
badge_image_url: badge_achievement.badge.badge_image_url
badge_image_url: badge_achievement.badge.badge_image_url,
credits_awarded: badge_achievement.badge.credits_awarded
}
}
}

View file

@ -30,6 +30,11 @@
<% end %>
<%= form.file_field :badge_image, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :credits_awarded, "Credits awarded:" %>
<%= form.text_field :credits_awarded, class: "form-control" %>
</div>
<%= submit_tag "Update Badge", class: "btn btn-primary" %>
<% end %>
</div>

View file

@ -21,6 +21,11 @@
<%= form.label :badge_image, "Badge Image:" %>
<%= form.file_field :badge_image, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :credits_awarded, "Credits awarded:" %>
<%= form.text_field :credits_awarded, class: "form-control" %>
</div>
<%= submit_tag "Create Badge", class: "btn btn-primary" %>
<% end %>
</div>

View file

@ -25,12 +25,15 @@
Check out your profile
</a>
</p>
<hr style="opacity:0.4;width: 150px;margin: 30px auto;" />
<p>
You also get <strong><a href="<%= credits_url %>">5 new credits</a></strong> to use for <strong><a href="<%= listings_url %>">community listings</a></strong><br />
if you have anything you'd like to promote. 🎉
</p>
<p>
<strong><a href="<%= app_url(about_listings_url) %>">More information about listings<a></strong>
</p>
<% unless @badge.credits_awarded.zero? %>
<hr style="opacity:0.4;width: 150px;margin: 30px auto;" />
<p>
You also get <strong><a href="<%= credits_url %>"><%= @badge.credits_awarded %> new credits</a></strong> to use for <strong><a href="<%= listings_url %>">community listings</a></strong><br />
if you have anything you'd like to promote. 🎉
</p>
<p>
<strong><a href="<%= app_url(about_listings_url) %>">More information about listings<a></strong>
</p>
<% end %>
</center>

View file

@ -6,8 +6,10 @@ Congratulations, <%= @user.name %>! You got the <%= @badge.title %> badge! Be su
<%= user_url(@user) %>
You also get 5 new credits to use for community listings if you have anything you'd like to promote: <%= listings_url %>
<% unless @badge.credits_awarded.zero? %>
You also get <%= @badge.credits_awarded %> new credits to use for community listings if you have anything you'd like to promote: <%= listings_url %>
To manage your credits: visit: <%= credits_url %>
To manage your credits visit: <%= credits_url %>
For more information about listings, visit: <%= app_url(about_listings_url) %>
For more information about listings, visit: <%= app_url(about_listings_url) %>
<% end %>

View file

@ -9,10 +9,12 @@
<div class="crayons-card crayons-card--secondary p-4 w-100 grid gap-2">
<img class="w-100 max-w-50 l:max-w-25 h-auto inline-block mx-auto" src="<%= optimized_image_url(json_data["badge_achievement"]["badge"]["badge_image_url"], width: 250) %>" alt="<%= json_data["badge_achievement"]["badge"]["title"] %>">
<p class="color-base-70"><em><%= json_data["badge_achievement"]["rewarding_context_message"].html_safe %></em></p>
<p class="color-base-70"><em><%= json_data["badge_achievement"]["rewarding_context_message"].to_s.html_safe %></em></p>
</div>
<p class="self-stretch"><a href="<%= json_data["user"]["path"] %>" class="crayons-btn w-100 m:w-50">Visit your profile</a></p>
<p class="max-w-75 mx-auto">You also get <a href="/credits" class="crayons-link crayons-link--brand fw-bold">5 new credits</a> to use for <a href="/listings">community listings</a> if you have anything you'd like to promote. 🎉</p>
<p class="fs-s"><a href="<%= about_listings_url %>" class="crayons-link crayons-link--secondary">More information about listings<a></p>
<% unless json_data["badge_achievement"]["badge"]["credits_awarded"].zero? %>
<p class="max-w-75 mx-auto">You also get <a href="/credits" class="crayons-link crayons-link--brand fw-bold"><%= json_data["badge_achievement"]["badge"]["credits_awarded"] %> new credits</a> to use for <a href="/listings">community listings</a> if you have anything you'd like to promote. 🎉</p>
<p class="fs-s"><a href="<%= about_listings_url %>" class="crayons-link crayons-link--secondary">More information about listings<a></p>
<% end %>
</div>

View file

@ -155,6 +155,10 @@ RSpec.describe NotifyMailer, type: :mailer do
let(:badge_achievement) { create_badge_achievement(user, badge, user2) }
let(:email) { described_class.with(badge_achievement: badge_achievement).new_badge_email }
let(:badge_with_credits) { create(:badge, credits_awarded: 7) }
let(:badge_achievement_with_credits) { create_badge_achievement(user, badge_with_credits, user2) }
let(:email_with_credits) { described_class.with(badge_achievement: badge_achievement_with_credits).new_badge_email }
def create_badge_achievement(user, badge, rewarder)
BadgeAchievement.create(
user: user,
@ -178,7 +182,47 @@ RSpec.describe NotifyMailer, type: :mailer do
expect(email.to).to eq([user.email])
end
context "when rendering the HTML email" do
context "when rendering the HTML email for badge with credits" do
it "includes the listings URL" do
expect(email_with_credits.html_part.body).to include(
CGI.escape(
Rails.application.routes.url_helpers.listings_url(host: SiteConfig.app_domain),
),
)
end
it "includes the about listings URL" do
expect(email_with_credits.html_part.body).to include(
CGI.escape(Rails.application.routes.url_helpers.about_listings_url(host: SiteConfig.app_domain)),
)
end
it "includes number of credits" do
expect(email_with_credits.html_part.body).to include("7 new credits")
end
end
context "when rendering the text email for badge with credits" do
it "includes the listings URL" do
expect(email_with_credits.text_part.body).not_to include(
CGI.escape(
Rails.application.routes.url_helpers.listings_url(host: SiteConfig.app_domain),
),
)
end
it "includes the about listings URL" do
expect(email_with_credits.text_part.body).not_to include(
CGI.escape(Rails.application.routes.url_helpers.about_listings_url(host: SiteConfig.app_domain)),
)
end
it "includes number of credits" do
expect(email_with_credits.text_part.body).to include("7 new credits")
end
end
context "when rendering the HTML email for badge w/o credits" do
it "includes the tracking pixel" do
expect(email.html_part.body).to include("open.gif")
end
@ -193,16 +237,16 @@ RSpec.describe NotifyMailer, type: :mailer do
expect(email.html_part.body).to include(CGI.escape(URL.user(user)))
end
it "includes the listings URL" do
expect(email.html_part.body).to include(
it "doesn't include the listings URL" do
expect(email.html_part.body).not_to include(
CGI.escape(
Rails.application.routes.url_helpers.listings_url(host: SiteConfig.app_domain),
),
)
end
it "includes the about listings URL" do
expect(email.html_part.body).to include(
it "doesn't include the about listings URL" do
expect(email.html_part.body).not_to include(
CGI.escape(Rails.application.routes.url_helpers.about_listings_url(host: SiteConfig.app_domain)),
)
end
@ -232,14 +276,14 @@ RSpec.describe NotifyMailer, type: :mailer do
expect(email.text_part.body).to include(URL.user(user))
end
it "includes the listings URL" do
expect(email.text_part.body).to include(
it "doesn't include the listings URL" do
expect(email.text_part.body).not_to include(
Rails.application.routes.url_helpers.listings_url(host: SiteConfig.app_domain),
)
end
it "includes the about listings URL" do
expect(email.text_part.body).to include(
it "doesn't include the about listings URL" do
expect(email.text_part.body).not_to include(
Rails.application.routes.url_helpers.about_listings_url(host: SiteConfig.app_domain),
)
end

View file

@ -1,7 +1,10 @@
require "rails_helper"
RSpec.describe BadgeAchievement, type: :model do
let(:achievement) { create(:badge_achievement) }
let(:badge_with_credits) { create(:badge, credits_awarded: 10) }
let(:badge) { create(:badge, credits_awarded: 0) }
let(:achievement) { create(:badge_achievement, badge: badge) }
let(:credits_achievement) { create(:badge_achievement, badge: badge_with_credits) }
describe "validations" do
describe "builtin validations" do
@ -18,8 +21,12 @@ RSpec.describe BadgeAchievement, type: :model do
expect(achievement.rewarding_context_message).to include("</a>")
end
it "awards credits after create" do
expect(achievement.user.credits.size).to eq(5)
it "doesn't award credits if credits_awarded is zero" do
expect(achievement.user.credits.size).to eq(0)
end
it "awards credits after create if credits_awarded exist" do
expect(credits_achievement.user.credits.size).to eq(10)
end
it "notifies recipients after commit" do

View file

@ -10,6 +10,7 @@ RSpec.describe "/admin/badges", type: :request do
title: "Hello, world!",
slug: "greeting-badge",
description: "Awarded to welcoming users",
credits_awarded: 10,
badge_image: Rack::Test::UploadedFile.new("spec/support/fixtures/images/image1.jpeg", "image/jpeg")
}
}
@ -39,5 +40,11 @@ RSpec.describe "/admin/badges", type: :request do
patch "/admin/badges/#{badge.id}", params: params
end.to change { badge.reload.title }.to("Hello, world!")
end
it "successfully updates badge's credits_awarded" do
expect do
patch "/admin/badges/#{badge.id}", params: params
end.to change { badge.reload.credits_awarded }.to(10)
end
end
end

View file

@ -590,10 +590,10 @@ RSpec.describe "NotificationsIndex", type: :request do
end
end
context "when a user has a new badge notification" do
context "when a user has a new badge notification w/o credits" do
before do
sign_in user
badge = create(:badge)
badge = create(:badge, credits_awarded: 0)
badge_achievement = create(:badge_achievement, user: user, badge: badge)
sidekiq_perform_enqueued_jobs do
Notification.send_new_badge_achievement_notification(badge_achievement)
@ -623,6 +623,26 @@ RSpec.describe "NotificationsIndex", type: :request do
def renders_visit_profile_button
expect(response.body).to include "Visit your profile"
end
it "has no information about credits" do
expect(response.body).not_to include "new credits"
end
end
context "when a user has a new badge notification with credits" do
before do
sign_in user
badge = create(:badge, credits_awarded: 11)
badge_achievement = create(:badge_achievement, user: user, badge: badge)
sidekiq_perform_enqueued_jobs do
Notification.send_new_badge_achievement_notification(badge_achievement)
end
get "/notifications"
end
it "renders information about credits" do
expect(response.body).to include "11 new credits"
end
end
context "when a user has a new mention notification" do

View file

@ -1,7 +1,8 @@
require "rails_helper"
RSpec.describe Notifications::NewBadgeAchievement::Send, type: :service do
let(:badge_achievement) { create(:badge_achievement) }
let(:badge) { create(:badge, credits_awarded: 7) }
let(:badge_achievement) { create(:badge_achievement, badge: badge) }
let(:blank_badge_achievement) { create(:badge_achievement, rewarding_context_message: nil) }
def expected_json_data(badge_achievement)
@ -13,7 +14,8 @@ RSpec.describe Notifications::NewBadgeAchievement::Send, type: :service do
badge: {
title: badge_achievement.badge.title,
description: badge_achievement.badge.description,
badge_image_url: badge_achievement.badge.badge_image_url
badge_image_url: badge_achievement.badge.badge_image_url,
credits_awarded: badge_achievement.badge.credits_awarded
}
}
}.to_json