From c2055732c79981d27f92c82f79d299c9c21415c6 Mon Sep 17 00:00:00 2001 From: Arpit Jalan Date: Thu, 26 Jun 2014 00:05:11 +0530 Subject: [PATCH] FEATURE: Add groups support to Bulk Invite --- app/jobs/regular/bulk_invite.rb | 74 +++++++++++++++++++++++++-------- spec/jobs/bulk_invite_spec.rb | 56 +++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 spec/jobs/bulk_invite_spec.rb diff --git a/app/jobs/regular/bulk_invite.rb b/app/jobs/regular/bulk_invite.rb index ed2ed63d138..316e824d4bb 100644 --- a/app/jobs/regular/bulk_invite.rb +++ b/app/jobs/regular/bulk_invite.rb @@ -22,26 +22,11 @@ module Jobs raise Discourse::InvalidParameters.new(:identifier) if identifier.blank? raise Discourse::InvalidParameters.new(:chunks) if chunks <= 0 - csv_path = "#{Invite.base_directory}/#{filename}" - tmp_csv_path = "#{csv_path}.tmp" - # path to tmp directory - tmp_directory = File.dirname(Invite.chunk_path(identifier, filename, 0)) - - # merge all chunks - HandleChunkUpload.merge_chunks(chunks, upload_path: csv_path, tmp_upload_path: tmp_csv_path, model: Invite, identifier: identifier, filename: filename, tmp_directory: tmp_directory) + # merge chunks, and get csv path + csv_path = get_csv_path(filename, identifier, chunks) # read csv file, and send out invitations - CSV.foreach(csv_path) do |csv_info| - if !csv_info[0].nil? - if validate_email(csv_info[0]) - Invite.invite_by_email(csv_info[0], current_user, topic=nil) - @sent += 1 - else - log "Invalid email '#{csv_info[0]}' at line number '#{$INPUT_LINE_NUMBER}'" - @failed += 1 - end - end - end + read_csv_file(csv_path, current_user) # send notification to user regarding progress notify_user(current_user) @@ -50,10 +35,63 @@ module Jobs FileUtils.rm_rf(csv_path) rescue nil end + def get_csv_path(filename, identifier, chunks) + csv_path = "#{Invite.base_directory}/#{filename}" + tmp_csv_path = "#{csv_path}.tmp" + # path to tmp directory + tmp_directory = File.dirname(Invite.chunk_path(identifier, filename, 0)) + # merge all chunks + HandleChunkUpload.merge_chunks(chunks, upload_path: csv_path, tmp_upload_path: tmp_csv_path, model: Invite, identifier: identifier, filename: filename, tmp_directory: tmp_directory) + + return csv_path + end + + def read_csv_file(csv_path, current_user) + CSV.foreach(csv_path) do |csv_info| + if !csv_info[0].nil? + if validate_email(csv_info[0]) + # email is valid, now check for groups + if !csv_info[1].nil? + # group(s) present + send_invite_with_groups(csv_info[0], csv_info[1], current_user, $INPUT_LINE_NUMBER) + else + # no group present + send_invite_without_group(csv_info[0], current_user) + end + @sent += 1 + else + # invalid email + log "Invalid email '#{csv_info[0]}' at line number '#{$INPUT_LINE_NUMBER}'" + @failed += 1 + end + end + end + end + def validate_email(email) /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/.match(email) end + def send_invite_with_groups(email, group_names, current_user, csv_line_number) + group_ids = [] + group_names = group_names.split(';') + group_names.each { |group_name| + group_detail = Group.find_by_name(group_name) + if !group_detail.nil? + # valid group + group_ids.push(group_detail.id) + else + # invalid group + log "Invalid group '#{group_name}' at line number '#{csv_line_number}'" + end + } + Invite.invite_by_email(email, current_user, topic=nil, group_ids) + end + + def send_invite_without_group(email, current_user) + Invite.invite_by_email(email, current_user, topic=nil) + end + def log(message) puts(message) rescue nil save_log(message) diff --git a/spec/jobs/bulk_invite_spec.rb b/spec/jobs/bulk_invite_spec.rb new file mode 100644 index 00000000000..89eae26c425 --- /dev/null +++ b/spec/jobs/bulk_invite_spec.rb @@ -0,0 +1,56 @@ +require 'spec_helper' + +describe Jobs::BulkInvite do + + context '.execute' do + + it 'raises an error when the filename is missing' do + lambda { Jobs::BulkInvite.new.execute(identifier: '46-discoursecsv', chunks: '1') }.should raise_error(Discourse::InvalidParameters) + end + + it 'raises an error when the identifier is missing' do + lambda { Jobs::BulkInvite.new.execute(filename: 'discourse.csv', chunks: '1') }.should raise_error(Discourse::InvalidParameters) + end + + it 'raises an error when the chunks is missing' do + lambda { Jobs::BulkInvite.new.execute(filename: 'discourse.csv', identifier: '46-discoursecsv') }.should raise_error(Discourse::InvalidParameters) + end + + context '.read_csv_file' do + let(:bulk_invite) { Jobs::BulkInvite.new } + let(:csv_file) { File.new("#{Rails.root}/spec/fixtures/csv/discourse.csv") } + let(:user) { Fabricate(:user) } + + it 'reads csv file' do + bulk_invite.read_csv_file(csv_file, user) + end + end + + context '.send_invite_with_groups' do + let(:bulk_invite) { Jobs::BulkInvite.new } + let(:user) { Fabricate(:user) } + let(:group) { Fabricate(:group) } + let(:email) { "evil@trout.com" } + + it 'creates an invite to the group' do + bulk_invite.send_invite_with_groups(email, group.name, user, 1) + invite = Invite.where(email: email).first + invite.should be_present + InvitedGroup.where(invite_id: invite.id, group_id: group.id).exists?.should be_true + end + end + + context '.send_invite_without_group' do + let(:bulk_invite) { Jobs::BulkInvite.new } + let(:user) { Fabricate(:user) } + let(:email) { "evil@trout.com" } + + it 'creates an invite' do + bulk_invite.send_invite_without_group(email, user) + Invite.where(email: email).exists?.should be_true + end + end + + end + +end