From 78fd99fc40ea162d71189cd125055c3d781ccf3b Mon Sep 17 00:00:00 2001 From: Arpit Jalan Date: Tue, 7 Oct 2014 00:18:56 +0530 Subject: [PATCH] Feature: resend invites --- .../discourse/controllers/user-invited.js.es6 | 11 ++++++ .../javascripts/discourse/models/invite.js | 10 ++++-- .../discourse/templates/user/invited.hbs | 7 ++++ app/controllers/invites_controller.rb | 12 ++++++- app/models/invite.rb | 6 +++- config/locales/client.en.yml | 2 ++ config/routes.rb | 1 + spec/controllers/invites_controller_spec.rb | 34 +++++++++++++++++++ 8 files changed, 79 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/user-invited.js.es6 b/app/assets/javascripts/discourse/controllers/user-invited.js.es6 index a37e929e7ac..3274963eac1 100644 --- a/app/assets/javascripts/discourse/controllers/user-invited.js.es6 +++ b/app/assets/javascripts/discourse/controllers/user-invited.js.es6 @@ -72,6 +72,17 @@ export default Ember.ObjectController.extend({ return false; }, + /** + Resend a given invite + + @method reinvite + @param {Discourse.Invite} invite the invite to resend. + **/ + reinvite: function(invite) { + invite.reinvite(); + return false; + }, + loadMore: function() { var self = this; var model = self.get('model'); diff --git a/app/assets/javascripts/discourse/models/invite.js b/app/assets/javascripts/discourse/models/invite.js index 3ed3ae5ab3d..f90f3871661 100644 --- a/app/assets/javascripts/discourse/models/invite.js +++ b/app/assets/javascripts/discourse/models/invite.js @@ -15,6 +15,14 @@ Discourse.Invite = Discourse.Model.extend({ data: { email: this.get('email') } }); this.set('rescinded', true); + }, + + reinvite: function() { + Discourse.ajax('/invites/reinvite', { + type: 'POST', + data: { email: this.get('email') } + }); + this.set('reinvited', true); } }); @@ -46,5 +54,3 @@ Discourse.Invite.reopenClass({ } }); - - diff --git a/app/assets/javascripts/discourse/templates/user/invited.hbs b/app/assets/javascripts/discourse/templates/user/invited.hbs index a3a12dd91c4..6432bad3f40 100644 --- a/app/assets/javascripts/discourse/templates/user/invited.hbs +++ b/app/assets/javascripts/discourse/templates/user/invited.hbs @@ -51,12 +51,19 @@ {{#if invite.expired}} {{i18n user.invited.expired}} +      {{/if}} {{#if invite.rescinded}} {{i18n user.invited.rescinded}} {{else}} {{/if}} +      + {{#if invite.reinvited}} + {{i18n user.invited.reinvited}} + {{else}} + + {{/if}} {{/if}} diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 433226504cb..3958a7db85c 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -3,7 +3,7 @@ class InvitesController < ApplicationController skip_before_filter :check_xhr skip_before_filter :redirect_to_login_if_required - before_filter :ensure_logged_in, only: [:destroy, :create, :check_csv_chunk, :upload_csv_chunk] + before_filter :ensure_logged_in, only: [:destroy, :create, :resend_invite, :check_csv_chunk, :upload_csv_chunk] before_filter :ensure_new_registrations_allowed, only: [:show, :redeem_disposable_invite] def show @@ -96,6 +96,16 @@ class InvitesController < ApplicationController render nothing: true end + def resend_invite + params.require(:email) + + invite = Invite.find_by(invited_by_id: current_user.id, email: params[:email]) + raise Discourse::InvalidParameters.new(:email) if invite.blank? + invite.resend_invite + + render nothing: true + end + def check_csv_chunk guardian.ensure_can_bulk_invite_to_forum!(current_user) diff --git a/app/models/invite.rb b/app/models/invite.rb index f55f3468757..1fdc17453a0 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -95,7 +95,6 @@ class Invite < ActiveRecord::Base invite end - # generate invite tokens without email def self.generate_disposable_tokens(invited_by, quantity=nil, group_names=nil) invite_tokens = [] @@ -179,6 +178,11 @@ class Invite < ActiveRecord::Base user end + def resend_invite + self.update_columns(created_at: Time.zone.now, updated_at: Time.zone.now) + Jobs.enqueue(:invite_email, invite_id: self.id) + end + def self.base_directory File.join(Rails.root, "public", "csv", RailsMultisite::ConnectionManagement.current_db) end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 754421fa984..acc5cc2524c 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -474,6 +474,8 @@ en: expired: "This invite has expired." rescind: "Remove" rescinded: "Invite removed" + reinvite: "Resend Invite" + reinvited: "Invite re-sent" time_read: "Read Time" days_visited: "Days Visited" account_age_days: "Account age in days" diff --git a/config/routes.rb b/config/routes.rb index 8d9c0a6abf0..8da9d9b2ef7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -413,6 +413,7 @@ Discourse::Application.routes.draw do post "upload" => "invites#upload_csv_chunk" end end + post "invites/reinvite" => "invites#resend_invite" post "invites/disposable" => "invites#create_disposable_invite" get "invites/redeem/:token" => "invites#redeem_disposable_invite" delete "invites" => "invites#destroy" diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index 67bebae12b4..980dadea28a 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -280,6 +280,40 @@ describe InvitesController do end + context '.resend_invite' do + + it 'requires you to be logged in' do + lambda { + delete :resend_invite, email: 'first_name@example.com' + }.should raise_error(Discourse::NotLoggedIn) + end + + context 'while logged in' do + let!(:user) { log_in } + let!(:invite) { Fabricate(:invite, invited_by: user) } + let(:another_invite) { Fabricate(:invite, email: 'last_name@example.com') } + + it 'raises an error when the email is missing' do + lambda { post :resend_invite }.should raise_error(ActionController::ParameterMissing) + end + + it "raises an error when the email cannot be found" do + lambda { post :resend_invite, email: 'first_name@example.com' }.should raise_error(Discourse::InvalidParameters) + end + + it 'raises an error when the invite is not yours' do + lambda { post :resend_invite, email: another_invite.email }.should raise_error(Discourse::InvalidParameters) + end + + it "resends the invite" do + Invite.any_instance.expects(:resend_invite) + post :resend_invite, email: invite.email + end + + end + + end + context '.check_csv_chunk' do it 'requires you to be logged in' do lambda {