Skip to content

Commit

Permalink
Scheduling a call. Closes #24
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver Azevedo Barnes committed Feb 19, 2016
1 parent e268081 commit ed56a5e
Show file tree
Hide file tree
Showing 47 changed files with 870 additions and 213 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@

# vagrant instance folder
.vagrant

Procfile
10 changes: 8 additions & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ Style/DotPosition:
EnforcedStyle: trailing

Style/EmptyLinesAroundClassBody:
EnforcedStyle: empty_lines
Enabled: false

Style/EmptyLinesAroundModuleBody:
EnforcedStyle: empty_lines
Enabled: false

Style/IndentationConsistency:
EnforcedStyle: rails
Expand Down Expand Up @@ -67,6 +67,12 @@ Style/BlockDelimiters:
Style/ClassAndModuleChildren:
Enabled: false

Style/ExtraSpacing:
Enabled: false

Style/SpaceAroundOperators:
Enabled: false

Metrics/AbcSize:
Max: 25

Expand Down
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ group :development, :test do
gem 'guard-rubocop'
gem 'guard-bundler', require: false
gem 'capybara'
gem 'capybara-email'
gem 'pry'
gem 'factory_girl_rails'
gem 'shoulda-matchers', require: false
gem 'shoulda-matchers', '~> 3.1.1', require: false
gem 'database_cleaner'
end
10 changes: 8 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ GEM
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
capybara-email (2.4.0)
capybara (~> 2.4)
mail
coderay (1.1.0)
coffee-rails (4.1.1)
coffee-script (>= 2.2.0)
Expand All @@ -78,6 +81,7 @@ GEM
coffee-script-source (1.10.0)
concurrent-ruby (1.0.0)
daemons (1.2.3)
database_cleaner (1.5.1)
debug_inspector (0.0.2)
delayed_job (4.1.1)
activesupport (>= 3.0, < 5.0)
Expand Down Expand Up @@ -316,7 +320,7 @@ GEM
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
shellany (0.0.1)
shoulda-matchers (3.1.0)
shoulda-matchers (3.1.1)
activesupport (>= 4.0.0)
slop (3.6.0)
sprockets (3.5.2)
Expand Down Expand Up @@ -399,8 +403,10 @@ DEPENDENCIES
bullet
capistrano!
capybara
capybara-email
coffee-rails
daemons
database_cleaner
delayed_job_active_record
devise
factory_girl_rails
Expand Down Expand Up @@ -434,7 +440,7 @@ DEPENDENCIES
ruby-prof
rvm-capistrano
sass-rails
shoulda-matchers
shoulda-matchers (~> 3.1.1)
sqlite3
stackprof
tire
Expand Down
26 changes: 24 additions & 2 deletions Guardfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This group allows to skip running RuboCop when RSpec failed.
group :red_green_refactor, halt_on_fail: true do
guard :rspec, cmd: "bundle exec rspec" do
guard :rspec, cmd: "bundle exec rspec --fail-fast" do
require "guard/rspec/dsl"
dsl = Guard::RSpec::Dsl.new(self)

Expand Down Expand Up @@ -41,9 +41,31 @@ group :red_green_refactor, halt_on_fail: true do
watch('spec/features/people_registration_spec.rb')
watch('app/controllers/public/people_controller.rb') { 'spec/features/people_registration_spec.rb' }
watch('app/views/public/people/new.html.erb') { 'spec/features/people_registration_spec.rb' }
watch('app/views/public/people/_form.html.erb') { 'spec/features/people_registration_spec.rb' }

watch('app/models/v2/event.rb') { 'spec/features/invite_person_to_phone_call_spec.rb' }
watch('app/models/v2/event_invitation.rb') { 'spec/features/invite_person_to_phone_call_spec.rb' }
watch('app/models/v2/time_window.rb') { 'spec/features/invite_person_to_phone_call_spec.rb' }
watch('app/models/v2/time_slot.rb') { 'spec/features/invite_person_to_phone_call_spec.rb' }
watch('app/mailers/event_invitation_mailer.rb') { 'spec/features/invite_person_to_phone_call_spec.rb' }
watch('app/controllers/v2/event_invitations_controller.rb') { 'spec/features/invite_person_to_phone_call_spec.rb' }
watch('app/views/v2/event_invitations/new.html.erb') { 'spec/features/invite_person_to_phone_call_spec.rb' }
watch('app/views/v2/event_invitations/_form.html.erb') { 'spec/features/invite_person_to_phone_call_spec.rb' }
watch('app/views/event_invitation_mailer/invite.html.erb') { 'spec/features/invite_person_to_phone_call_spec.rb' }
watch('app/views/event_invitation_mailer/invite.text.erb') { 'spec/features/invite_person_to_phone_call_spec.rb' }

watch('spec/features/person_responds_to_interview_invitation_spec.rb')
watch('app/views/event_invitation_mailer/invite.html.erb') { 'spec/features/person_responds_to_interview_invitation_spec.rb' }
watch('app/views/event_invitation_mailer/invite.text.erb') { 'spec/features/person_responds_to_interview_invitation_spec.rb' }

watch('app/mailers/event_invitation_mailer.rb') { 'spec/features/person_responds_to_interview_invitation_spec.rb' }
watch('app/models/v2/reservation.rb') { 'spec/features/person_responds_to_interview_invitation_spec.rb' }
watch('app/controllers/v2/reservations_controller.rb') { 'spec/features/person_responds_to_interview_invitation_spec.rb' }
watch('app/views/v2/reservations/new.html.erb') { 'spec/features/person_responds_to_interview_invitation_spec.rb' }
watch('app/views/v2/reservations/_form.html.erb') { 'spec/features/person_responds_to_interview_invitation_spec.rb' }
end

guard :minitest do
guard :minitest, test_folders: ['test'] do
watch(%r{^test/(.*)\/?test_(.*)\.rb$})
watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
watch(%r{^test/test_helper\.rb$}) { 'test' }
Expand Down
39 changes: 39 additions & 0 deletions app/controllers/v2/event_invitations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class V2::EventInvitationsController < ApplicationController
def new
@event_invitation = V2::EventInvitation.new
end

def create
@event_invitation = V2::EventInvitation.new(event_invitation_params)

if @event_invitation.save
send_notifications(@event_invitation)
flash[:notice] = 'Person was successfully invited.'
else
flash[:error] = 'There were problems with some of the fields.'
end

render :new
end

private

def send_notifications(event_invitation)
EventInvitationMailer.invite(
email_address: event_invitation.email_address,
event: event_invitation.event
).deliver_later
end

def event_invitation_params
params.require(:v2_event_invitation).
permit(
:email_address,
:description,
:slot_length,
:date,
:start_time,
:end_time
)
end
end
48 changes: 48 additions & 0 deletions app/controllers/v2/reservations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class V2::ReservationsController < ApplicationController
skip_before_action :authenticate_user!

def new
event = V2::Event.find(event_params[:event_id])
@time_slots = event.time_slots
@person = Person.find_by(email_address: person_params[:email_address])
@reservation = V2::Reservation.new(time_slot: V2::TimeSlot.new)
end

def create
@reservation = V2::Reservation.new(reservation_params)

if @reservation.save
flash[:notice] = "An interview has been booked for #{@reservation.time_slot.to_weekday_and_time}"

send_notifications(@reservation)
else
flash[:error] = "No time slot was selected, couldn't create the reservation"
end

@time_slots = []
@person = @reservation.person

render :new
end

private

def send_notifications(reservation)
ReservationNotifier.notify(
email_address: reservation.person.email_address,
reservation: reservation
).deliver_later
end

def event_params
params.permit(:event_id)
end

def reservation_params
params.require(:v2_reservation).permit(:person_id, :time_slot_id)
end

def person_params
params.permit(:email_address, :person_id)
end
end
10 changes: 10 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module ApplicationHelper
def simple_time_select_options
minutes = %w( 00 15 30 45 )
hours = (0..23).to_a.map { |h| format('%.2d', h) }
options = hours.map do |h|
minutes.map { |m| "#{h}:#{m}" }
end.flatten
options_for_select(options)
end
end
4 changes: 4 additions & 0 deletions app/mailers/application_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class ApplicationMailer < ActionMailer::Base
default from: '[email protected]'
layout 'mailer'
end
10 changes: 10 additions & 0 deletions app/mailers/event_invitation_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class EventInvitationMailer < ApplicationMailer
def invite(email_address:, event:)
admin_email = '[email protected]'
@email_address = email_address
@event = event
mail(to: email_address,
bcc: admin_email,
subject: 'Phone call interview')
end
end
10 changes: 10 additions & 0 deletions app/mailers/reservation_notifier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class ReservationNotifier < ApplicationMailer
def notify(email_address:, reservation:)
admin_email = '[email protected]'
@email_address = email_address
@reservation = reservation
mail(to: email_address,
bcc: admin_email,
subject: 'Interview scheduled')
end
end
1 change: 0 additions & 1 deletion app/models/comment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ class Comment < ActiveRecord::Base

validates_presence_of :content
belongs_to :commentable, polymorphic: true, touch: true

end
6 changes: 6 additions & 0 deletions app/models/v2/event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class V2::Event < ActiveRecord::Base
has_many :time_slots, class_name: '::V2::TimeSlot'

validates :description, presence: true
validates :time_slots, presence: true
end
32 changes: 32 additions & 0 deletions app/models/v2/event_invitation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class V2::EventInvitation
include ActiveModel::Model

attr_accessor :email_address, :description, :slot_length, :date, :start_time, :end_time
attr_reader :event

validates :email_address, :description, :slot_length, :date, :start_time, :end_time, presence: true

def save
if valid?
@event = V2::Event.new(
description: description,
time_slots: time_slots
)

@event.save!
else
false
end
end

private

def time_slots
V2::TimeWindow.new(
slot_length: slot_length,
date: date,
start_time: start_time,
end_time: end_time
).slots
end
end
9 changes: 9 additions & 0 deletions app/models/v2/reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class V2::Reservation < ActiveRecord::Base
self.table_name = 'v2_reservations'

belongs_to :time_slot, class_name: '::V2::TimeSlot'
belongs_to :person

validates :person, presence: true
validates :time_slot, presence: true
end
16 changes: 16 additions & 0 deletions app/models/v2/time_slot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class V2::TimeSlot < ActiveRecord::Base
self.table_name = 'v2_time_slots'

belongs_to :event, class_name: '::V2::Event'

validates :start_time, presence: true
validates :end_time, presence: true

def to_time_and_weekday
"#{start_time.strftime('%H:%M')} - #{end_time.strftime('%H:%M')} #{start_time.strftime('%A %d')}"
end

def to_weekday_and_time
"#{start_time.strftime('%A %d')} #{start_time.strftime('%H:%M')} - #{end_time.strftime('%H:%M')}"
end
end
42 changes: 42 additions & 0 deletions app/models/v2/time_window.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
class V2::TimeWindow

def initialize(date:, start_time:, end_time:, slot_length:)
@date = date
@start_time = start_time
@end_time = end_time
@slot_length = slot_length
@slots = []
end

def slots
slot_start = start_time
slot_end = slot_start + slot_length

while slot_end <= end_time
@slots << ::V2::TimeSlot.new(start_time: slot_start, end_time: slot_end)

slot_start = slot_end
slot_end += slot_length
end

@slots
end

private

def date
Date.strptime(@date, '%m/%d/%Y')
end

def start_time
Time.zone.parse("#{date} #{@start_time}")
end

def end_time
Time.zone.parse("#{date} #{@end_time}")
end

def slot_length
@slot_length.delete(' mins').to_i.minutes
end
end
8 changes: 8 additions & 0 deletions app/views/event_invitation_mailer/invite.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<p>Hello, you've been invited to a phone interview</p>

<p><%= link_to 'Please click to setup a time for your interview',
new_v2_reservation_url(
email_address: @email_address,
event_id: @event.id
) %></p>

7 changes: 7 additions & 0 deletions app/views/event_invitation_mailer/invite.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Hello, you've been invited to a phone interview

<%= link_to 'Please click to setup a time for your interview',
new_v2_reservation_url(
email_address: @email_address,
event_id: @event.id
) %>
5 changes: 5 additions & 0 deletions app/views/layouts/mailer.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<html>
<body>
<%= yield %>
</body>
</html>
1 change: 1 addition & 0 deletions app/views/layouts/mailer.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= yield %>
Loading

0 comments on commit ed56a5e

Please sign in to comment.