diff --git a/app/controllers/invitations_controller.rb b/app/controllers/invitations_controller.rb index b7f8f9882..66653e83e 100644 --- a/app/controllers/invitations_controller.rb +++ b/app/controllers/invitations_controller.rb @@ -4,6 +4,7 @@ class InvitationsController < ApplicationController before_action :authenticate_user! + before_action :check_invitations_available!, only: :create def new @invite_code = current_user.invitation_code @@ -46,6 +47,17 @@ class InvitationsController < ApplicationController private + def check_invitations_available! + return true if AppConfig.settings.enable_registrations? || current_user.invitation_code.can_be_used? + + flash[:error] = if AppConfig.settings.invitations.open? + t("invitations.create.no_more") + else + t("invitations.create.closed") + end + redirect_to :back + end + def valid_email?(email) User.email_regexp.match(email).present? end diff --git a/app/models/invitation_code.rb b/app/models/invitation_code.rb index 10bf5c8d3..7b732359d 100644 --- a/app/models/invitation_code.rb +++ b/app/models/invitation_code.rb @@ -12,7 +12,7 @@ class InvitationCode < ActiveRecord::Base end def can_be_used? - self.count > 0 + count > 0 && AppConfig.settings.invitations.open? end def add_invites! diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index bdac8f67d..117005596 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -560,6 +560,7 @@ en: no_more: "You have no more invitations." empty: "Please enter at least one email address." note_already_sent: "Invitations have already been sent to: %{emails}" + closed: "Invitations are closed on this diaspora* pod." new: language: "Language" invite_someone_to_join: "Invite someone to join diaspora*!" diff --git a/spec/controllers/invitations_controller_spec.rb b/spec/controllers/invitations_controller_spec.rb index 086c90991..00e6b2e8c 100644 --- a/spec/controllers/invitations_controller_spec.rb +++ b/spec/controllers/invitations_controller_spec.rb @@ -2,131 +2,142 @@ # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. -require 'spec_helper' - -describe InvitationsController, :type => :controller do - - before do - AppConfig.settings.invitations.open = true - @user = alice - @invite = {'email_inviter' => {'message' => "test", 'emails' => "abc@example.com"}} - end +require "spec_helper" +describe InvitationsController, type: :controller do describe "#create" do + let(:referer) { "http://test.host/cats/foo" } + let(:invite_params) { {email_inviter: {emails: "abc@example.com"}} } + before do - sign_in @user, scope: :user - allow(@controller).to receive(:current_user).and_return(@user) - @referer = 'http://test.host/cats/foo' - request.env["HTTP_REFERER"] = @referer + sign_in alice, scope: :user + request.env["HTTP_REFERER"] = referer end context "no emails" do - before do - @invite = {'email_inviter' => {'message' => "test", 'emails' => ""}} - end + let(:invite_params) { {email_inviter: {emails: ""}} } - it 'does not create an EmailInviter' do + it "does not create an EmailInviter" do expect(Workers::Mail::InviteEmail).not_to receive(:perform_async) - post :create, @invite + post :create, invite_params end - it 'returns to the previous page' do - post :create, @invite - expect(response).to redirect_to @referer + it "returns to the previous page" do + post :create, invite_params + expect(response).to redirect_to referer end - it 'flashes an error' do - post :create, @invite + it "flashes an error" do + post :create, invite_params expect(flash[:error]).to eq(I18n.t("invitations.create.empty")) end end - context 'only valid emails' do - before do - @emails = 'mbs@gmail.com' - @invite = {'email_inviter' => {'message' => "test", 'emails' => @emails}} + context "only valid emails" do + let(:emails) { "mbs@gmail.com" } + let(:invite_params) { {email_inviter: {emails: emails}} } + + it "creates an InviteEmail worker" do + expect(Workers::Mail::InviteEmail).to receive(:perform_async).with( + emails, alice.id, invite_params[:email_inviter] + ) + post :create, invite_params end - it 'creates an InviteEmail worker' do - inviter = double(:emails => [@emails], :send! => true) - expect(Workers::Mail::InviteEmail).to receive(:perform_async).with(@invite['email_inviter']['emails'], @user.id, @invite['email_inviter']) - post :create, @invite + it "returns to the previous page on success" do + post :create, invite_params + expect(response).to redirect_to referer end - it 'returns to the previous page on success' do - post :create, @invite - expect(response).to redirect_to @referer - end - - it 'flashes a notice' do - post :create, @invite - expected = I18n.t('invitations.create.sent', :emails => @emails.split(',').join(', ')) + it "flashes a notice" do + post :create, invite_params + expected = I18n.t("invitations.create.sent", emails: emails) expect(flash[:notice]).to eq(expected) end end - context 'only invalid emails' do - before do - @emails = 'invalid_email' - @invite = {'email_inviter' => {'message' => "test", 'emails' => @emails}} - end + context "only invalid emails" do + let(:emails) { "invalid_email" } + let(:invite_params) { {email_inviter: {emails: emails}} } - it 'does not create an InviteEmail worker' do + it "does not create an InviteEmail worker" do expect(Workers::Mail::InviteEmail).not_to receive(:perform_async) - post :create, @invite + post :create, invite_params end - it 'returns to the previous page' do - post :create, @invite - expect(response).to redirect_to @referer + it "returns to the previous page" do + post :create, invite_params + expect(response).to redirect_to referer end it "flashes an error" do - post :create, @invite + post :create, invite_params - expected = I18n.t("invitations.create.rejected", emails: @emails.split(",").join(", ")) + expected = I18n.t("invitations.create.rejected", emails: emails) expect(flash[:error]).to eq(expected) end end - context 'mixed valid and invalid emails' do - before do - @valid_emails = 'foo@bar.com,mbs@gmail.com' - @invalid_emails = 'invalid' - @invite = {'email_inviter' => {'message' => "test", 'emails' => - @valid_emails + ',' + @invalid_emails}} + context "mixed valid and invalid emails" do + let(:valid_emails) { "foo@bar.com,mbs@gmail.com" } + let(:invalid_emails) { "invalid_email" } + let(:invite_params) { {email_inviter: {emails: valid_emails + "," + invalid_emails}} } + + it "creates an InviteEmail worker" do + expect(Workers::Mail::InviteEmail).to receive(:perform_async).with( + valid_emails, alice.id, invite_params[:email_inviter] + ) + post :create, invite_params end - it 'creates an InviteEmail worker' do - inviter = double(:emails => [@emails], :send! => true) - expect(Workers::Mail::InviteEmail).to receive(:perform_async).with(@valid_emails, @user.id, @invite['email_inviter']) - post :create, @invite - end - - it 'returns to the previous page' do - post :create, @invite - expect(response).to redirect_to @referer + it "returns to the previous page" do + post :create, invite_params + expect(response).to redirect_to referer end it "flashes a notice" do - post :create, @invite - expected = I18n.t("invitations.create.sent", emails: @valid_emails.split(",").join(", ")) + ". " + - I18n.t("invitations.create.rejected", emails: @invalid_emails.split(",").join(", ")) + post :create, invite_params + expected = I18n.t("invitations.create.sent", emails: valid_emails.split(",").join(", ")) + ". " + + I18n.t("invitations.create.rejected", emails: invalid_emails) expect(flash[:error]).to eq(expected) end end - it 'redirects if invitations are closed' do - AppConfig.settings.invitations.open = false + context "with registration disabled" do + before do + AppConfig.settings.enable_registrations = false + end - post :create, @invite - expect(response).to be_redirect + it "displays an error if invitations are closed" do + AppConfig.settings.invitations.open = false + + post :create, invite_params + + expect(flash[:error]).to eq(I18n.t("invitations.create.closed")) + end + + it "displays an error when no invitations are left" do + alice.invitation_code.update_attributes(count: 0) + + post :create, invite_params + + expect(flash[:error]).to eq(I18n.t("invitations.create.no_more")) + end + end + + it "does not display an error when registration is open" do + AppConfig.settings.invitations.open = false + alice.invitation_code.update_attributes(count: 0) + + post :create, invite_params + + expect(flash[:error]).to be_nil end end describe '#new' do it 'renders' do - sign_in @user, scope: :user + sign_in alice, scope: :user get :new end end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 1a7c43987..49e07fa19 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -56,6 +56,14 @@ describe RegistrationsController, type: :controller do expect(response).to redirect_to new_user_session_path end + it "does redirect when invitations are closed now" do + code = InvitationCode.create(user: bob) + AppConfig.settings.invitations.open = false + + get :new, invite: {token: code.token} + expect(response).to redirect_to new_user_session_path + end + it "does not redirect when the registration is open" do AppConfig.settings.enable_registrations = true