-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f17082a
commit c72c902
Showing
11 changed files
with
230 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# frozen_string_literal: true | ||
|
||
class TimeOffsController < ApplicationController | ||
skip_before_action :authenticate | ||
|
||
def create | ||
if text.blank? || start_datetime.nil? || end_datetime.nil? | ||
render json: { message: 'Invalid parameters' }, status: :ok | ||
return | ||
end | ||
|
||
time_off = TimeOffBuilder.call(text, start_datetime, end_datetime) | ||
time_off&.save | ||
success = time_off&.persisted? | ||
msg = success ? { id: time_off&.id } : 'The time of request creation failed' | ||
|
||
render json: msg, status: success ? :ok : :unprocessable_entity | ||
rescue StandardError => e | ||
logger.fatal "Error: TimeOffCreator: #{e.message}, Params: #{time_off_params}" | ||
|
||
render json: { message: e.message }, status: :internal_server_error | ||
end | ||
|
||
def destroy | ||
time_off = TimeOffBuilder.new(text, start_datetime, end_datetime).call | ||
found_time_off = TimeOff.where(user: time_off.user, starts_at: time_off.starts_at, ends_at: time_off.ends_at).first | ||
found_time_off&.destroy | ||
|
||
render json: { message: 'Time off request deleted' }, status: :ok | ||
end | ||
|
||
private | ||
|
||
def text | ||
@text ||= time_off_params[:text] | ||
end | ||
|
||
def start_datetime | ||
@start_datetime ||= time_off_params[:start_datetime] | ||
end | ||
|
||
def end_datetime | ||
@end_datetime ||= time_off_params[:end_datetime] | ||
end | ||
|
||
def time_off_params | ||
params.require(:webhook_time_off).permit(:text, :start_datetime, :end_datetime).to_h | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# frozen_string_literal: true | ||
|
||
class TimeOffBuilder < ApplicationService | ||
def initialize(text, start_datetime, end_datetime) | ||
@text = text | ||
@start_datetime = start_datetime.to_time | ||
@end_datetime = end_datetime.to_time | ||
end | ||
|
||
def call | ||
return nil if invalid_params? | ||
|
||
return raise("Many users with the same name. Users: #{users}") unless users.count.eql?(1) | ||
return raise("No user found with the name #{user_name}") if users.count.eql?(0) | ||
|
||
build_time_off(users.first) | ||
end | ||
|
||
def build_time_off(user) | ||
TimeOff.new( | ||
user:, | ||
starts_at: @start_datetime, | ||
ends_at: @end_datetime, | ||
time_off_type: | ||
) | ||
end | ||
|
||
private | ||
|
||
def time_off_type | ||
TimeOffType.find_or_create_by!(name: time_off_name) | ||
end | ||
|
||
def users | ||
@users = User.by_name(user_name) | ||
end | ||
|
||
def invalid_params? | ||
@text.blank? || (@start_datetime.nil? || @end_datetime.nil?) | ||
end | ||
|
||
def user_name | ||
name_match = @text.match(/^([\w'-]+(?:\s+[\w'-]+)*)(?:\s+on|\s+is)/i) | ||
name_match ? name_match[1] : @text | ||
end | ||
|
||
def time_off_name | ||
case @text | ||
when /.*Paid Time Off.*/ | ||
'vacation' | ||
when /.*Unpaid Time Off.*/ | ||
'unpaid leave' | ||
when /.*Errand.*/, /.*Out of Office.*/ | ||
'errand' | ||
when /.*Sick.*/ | ||
'sick leave' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# frozen_string_literal: true | ||
|
||
json.extract! time_off, :id, :created_at, :updated_at | ||
json.url time_off_url(time_off, format: :json) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# frozen_string_literal: true | ||
|
||
json.array! @time_offs, partial: 'time_offs/time_off', as: :time_off |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# frozen_string_literal: true | ||
|
||
json.partial! 'time_offs/time_off', time_off: @time_off |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
class AddUnaccentExtension < ActiveRecord::Migration[7.0] | ||
def change | ||
enable_extension 'unaccent' | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe TimeOffsController, type: :controller do | ||
render_views | ||
|
||
let!(:user) { create(:user, first_name: 'Kaio', last_name: 'Magalhaes') } | ||
|
||
def valid_params(text, _start_datetime = '2018-03-29T13:34:00', end_datetime = '2018-03-29T17:35:00') | ||
{ webhook_time_off: { | ||
text:, | ||
start_datetime: end_datetime, end_datetime: | ||
} } | ||
end | ||
|
||
before do | ||
user | ||
end | ||
|
||
describe '#create' do | ||
context 'with valid params' do | ||
it 'creates a new TimeOff' do | ||
post :create, params: valid_params('Kaio Costa Porto De Magalhães on Paid Time Off') | ||
expect(response).to have_http_status(:ok) | ||
end | ||
end | ||
|
||
context 'with a Paid Time Off request it' do | ||
it "creates a time off with the 'paid time off' type" do | ||
post :create, params: valid_params('Kaio Costa Porto De Magalhães on Paid Time Off') | ||
time_of_id = response.parsed_body['id'] | ||
time_off = TimeOff.find(time_of_id) | ||
|
||
expect(time_off.time_off_type.name).to eq('vacation') | ||
end | ||
end | ||
|
||
context 'with an On Errands request it' do | ||
it "creates a time off with the 'errands' type" do | ||
post :create, params: valid_params('Kaio Costa Porto De Magalhães on Errands') | ||
time_of_id = response.parsed_body['id'] | ||
time_off = TimeOff.find(time_of_id) | ||
|
||
expect(time_off.time_off_type.name).to eq('errand') | ||
end | ||
end | ||
|
||
context 'with a Sick Leave request it' do | ||
it "creates a time off with the 'sick leave' type" do | ||
post :create, params: valid_params('Kaio Costa Porto De Magalhães on Sick Leave') | ||
time_of_id = response.parsed_body['id'] | ||
time_off = TimeOff.find(time_of_id) | ||
|
||
expect(time_off.time_off_type.name).to eq('sick leave') | ||
end | ||
end | ||
|
||
context 'with a start and end date difference of less than 4 hours' do | ||
it 'creates a time off request' do | ||
start_date = '2018-03-29T13:34:00' | ||
end_date = '2018-03-29T14:35:00' | ||
difference_in_hours = (Time.zone.parse(end_date) - Time.zone.parse(start_date)) / 3600 | ||
|
||
# confirm the difference in hours between the dates | ||
expect(difference_in_hours).to be < 4 | ||
|
||
post :create, | ||
params: valid_params('Kaio Costa Porto De Magalhães on Errands', end_date, | ||
end_date) | ||
|
||
expect(response).to have_http_status(:ok) | ||
end | ||
end | ||
end | ||
|
||
describe '#destroy' do | ||
context 'with valid params' do | ||
it 'finds and deletes the time off' do | ||
create(:time_off_type) | ||
# first creat the time off | ||
post :create, | ||
params: valid_params('Kaio Costa Porto De Magalhães on Paid Time Off') | ||
|
||
expect do | ||
delete :destroy, params: valid_params('Kaio Costa Porto De Magalhães on Paid Time Off') | ||
end.to change(TimeOff, :count).by(-1) | ||
end | ||
end | ||
end | ||
end |