Skip to content

Commit

Permalink
Prevent creating shifts in the past
Browse files Browse the repository at this point in the history
  • Loading branch information
woarewe committed Apr 3, 2023
1 parent 3e495ce commit e1048d6
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 2 deletions.
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ Style/WordArray:

Style/Documentation:
Enabled: false

Metrics/MethodLength:
Exclude:
- db/migrate/**/*.rb
14 changes: 12 additions & 2 deletions app/gateways/rest/api/shifts/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ module REST
class API
class Shifts
class Create < Base
helpers do
def handle_operation_errors
yield
rescue ::Shift::DoubleBookError, ::Shift::PastStartError => error
wrapped_error!({ start_at: error.message }, 422, as: :attributes)
end
end

class Contract < Dry::Validation::Contract
json do
required(:worker_id).filled(:string)
Expand All @@ -17,8 +25,10 @@ class Contract < Dry::Validation::Contract
payload => { worker_id: external_id, attributes: { start_at: }}
worker = ::Worker.find_by(external_id:)
not_found(:worker_id) if worker.nil?
shift = ::Shift::Create.new.call(worker:, start_at:)
present shift, with: Serialization::Shift
handle_operation_errors do
shift = ::Shift::Create.new.call(worker:, start_at:)
present shift, with: Serialization::Shift
end
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions app/operations/shift/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
class Shift
class Create < BaseOperation
def call(worker:, start_at:)
validate_start_at!(start_at)
attributes = prepare_attributes(worker, start_at)
handle_duplication_error do
Shift.create!(worker:, **attributes)
Expand All @@ -13,6 +14,10 @@ def call(worker:, start_at:)

private

def validate_start_at!(start_at)
raise PastStartError, I18n.t!("models.shift.errors.past_start") if start_at.past?
end

def prepare_attributes(worker, start_at)
{
start_at: worker.local_time(start_at),
Expand Down
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ en:
shift:
errors:
double_book: "The worker already has a shift on %{date}"
past_start: is in the past

hello: "Hello world"
4 changes: 4 additions & 0 deletions test/factories/shifts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,9 @@
trait :next_day do
start_at { in_zone_time.next_day }
end

trait :in_past do
start_at { in_zone_time - 7.days }
end
end
end
6 changes: 6 additions & 0 deletions test/gateways/rest/api/shifts/create_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class REST::API::Shifts::CreateTest < ActionDispatch::IntegrationTest
assert_response 422
end

test "preventing booking a shift in the past" do
shift = build(:shift, :in_past, worker:)
execute(payload(worker, shift))
assert_response 422
end

private

attr_reader(
Expand Down

0 comments on commit e1048d6

Please sign in to comment.