From c7d48da0aeed69be67cc41809e6a9bfb5d7076ea Mon Sep 17 00:00:00 2001 From: Fagner Oliveira Date: Wed, 6 Sep 2017 20:08:09 -0500 Subject: [PATCH] updating checkout validation --- app/controllers/self_tracking_controller.rb | 18 +++- app/models/workday.rb | 20 +++++ app/views/self_tracking/index.html.erb | 4 +- .../self_tracking_controller_test.rb | 87 ++++++++++++++++++- test/integration/self_tracking_test.rb | 18 ++++ test/integration/users_login_test.rb | 14 +-- 6 files changed, 147 insertions(+), 14 deletions(-) diff --git a/app/controllers/self_tracking_controller.rb b/app/controllers/self_tracking_controller.rb index b8ac420..6a25737 100644 --- a/app/controllers/self_tracking_controller.rb +++ b/app/controllers/self_tracking_controller.rb @@ -153,16 +153,26 @@ def check_out_all if workday_volunteer.end_time.nil? workday_volunteer.end_time = Time.parse(@check_out_all_form.check_out_time) if !workday_volunteer.is_end_time_valid - unupdated_volunteers[workday_volunteer.volunteer_id.to_s] = 'End time is before start time.' - elsif !@workday.is_overlapping_volunteer(workday_volunteer) - unupdated_volunteers[workday_volunteer.volunteer_id.to_s] = 'End time overlaps another workday entry for this volunteer' + unupdated_volunteers[workday_volunteer.id.to_s] = 'End time is before start time.' else - workday_volunteer.save + overlapped_workday = @workday.get_overlapping_workday(workday_volunteer); + if !overlapped_workday.nil? + unupdated_volunteers[workday_volunteer.id.to_s] = 'End time overlaps the workday:' << overlapped_workday.name + else + if @workday.is_overlapping_volunteer(workday_volunteer) + unupdated_volunteers[workday_volunteer.id.to_s] = 'End time overlaps another workday entry for this volunteer' + else + workday_volunteer.save + end + end end end end if unupdated_volunteers.length == 0 + session.delete(:unupdated_message) + session.delete(:unupdated_date) + redirect_to self_tracking_index_path else session[:unupdated_date] = Time.parse(@check_out_all_form.check_out_time).strftime("%l:%M %p") diff --git a/app/models/workday.rb b/app/models/workday.rb index cf58f6b..b430573 100644 --- a/app/models/workday.rb +++ b/app/models/workday.rb @@ -19,6 +19,7 @@ def skip_dup_check? def is_overlapping_volunteer(workday_volunteer) + # Check overlapping in the current workday overlapping_shifts = self.workday_volunteers.where( "(volunteer_id = :volunteer_id) AND (id != :this_workday_volunteer_id) AND (start_time > :this_start_time) AND (:this_end_time >= start_time)", @@ -32,4 +33,23 @@ def is_overlapping_volunteer(workday_volunteer) overlapping_shifts.count > 0 ? true : false end + def get_overlapping_workday(workday_volunteer) + overlapping_shifts = + Workday.joins(:workday_volunteers) + .where("workdays.workdate = :workdate AND + (workday_volunteers.volunteer_id = :volunteer_id) AND + (workdays.id != :id) AND (:this_end_time > workday_volunteers.start_time) AND + (workday_volunteers.end_time is null) ", + { + id: self.id, + workdate: self.workdate, + volunteer_id: workday_volunteer.volunteer.id, + this_workday_volunteer_id: workday_volunteer.id, + this_start_time: workday_volunteer.start_time.strftime("%H:%M:%S"), + this_end_time: workday_volunteer.end_time.strftime("%H:%M:%S") + }) + + overlapping_shifts.count > 0 ? overlapping_shifts[0] : nil + end + end diff --git a/app/views/self_tracking/index.html.erb b/app/views/self_tracking/index.html.erb index 57e151d..da24501 100644 --- a/app/views/self_tracking/index.html.erb +++ b/app/views/self_tracking/index.html.erb @@ -19,7 +19,7 @@ volunteer = workday_volunteer.volunteer %> <% has_message = session[:unupdated_message].present? && - !session[:unupdated_message][workday_volunteer.volunteer_id.to_s].nil? %> + !session[:unupdated_message][workday_volunteer.id.to_s].nil? %> class="text-muted"<% end %>> <%= volunteer.name %> @@ -42,7 +42,7 @@ <% if has_message %> - + <%= session[:unupdated_date] %> diff --git a/test/controllers/self_tracking_controller_test.rb b/test/controllers/self_tracking_controller_test.rb index 1db52f3..33abdb2 100644 --- a/test/controllers/self_tracking_controller_test.rb +++ b/test/controllers/self_tracking_controller_test.rb @@ -154,8 +154,6 @@ def setup # Confirm no one is checked in yet. assert @workday.workday_volunteers.empty? - - # Check-in at 8am. get :check_in, id: @volunteer.id, :check_in_form => {check_in_time: "8:00 AM"} assert_response :success @@ -286,6 +284,91 @@ def setup end end + test "should validate checkout all functionality" do + self.setup_self_tracking_session + + # Confirm no one is checked in yet. + assert @workday.workday_volunteers.empty? + + # Check-in two volunteers and then check them out. + get :check_in, id: @volunteer.id, :check_in_form => {check_in_time: "12:30 PM"} + get :check_in, id: @volunteer.id, :check_in_form => {check_in_time: "8:00 AM"} + get :check_in, id: @pending_volunteer.id, :check_in_form => {check_in_time: "1:20 PM"} + assert_equal 3, @workday.workday_volunteers.count + + workdate = @workday.workdate + # Using .change so we retain the timezone. + target_date_time = DateTime.now.change( + :year => workdate.year, :month => workdate.month, :day => workdate.day, :hour => 17, :minute => 0 + ) + Timecop.freeze(target_date_time) do + + # Get the original records + volunteer_workday = @workday.workday_volunteers.where(:volunteer_id => @volunteer.id).order(:start_time).first + pending_volunteer_workday = @workday.workday_volunteers.where(:volunteer_id => @pending_volunteer.id).first + + # Checkout before the check-in time. + get :check_out_all, :check_out_all_form => { check_out_time: "6:00 AM" } + assert_redirected_to self_tracking_index_path + assert !session[:unupdated_message].empty? + assert session[:unupdated_message].has_value?("End time is before start time.") + + # Checkout after the start of next shift + get :check_out_all, :check_out_all_form => {check_out_time: "2:00 PM"} + assert_redirected_to self_tracking_index_path + assert_equal 1, session[:unupdated_message].count + assert session[:unupdated_message].has_value?("End time overlaps another workday entry for this volunteer") + + # Valid checkout + get :check_out_all, :check_out_all_form => {check_out_time: "11:46 AM"} + assert_redirected_to self_tracking_index_path + + end + end + + test "Should check out all overlapp another workday" do + + self.setup_self_tracking_session + assert @workday.workday_volunteers.empty? + get :check_in, id: @volunteer.id, :check_in_form => {check_in_time: "3:00 PM"} + assert_equal 1, @workday.workday_volunteers.count + + @workday = workdays(:two) + self.setup_self_tracking_session + assert @workday.workday_volunteers.empty? + get :check_in, id: @volunteer.id, :check_in_form => {check_in_time: "12:30 PM"} + get :check_in, id: @volunteer.id, :check_in_form => {check_in_time: "8:00 AM"} + get :check_in, id: @pending_volunteer.id, :check_in_form => {check_in_time: "1:20 PM"} + assert_equal 3, @workday.workday_volunteers.count + + workdate = @workday.workdate + # Using .change so we retain the timezone. + target_date_time = DateTime.now.change( + :year => workdate.year, :month => workdate.month, :day => workdate.day, :hour => 17, :minute => 0 + ) + Timecop.freeze(target_date_time) do + + # Overlaps workday + get :check_out_all, :check_out_all_form => {check_out_time: "3:01 PM"} + assert_redirected_to self_tracking_index_path + assert_equal 2, session[:unupdated_message].count + + # Overlaps 8:00 AM and checks out 12:00 PM + get :check_out_all, :check_out_all_form => {check_out_time: "2:00 PM"} + assert_redirected_to self_tracking_index_path + assert_equal 1, session[:unupdated_message].count + + # End time overlaps checked out item + get :check_out_all, :check_out_all_form => {check_out_time: "1:00 PM"} + assert_redirected_to self_tracking_index_path + assert_equal 1, session[:unupdated_message].count + + # Check out 08:00 AM + get :check_out_all, :check_out_all_form => {check_out_time: "12:29 PM"} + assert_redirected_to self_tracking_index_path + assert session[:unupdated_message].nil? + end + end def setup_self_tracking_session session[:self_tracking_workday_id] = @workday.id diff --git a/test/integration/self_tracking_test.rb b/test/integration/self_tracking_test.rb index 8c0c200..edfe442 100644 --- a/test/integration/self_tracking_test.rb +++ b/test/integration/self_tracking_test.rb @@ -1,4 +1,22 @@ require 'test_helper' class SelfTrackingTest < ActionDispatch::IntegrationTest + + def setup + @user = users(:one) + @project = projects(:one) + @workday = Workday.new(project: @project, workdate: Date.today.to_s(:db), name: "Example") + @workday.save + end + + def teardown + @workday.destroy + end + + test "should redirect to check out all" do + log_in_as(@user) + get self_tracking_launch_path(:check_out_all => true, :id => @workday.id), session: { user_id: @user.id } + assert_redirected_to self_tracking_check_out_all_path + end + end diff --git a/test/integration/users_login_test.rb b/test/integration/users_login_test.rb index 96570f0..4ab563a 100644 --- a/test/integration/users_login_test.rb +++ b/test/integration/users_login_test.rb @@ -6,15 +6,20 @@ def setup @user = users(:one) end - test "login with invalid information" do get login_path assert_template 'sessions/new' post login_path, session: { email: "", password: "" } + assert_redirected_to login_path + assert_not flash.empty? + end + + test "login with invalid information and target_url" do + get login_path assert_template 'sessions/new' + post login_path, session: { email: "", password: "", target_url: root_path } + assert_redirected_to login_path(:target_url => root_path) assert_not flash.empty? - get root_path - assert flash.empty? end test "login with valid information followed by log out" do @@ -51,7 +56,4 @@ def setup assert_nil cookies['remember_token'] end - - end -