FEATURE: Support uploading a csv with either user emails or usernames (#8971)
This commit is contained in:
parent
be3e4ab3f5
commit
9441362c72
|
@ -51,6 +51,9 @@ class Admin::BadgesController < Admin::AdminController
|
||||||
batch = []
|
batch = []
|
||||||
|
|
||||||
File.open(csv_file) do |csv|
|
File.open(csv_file) do |csv|
|
||||||
|
mode = Email.is_valid?(CSV.parse_line(csv.first).first) ? 'email' : 'username'
|
||||||
|
csv.rewind
|
||||||
|
|
||||||
csv.each_line do |email_line|
|
csv.each_line do |email_line|
|
||||||
batch.concat CSV.parse_line(email_line)
|
batch.concat CSV.parse_line(email_line)
|
||||||
line_number += 1
|
line_number += 1
|
||||||
|
@ -60,7 +63,7 @@ class Admin::BadgesController < Admin::AdminController
|
||||||
last_batch_item = full_batch || csv.eof?
|
last_batch_item = full_batch || csv.eof?
|
||||||
|
|
||||||
if last_batch_item
|
if last_batch_item
|
||||||
Jobs.enqueue(:mass_award_badge, user_emails: batch, badge_id: badge.id)
|
Jobs.enqueue(:mass_award_badge, users_batch: batch, badge_id: badge.id, mode: mode)
|
||||||
batch = []
|
batch = []
|
||||||
batch_number += 1
|
batch_number += 1
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,8 +3,16 @@
|
||||||
module Jobs
|
module Jobs
|
||||||
class MassAwardBadge < ::Jobs::Base
|
class MassAwardBadge < ::Jobs::Base
|
||||||
def execute(args)
|
def execute(args)
|
||||||
|
return unless mode = args[:mode]
|
||||||
badge = Badge.find_by(id: args[:badge_id])
|
badge = Badge.find_by(id: args[:badge_id])
|
||||||
users = User.select(:id, :username, :locale).with_email(args[:user_emails])
|
|
||||||
|
users = User.select(:id, :username, :locale)
|
||||||
|
|
||||||
|
if mode == 'email'
|
||||||
|
users = users.with_email(args[:users_batch])
|
||||||
|
else
|
||||||
|
users = users.where(username_lower: args[:users_batch].map!(&:downcase))
|
||||||
|
end
|
||||||
|
|
||||||
return if users.empty? || badge.nil?
|
return if users.empty? || badge.nil?
|
||||||
|
|
||||||
|
|
|
@ -4502,8 +4502,8 @@ en:
|
||||||
description: Award the same badge to many users at once.
|
description: Award the same badge to many users at once.
|
||||||
no_badge_selected: Please select a badge to get started.
|
no_badge_selected: Please select a badge to get started.
|
||||||
perform: "Award Badge to Users"
|
perform: "Award Badge to Users"
|
||||||
upload_csv: Upload a CSV with user emails
|
upload_csv: Upload a CSV with either user emails or usernames
|
||||||
aborted: Please upload a CSV containing user emails
|
aborted: Please upload a CSV containing either user emails or usernames
|
||||||
success: Your CSV was received and users will receive their badge shortly.
|
success: Your CSV was received and users will receive their badge shortly.
|
||||||
replace_owners: Remove the badge from previous owners
|
replace_owners: Remove the badge from previous owners
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
username1
|
||||||
|
username2
|
||||||
|
username3
|
|
|
@ -6,9 +6,10 @@ describe Jobs::MassAwardBadge do
|
||||||
describe '#execute' do
|
describe '#execute' do
|
||||||
fab!(:badge) { Fabricate(:badge) }
|
fab!(:badge) { Fabricate(:badge) }
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
let(:email_mode) { 'email' }
|
||||||
|
|
||||||
it 'creates the badge for an existing user' do
|
it 'creates the badge for an existing user' do
|
||||||
subject.execute(user_emails: [user.email], badge_id: badge.id)
|
execute_job([user.email])
|
||||||
|
|
||||||
expect(UserBadge.where(user: user, badge: badge).exists?).to eq(true)
|
expect(UserBadge.where(user: user, badge: badge).exists?).to eq(true)
|
||||||
end
|
end
|
||||||
|
@ -16,14 +17,14 @@ describe Jobs::MassAwardBadge do
|
||||||
it 'works with multiple users' do
|
it 'works with multiple users' do
|
||||||
user_2 = Fabricate(:user)
|
user_2 = Fabricate(:user)
|
||||||
|
|
||||||
subject.execute(user_emails: [user.email, user_2.email], badge_id: badge.id)
|
execute_job([user.email, user_2.email])
|
||||||
|
|
||||||
expect(UserBadge.exists?(user: user, badge: badge)).to eq(true)
|
expect(UserBadge.exists?(user: user, badge: badge)).to eq(true)
|
||||||
expect(UserBadge.exists?(user: user_2, badge: badge)).to eq(true)
|
expect(UserBadge.exists?(user: user_2, badge: badge)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'also creates a notification for the user' do
|
it 'also creates a notification for the user' do
|
||||||
subject.execute(user_emails: [user.email], badge_id: badge.id)
|
execute_job([user.email])
|
||||||
|
|
||||||
expect(Notification.exists?(user: user)).to eq(true)
|
expect(Notification.exists?(user: user)).to eq(true)
|
||||||
expect(UserBadge.where.not(notification_id: nil).exists?(user: user, badge: badge)).to eq(true)
|
expect(UserBadge.where.not(notification_id: nil).exists?(user: user, badge: badge)).to eq(true)
|
||||||
|
@ -34,10 +35,14 @@ describe Jobs::MassAwardBadge do
|
||||||
|
|
||||||
UserBadge.create!(badge_id: Badge::Member, user: user, granted_by: Discourse.system_user, granted_at: Time.now)
|
UserBadge.create!(badge_id: Badge::Member, user: user, granted_by: Discourse.system_user, granted_at: Time.now)
|
||||||
|
|
||||||
subject.execute(user_emails: [user.email, user_2.email], badge_id: badge.id)
|
execute_job([user.email, user_2.email])
|
||||||
|
|
||||||
expect(UserBadge.find_by(user: user, badge: badge).featured_rank).to eq(2)
|
expect(UserBadge.find_by(user: user, badge: badge).featured_rank).to eq(2)
|
||||||
expect(UserBadge.find_by(user: user_2, badge: badge).featured_rank).to eq(1)
|
expect(UserBadge.find_by(user: user_2, badge: badge).featured_rank).to eq(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def execute_job(emails)
|
||||||
|
subject.execute(users_batch: emails, badge_id: badge.id, mode: 'email')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -199,7 +199,7 @@ describe Admin::BadgesController do
|
||||||
expect(response.status).to eq(400)
|
expect(response.status).to eq(400)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates the badge for an existing user' do
|
it 'awards the badge using a list of user emails' do
|
||||||
Jobs.run_immediately!
|
Jobs.run_immediately!
|
||||||
|
|
||||||
user = Fabricate(:user, email: 'user1@test.com')
|
user = Fabricate(:user, email: 'user1@test.com')
|
||||||
|
@ -209,6 +209,17 @@ describe Admin::BadgesController do
|
||||||
|
|
||||||
expect(UserBadge.exists?(user: user, badge: badge)).to eq(true)
|
expect(UserBadge.exists?(user: user, badge: badge)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'awards the badge using a list of usernames' do
|
||||||
|
Jobs.run_immediately!
|
||||||
|
|
||||||
|
user = Fabricate(:user, username: 'username1')
|
||||||
|
file = file_from_fixtures('usernames.csv', 'csv')
|
||||||
|
|
||||||
|
post "/admin/badges/award/#{badge.id}.json", params: { file: fixture_file_upload(file) }
|
||||||
|
|
||||||
|
expect(UserBadge.exists?(user: user, badge: badge)).to eq(true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue