Skip to content
This repository has been archived by the owner on Jan 30, 2018. It is now read-only.

Commit

Permalink
Extract EventInviter from Invitations controller
Browse files Browse the repository at this point in the history
* Add validation for for invitation text to Invitation

https://trello.com/c/WXLLlx9n
  • Loading branch information
Jessie Young committed Aug 7, 2013
1 parent 452ac3a commit 99a2c5e
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 41 deletions.
50 changes: 16 additions & 34 deletions app/controllers/invitations_controller.rb
Expand Up @@ -5,7 +5,14 @@ class InvitationsController < ApplicationController
layout 'events'

def create
check_for_empty_invitation_text
event_inviter = EventInviter.new(event_inviter_attributes)

if event_inviter.valid?
event_inviter.send_invitations
else
flash[:error] = event_inviter.invalid_invitation_errors
end

redirect_to event
end

Expand All @@ -22,52 +29,27 @@ def destroy

private

def create_invitations(event, invitation_text)
invitee_emails.each do |email|
invitation = Invitation.new(
event: event,
invitation_text: invitation_text,
invitee: find_or_create_user(email),
sender: current_user
)
invitation.invite

if invitation.invalid?
flash[:error] = invitation.errors.full_messages.join(', ')
break
end
end
end

def check_for_empty_invitation_text
if invitation_text.empty?
flash[:error] = 'Invitation text cannot be blank'
else
create_invitations(event, invitation_text)
end
def event_inviter_attributes
{
current_user: current_user,
event: event,
invitee_emails: invitee_emails,
invitation_text: invitation_text
}
end

def event
@event ||= Event.find(params[:invitation][:event_id])
end

def find_or_create_user(email)
InviteeBuilder.new(email.strip, event).find_user_by_email_or_create_guest
end

def invitation_text
if params[:invitation][:invitation_text]
params[:invitation][:invitation_text].strip
else
""
end
params[:invitation][:invitation_text].strip
end

def invitee_emails
params[:invitation][:invitee_attributes][:name_or_email].split(',')
end


def after_destroy_path(event)
if event.owned_by?(current_user)
event_path(event)
Expand Down
44 changes: 44 additions & 0 deletions app/models/event_inviter.rb
@@ -0,0 +1,44 @@
class EventInviter
def initialize(options = {})
@current_user = options[:current_user]
@event = options[:event]
@invitation_text = options[:invitation_text]
@invitee_emails = options[:invitee_emails]
end

def valid?
invitations.map(&:valid?).exclude? false
end

def send_invitations
invitations.map do |invitation|
invitation.invite
end
end

def invalid_invitation_errors
invalid_invitations = invitations.select(&:invalid?)
invalid_invitations.first.errors.full_messages.join(', ')
end

private

def invitations
@invitations ||= @invitee_emails.map do |email|
build_invitation_for(email)
end
end

def build_invitation_for(email)
Invitation.new(
event: @event,
invitation_text: @invitation_text,
invitee: find_or_create_user(email),
sender: @current_user
)
end

def find_or_create_user(email)
InviteeBuilder.new(email.strip, @event).find_user_by_email_or_create_guest
end
end
2 changes: 2 additions & 0 deletions app/models/invitation.rb
Expand Up @@ -7,6 +7,7 @@ class Invitation < ActiveRecord::Base
accepts_nested_attributes_for :invitee

validates :event_id, presence: true
validates :invitation_text, presence: true
validates :invitee_type, presence: true
validates :invitee_id, presence: { message: 'is invalid' }
validates :invitee_id, uniqueness: {
Expand All @@ -21,6 +22,7 @@ def invite
end

def invite_without_notification
update_attributes(invitation_text: 'n/a')
save
end

Expand Down
2 changes: 1 addition & 1 deletion spec/controllers/invitations_controller_spec.rb
Expand Up @@ -80,7 +80,7 @@
it 'creates multiple invitations for the correct users' do
event_creator = create_user_and_sign_in
event = create_event_and_mock_find(event_creator)
invitation = stub('invitation', invite: nil, invalid?: false)
invitation = stub('invitation', invite: nil, valid?: true)
emails = 'guest1@example.com, guest2@example.com'
Invitation.stubs(new: invitation)
invitee = stub('invitee')
Expand Down
2 changes: 2 additions & 0 deletions spec/controllers/yammer_group_invitations_controller_spec.rb
Expand Up @@ -9,6 +9,7 @@

post :create,
invitation: {
invitation_text: 'Example text',
invitee_attributes: {
yammer_group_id: group.yammer_group_id,
name_or_email: group.name
Expand All @@ -27,6 +28,7 @@
2.times do
post :create,
invitation: {
invitation_text: 'Example text',
invitee_attributes: {
yammer_group_id: group.yammer_group_id,
name_or_email: group.name
Expand Down
2 changes: 2 additions & 0 deletions spec/controllers/yammer_user_invitations_controller_spec.rb
Expand Up @@ -8,6 +8,7 @@

post :create,
invitation: {
invitation_text: 'Example text',
invitee_attributes: { yammer_user_id: invitee.yammer_user_id },
event_id: event.id
}
Expand All @@ -23,6 +24,7 @@
2.times do
post :create,
invitation: {
invitation_text: 'Example text',
invitee_attributes: { yammer_user_id: invalid_invitee_id },
event_id: event.id
}
Expand Down
75 changes: 75 additions & 0 deletions spec/models/event_inviter_spec.rb
@@ -0,0 +1,75 @@
require 'spec_helper'

describe EventInviter, '#valid?' do
it 'returns true if all invitations are valid' do
current_user = build_stubbed(:user)
event = build_stubbed(:event)
invitation_text = 'Example text'
invitee_emails = ['example1@example.com', 'example2@example.com']
options = {
current_user: current_user,
event: event,
invitation_text: invitation_text,
invitee_emails: invitee_emails
}

valid = EventInviter.new(options).valid?

expect(valid).to be true
end

it 'returns false if all invitations are not valid' do
current_user = build_stubbed(:user)
event = build_stubbed(:event)
invitation_text = 'Example text'
invitee_emails = ['example1@example.com', 'example@example.com']
options = {
current_user: current_user,
event: event,
invitee_emails: invitee_emails
}

valid = EventInviter.new(options).valid?

expect(valid).to be false
end
end

describe EventInviter, '#send_invitations' do
it 'calls invite on each invitation' do
invitation_stub = stub('invitation', :invite)
Invitation.stubs(:new).returns(invitation_stub)
current_user = build_stubbed(:user)
event = build_stubbed(:event)
invitation_text = 'Example text'
invitee_emails = ['example1@example.com', 'example2@example.com']
options = {
current_user: current_user,
event: event,
invitation_text: invitation_text,
invitee_emails: invitee_emails
}

EventInviter.new(options).send_invitations

expect(Invitation).to have_received(:new).twice
expect(invitation_stub).to have_received(:invite).twice
end
end

describe EventInviter, '#invalid_invitation_errors' do
it 'returns the errors belonging to the first invalid invitation' do
current_user = build_stubbed(:user)
event = build_stubbed(:event)
invitee_emails = ['example1@example.com', 'example2@example.com']
options = {
current_user: current_user,
event: event,
invitee_emails: invitee_emails
}

errors = EventInviter.new(options).invalid_invitation_errors

expect(errors).to eq "Invitation text can't be blank"
end
end
19 changes: 13 additions & 6 deletions spec/models/invitation_spec.rb
Expand Up @@ -12,6 +12,7 @@
it { expect(subject).to accept_nested_attributes_for :invitee }

it { expect(subject).to validate_presence_of(:event_id) }
it { expect(subject).to validate_presence_of(:invitation_text) }
it { expect(subject).to validate_presence_of(:invitee_type) }
it { expect(subject).to validate_presence_of(:invitee_id).with_message(/is invalid/) }

Expand Down Expand Up @@ -39,11 +40,13 @@
describe Invitation, '#invite' do
context 'when the invite is valid' do
it 'notifies the invitee with a message' do
invitee = create(:user)
sender = build_stubbed(:user)
event = build_stubbed(:event)
InvitationCreatedMessageJob.stubs(:enqueue)
invitation = Invitation.new(event: event, invitee: invitee, sender: sender)
invitation = Invitation.new(
event: build_stubbed(:event),
invitation_text: 'text',
invitee: create(:user),
sender: build_stubbed(:user)
)

invitation.invite

Expand All @@ -64,11 +67,15 @@

context 'when the sender is a yammer user' do
it 'creates an activity message for the sending user' do
invitee = create(:user)
sender = build_stubbed(:user)
event = build_stubbed(:event)
ActivityCreatorJob.stubs(:enqueue)
invitation = Invitation.new(event: event, invitee: invitee, sender: sender)
invitation = Invitation.new(
event: event,
invitation_text: 'text',
invitee: create(:user),
sender: sender
)
invitation.invite

expect(ActivityCreatorJob).to have_received(:enqueue).
Expand Down

0 comments on commit 99a2c5e

Please sign in to comment.