Skip to content

Commit

Permalink
Even simpler domain events
Browse files Browse the repository at this point in the history
Co-authored-by: Szymon Fiedler <szymon.fiedler@gmail.com>
  • Loading branch information
mostlyobvious and fidel committed Oct 13, 2023
1 parent ab7edc9 commit f31bb0d
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 59 deletions.
18 changes: 6 additions & 12 deletions lib/booking.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
module Booking
Event = Data.define(:data, :event_type) do
def initialize(data: Hash.new)
super(data: data, event_type: self.class.name)
end
end
ScheduleReleased = Data.define(:scheduled_at, :duration)
ScheduleReserved = Data.define(:scheduled_at, :duration)

ScheduleReleased = Class.new(Event)
ScheduleReserved = Class.new(Event)

AppointmentProposed = Class.new(Event)
AppointmentAccepted = Class.new(Event)
AppointmentRejected = Class.new(Event)
AppointmentCancelled = Class.new(Event)
AppointmentProposed = Data.define(:id, :proposed_at)
AppointmentAccepted = Data.define(:id, :accepted_at)
AppointmentRejected = Data.define(:id, :rejected_at)
AppointmentCancelled = Data.define(:id, :cancelled_at)
end
8 changes: 4 additions & 4 deletions lib/booking/appointment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@ def initialize(id, clock:)
def propose
invalid_state unless @state.initial?
@state.to_proposed
AppointmentProposed.new(data: { id: @id, proposed_at: @clock.call })
AppointmentProposed.new(id: @id, proposed_at: @clock.call)
end

def accept
invalid_state unless @state.proposed?
@state.to_accepted
AppointmentAccepted.new(data: { id: @id, accepted_at: @clock.call })
AppointmentAccepted.new(id: @id, accepted_at: @clock.call)
end

def reject
invalid_state unless @state.proposed?
@state.to_rejected
AppointmentRejected.new(data: { id: @id, rejected_at: @clock.call })
AppointmentRejected.new(id: @id, rejected_at: @clock.call)
end

def cancel
invalid_state unless @state.accepted? || @state.proposed?
AppointmentCancelled.new(data: { id: @id, cancelled_at: @clock.call })
AppointmentCancelled.new(id: @id, cancelled_at: @clock.call)
end

private
Expand Down
12 changes: 4 additions & 8 deletions lib/booking/day_schedule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,15 @@ def release(time_range)

def visit_scheduled(time_range)
ScheduleReserved.new(
data: {
scheduled_at: time_range.first,
duration: time_range.last - time_range.first
}
scheduled_at: time_range.first,
duration: time_range.last - time_range.first
)
end

def visit_released(time_range)
ScheduleReleased.new(
data: {
scheduled_at: time_range.first,
duration: time_range.last - time_range.first
}
scheduled_at: time_range.first,
duration: time_range.last - time_range.first
)
end

Expand Down
34 changes: 13 additions & 21 deletions test/lib/booking/appointment_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class AppointmentTest < ActiveSupport::TestCase

test "propose" do
appointment = new_appointment
assert_event appointment_proposed, appointment.propose
assert_domain_event appointment_proposed, appointment.propose
end

test "cannot propose twice" do
Expand All @@ -20,7 +20,7 @@ class AppointmentTest < ActiveSupport::TestCase
appointment = new_appointment
appointment.propose

assert_event appointment_accepted, appointment.accept
assert_domain_event appointment_accepted, appointment.accept
end

test "cannot accept without proposal" do
Expand All @@ -40,7 +40,7 @@ class AppointmentTest < ActiveSupport::TestCase
appointment = new_appointment
appointment.propose

assert_event appointment_rejected, appointment.reject
assert_domain_event appointment_rejected, appointment.reject
end

test "cannot reject without proposal" do
Expand Down Expand Up @@ -92,15 +92,15 @@ class AppointmentTest < ActiveSupport::TestCase
appointment = new_appointment
appointment.propose

assert_event appointment_cancelled, appointment.cancel
assert_domain_event appointment_cancelled, appointment.cancel
end

test "cancel accepted appointment" do
appointment = new_appointment
appointment.propose
appointment.accept

assert_event appointment_cancelled, appointment.cancel
assert_domain_event appointment_cancelled, appointment.cancel
end

test "cannot cancel rejected appointment" do
Expand Down Expand Up @@ -136,37 +136,29 @@ def new_appointment

def appointment_proposed
AppointmentProposed.new(
data: {
id: appointment_id,
proposed_at: current_time
}
id: appointment_id,
proposed_at: current_time
)
end

def appointment_accepted
AppointmentAccepted.new(
data: {
id: appointment_id,
accepted_at: current_time
}
id: appointment_id,
accepted_at: current_time
)
end

def appointment_rejected
AppointmentRejected.new(
data: {
id: appointment_id,
rejected_at: current_time
}
id: appointment_id,
rejected_at: current_time
)
end

def appointment_cancelled
AppointmentCancelled.new(
data: {
id: appointment_id,
cancelled_at: current_time
}
id: appointment_id,
cancelled_at: current_time
)
end
end
Expand Down
18 changes: 7 additions & 11 deletions test/lib/booking/day_schedule_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class DayScheduleTest < ActiveSupport::TestCase
test "happy path" do
day_schedule = DaySchedule.new(open_hours)

assert_event visit_scheduled(slot), day_schedule.reserve(slot)
assert_domain_event visit_scheduled(slot), day_schedule.reserve(slot)
end

test "cannot reserve same slot twice" do
Expand Down Expand Up @@ -41,7 +41,7 @@ class DayScheduleTest < ActiveSupport::TestCase
day_schedule = DaySchedule.new(open_hours)
day_schedule.reserve(rush_by(1.hour, slot))

assert_event visit_scheduled(slot), day_schedule.reserve(slot)
assert_domain_event visit_scheduled(slot), day_schedule.reserve(slot)
end

test "cannot reserve outside of open hours" do
Expand All @@ -54,7 +54,7 @@ class DayScheduleTest < ActiveSupport::TestCase
day_schedule = DaySchedule.new(open_hours)
day_schedule.reserve(slot)

assert_event visit_released(slot), day_schedule.release(slot)
assert_domain_event visit_released(slot), day_schedule.release(slot)
end

test "released slot can be taken again" do
Expand Down Expand Up @@ -91,19 +91,15 @@ def rush_by(seconds, slot)

def visit_scheduled(time_range)
ScheduleReserved.new(
data: {
scheduled_at: time_range.first,
duration: time_range.last - time_range.first
}
scheduled_at: time_range.first,
duration: time_range.last - time_range.first
)
end

def visit_released(time_range)
ScheduleReleased.new(
data: {
scheduled_at: time_range.first,
duration: time_range.last - time_range.first
}
scheduled_at: time_range.first,
duration: time_range.last - time_range.first
)
end
end
Expand Down
6 changes: 3 additions & 3 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ class TestCase

# Add more helper methods to be used by all tests here...

def assert_event(expected, actual)
assert_equal expected.event_type, actual.event_type
assert_equal expected.data, actual.data
def assert_domain_event(expected, actual)
assert_equal expected.class, actual.class
assert_equal expected.deconstruct_keys(nil), actual.deconstruct_keys(nil)
end
end
end

0 comments on commit f31bb0d

Please sign in to comment.