Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent non mc from dutying more than 6 hours consecutively #481

Open
wants to merge 55 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
2a0ec53
env
y33-j3T Mar 21, 2020
783db58
add function to check duty hours
y33-j3T Mar 21, 2020
1413800
get current user
JQChong Mar 21, 2020
0f9ff6f
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
JQChong Mar 21, 2020
7e27e0e
test of getting timeslots
JQChong Mar 21, 2020
397b38b
add non_mc_exceed_hrs function
y33-j3T Mar 29, 2020
2d66236
delete some code
JQChong Mar 29, 2020
5ebaa63
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
JQChong Mar 29, 2020
1de3725
collect timeslots
JQChong Mar 29, 2020
b4b6cb0
minor changes
y33-j3T Mar 29, 2020
7f5318b
merge jq work
y33-j3T Mar 29, 2020
8c59a1f
grab data
JQChong Mar 29, 2020
2c6627c
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
y33-j3T Mar 29, 2020
199245f
update non_mc_exceed_hrs?
y33-j3T Mar 29, 2020
2aebbf7
update duties controller
y33-j3T Mar 29, 2020
cf21c40
fix syntax errors
JQChong Apr 4, 2020
91d3252
bug fixes and implementing test cases
JQChong Apr 4, 2020
193b442
remove extra fn in js
y33-j3T Apr 4, 2020
5b48e19
Merge branch 'master' into prevent-non-mc-from-dutying-more-than-6-ho…
JQChong Apr 4, 2020
4e9d8f3
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
JQChong Apr 4, 2020
e0b6839
align literals
y33-j3T Apr 4, 2020
6979d13
resolve conflict
JQChong Apr 4, 2020
57c3bef
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
JQChong Apr 4, 2020
9b68e5c
fix hound violations
JQChong Apr 4, 2020
96c89d9
resolve spacing in brackets
y33-j3T Apr 4, 2020
c658d1c
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
y33-j3T Apr 4, 2020
a8ce2bb
fix more hound violations
JQChong Apr 4, 2020
44483ac
resolve spacing & line length
y33-j3T Apr 4, 2020
3adc797
fix hound violations for duties_controller_spec.rb
JQChong Apr 4, 2020
1390159
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
JQChong Apr 4, 2020
06901e3
alignment
y33-j3T Apr 4, 2020
f0a629c
fix more hound violations
JQChong Apr 4, 2020
4965911
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
JQChong Apr 4, 2020
7520a43
remove spaces
JQChong Apr 4, 2020
bd87012
update whitespace
y33-j3T Apr 4, 2020
8ca8ff9
alignment
y33-j3T Apr 4, 2020
02104f3
resolve conflict in js
y33-j3T Apr 4, 2020
97f55fc
add return statement
y33-j3T Apr 4, 2020
ddbc91c
remove return and whitespace
JQChong Apr 4, 2020
957721c
shorten function
y33-j3T Apr 11, 2020
e9bfee3
add end
JQChong Apr 11, 2020
1a5d756
add end
y33-j3T Apr 11, 2020
d794e61
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
y33-j3T Apr 11, 2020
6dee8cb
remove comment
y33-j3T Apr 11, 2020
ddb105f
.
JQChong Apr 11, 2020
3660437
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
JQChong Apr 11, 2020
6356bc1
.
JQChong Apr 11, 2020
08d0eac
Merge branch 'master' into prevent-non-mc-from-dutying-more-than-6-ho…
JQChong Apr 11, 2020
2e0fb47
split all time ranges
y33-j3T Apr 11, 2020
e7e1ddc
add end
y33-j3T Apr 11, 2020
2ba99e5
.
JQChong Apr 11, 2020
48f45ad
.
JQChong Apr 11, 2020
be6986b
remove extra line from index.html.erb
JQChong Apr 11, 2020
9bc57c7
fix syntax
y33-j3T Apr 11, 2020
18a408c
Merge branch 'prevent-non-mc-from-dutying-more-than-6-hours-consecuti…
y33-j3T Apr 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions app/assets/javascripts/duties.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,13 @@ function validateModal() {
}

function validateGrabPage() {
if ($("#grab-page-form input[type=checkbox]:checked").length > 0) {
return true;
} else {
// make sure at least one checkbox is checked
if (!$("#grab-page-form input[type=checkbox]:checked").length > 0) {
y33-j3T marked this conversation as resolved.
Show resolved Hide resolved
alert("Please select at least one time slot");
return false;
}
}

return true;
}

$(document).on('turbolinks:load', load);
43 changes: 43 additions & 0 deletions app/controllers/duties_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# rubocop:disable Metrics/ClassLength
class DutiesController < ApplicationController
MAX_HRS = 6
load_and_authorize_resource only: [:export]
def index
@header_iter = generate_header_iter
Expand Down Expand Up @@ -100,9 +101,51 @@ def can_duty_mc_timeslots?(duty_ids)
timeslots.all? { |t| !t.mc_only }
end

# helper for non_mc_exceed_hrs
def grabable_timeslots(duty_ids)
# timeslots of duty to grab
timeslot_ids = Duty.where(id: duty_ids).pluck(:timeslot_id)
time_range_ids = Timeslot.find(timeslot_ids).pluck(:time_range_id)
TimeRange.find(time_range_ids)
end

# helper for non_mc_exceed_hrs
def user_timeslots(duty_ids)
# timeslots of user on the day
date = Duty.where(id: duty_ids).pluck(:date)
usr_timeslot_ids = Duty.where(date: date, user_id: current_user.id)
.pluck(:timeslot_id)
usr_time_range_ids = Timeslot.find(usr_timeslot_ids).pluck(:time_range_id)
TimeRange.find(usr_time_range_ids)
end

def non_mc_exceed_hrs?(num_hrs, duty_ids)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/AbcSize: Assignment Branch Condition size for non_mc_exceed_hrs? is too high. [26.42/18]

return false if current_user.mc

all_time_ranges = grabable_timeslots(duty_ids) + user_timeslots(duty_ids)
all_time_ranges.sort! { |r1, r2| r1.start_time <=> r2.start_time }

prev_range = all_time_ranges[0]
total_hrs = (prev_range.end_time.to_i - prev_range.start_time.to_i) / 3600.0
(1...all_time_ranges.length).each do |i|
range = all_time_ranges[i]
if range.start_time.to_i == prev_range.end_time.to_i
total_hrs += (range.end_time.to_i - range.start_time.to_i) / 3600.0
return true if total_hrs > num_hrs
else
total_hrs = 0 # reset hour counter
end

prev_range = range
end

false
end

def grabable?(duty_ids)
return false if duty_ids.blank?
return false unless can_duty_mc_timeslots?(duty_ids)
return false if non_mc_exceed_hrs?(MAX_HRS, duty_ids)

grabable_duties.where(id: duty_ids).size == duty_ids.size
end
Expand Down
1 change: 1 addition & 0 deletions app/views/duties/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<div id="duty-start-time" data-start-time=<%= TimeRange.order(:start_time).first.start_time.strftime('%H') %>></div>
<div id="duty-end-time" data-end-time=<%= TimeRange.order(:end_time).last.end_time.strftime('%H')%>></div>
<div id="num-of-places" data-num-of-places=<%= @places.count %>></div>
<div id="current-user" data-current-user=<%= current_user%>>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this?


<div class="container-fluid no-padding-top">
<div class="row">
Expand Down
3 changes: 3 additions & 0 deletions env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MAILGUN_API_KEY=key-0123456789abcdef0123456789abcdef
MAILGUN_DOMAIN=sandbox0123456789abcdef0123456789abcdef.mailgun.org
MAILER_HOST=nussucommit.org
Comment on lines +1 to +3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't include this file in the branch. (Btw, the filename is supposed to be .env, you're missing a dot)

84 changes: 83 additions & 1 deletion spec/controllers/duties_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@

describe 'POST duties#grab' do
before do
sign_in create(:user)
@user = create(:user)
sign_in @user
end

it 'grab a duty' do
Expand Down Expand Up @@ -136,6 +137,87 @@
should redirect_to duties_path
expect(flash[:alert]).to be('Invalid duties to grab')
end

it 'does nothing when non-MC user tries to duty for more than 6 hours
consecutively' do
time_range1 = create(:time_range, start_time: Time.zone.now - 1.hour,
end_time: Time.zone.now + 2.hours)
timeslot1 = create(:timeslot, time_range: time_range1)
create(:duty, user: @user, timeslot: timeslot1)

time_range2 = create(:time_range, start_time: Time.zone.now + 4.hours,
end_time: Time.zone.now + 6.hours)
timeslot2 = create(:timeslot, time_range: time_range2)
create(:duty, user: @user, timeslot: timeslot2)

time_range3 = create(:time_range, start_time: Time.zone.now + 2.hours,
end_time: Time.zone.now + 4.hours)
timeslot3 = create(:timeslot, time_range: time_range3)
duty_to_grab = create(:duty, free: true, timeslot: timeslot3)

patch :grab, params: { duty_id: { duty_to_grab.id => duty_to_grab.id } }

should redirect_to duties_path
expect(flash[:alert]).to be('Invalid duties to grab')
end

it 'grabs duty when non-MC user tries to duty for exactly 6 hours
consecutively' do
time_range1 = create(:time_range, start_time: Time.zone.now - 1.hour,
end_time: Time.zone.now + 2.hours)
timeslot1 = create(:timeslot, time_range: time_range1)
create(:duty, user: @user, timeslot: timeslot1)

time_range2 = create(:time_range, start_time: Time.zone.now + 4.hours,
end_time: Time.zone.now + 5.hours)
timeslot2 = create(:timeslot, time_range: time_range2)
create(:duty, user: @user, timeslot: timeslot2)

time_range3 = create(:time_range, start_time: Time.zone.now + 2.hours,
end_time: Time.zone.now + 4.hours)
timeslot3 = create(:timeslot, time_range: time_range3)
duty_to_grab = create(:duty, free: true, timeslot: timeslot3)

start_date = duty_to_grab.date.beginning_of_week
expect do
patch :grab, params: { duty_id: { duty_to_grab.id => duty_to_grab.id } }
duty_to_grab.reload
end.to change { duty_to_grab.user }.to(subject.current_user)

expect(duty_to_grab.free).to be(false)
expect(duty_to_grab.request_user_id).to be(nil)
should redirect_to duties_path(start_date: start_date)
expect(flash[:notice]).to be('Duty successfully grabbed!')
end

it 'grabs duty when non-MC user tries to duty for more than 6 hours
non-consecutively' do
time_range1 = create(:time_range, start_time: Time.zone.now - 1.hour,
end_time: Time.zone.now + 2.hours)
timeslot1 = create(:timeslot, time_range: time_range1)
create(:duty, user: @user, timeslot: timeslot1)

time_range2 = create(:time_range, start_time: Time.zone.now + 5.hours,
end_time: Time.zone.now + 7.hours)
timeslot2 = create(:timeslot, time_range: time_range2)
create(:duty, user: @user, timeslot: timeslot2)

time_range3 = create(:time_range, start_time: Time.zone.now + 2.hours,
end_time: Time.zone.now + 4.hours)
timeslot3 = create(:timeslot, time_range: time_range3)
duty_to_grab = create(:duty, free: true, timeslot: timeslot3)

start_date = duty_to_grab.date.beginning_of_week
expect do
patch :grab, params: { duty_id: { duty_to_grab.id => duty_to_grab.id } }
duty_to_grab.reload
end.to change { duty_to_grab.user }.to(subject.current_user)

expect(duty_to_grab.free).to be(false)
expect(duty_to_grab.request_user_id).to be(nil)
should redirect_to duties_path(start_date: start_date)
expect(flash[:notice]).to be('Duty successfully grabbed!')
end
end

describe 'POST duties#drop' do
Expand Down