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

feat(bookings): [PPT-387] implement linked bookings child parent relationship #278

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions shard.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ shards:

eventbus:
git: https://github.com/spider-gazelle/eventbus.git
version: 0.9.9+git.commit.1f0e2524e766b10d9dc72705fa6578858e8e0b1b
version: 0.9.9+git.commit.8572cf71937680e38df4652fe886e4383b20e4f1

exception_page:
git: https://github.com/crystal-loot/exception_page.git
Expand Down Expand Up @@ -131,7 +131,7 @@ shards:

opentelemetry-instrumentation:
git: https://github.com/wyhaines/opentelemetry-instrumentation.cr.git
version: 0.5.1+git.commit.d698621cdc7722475e56e6dd8a7c07272432f270
version: 0.5.2+git.commit.327d335104d3bafd08426a0afb3755f50bafe13f

opentelemetry-sdk:
git: https://github.com/wyhaines/opentelemetry-sdk.cr.git
Expand Down Expand Up @@ -171,7 +171,7 @@ shards:

placeos-models:
git: https://github.com/placeos/models.git
version: 9.2.0
version: 9.6.0

pool:
git: https://github.com/ysbaddaden/pool.git
Expand Down
75 changes: 75 additions & 0 deletions spec/controllers/bookings_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1167,4 +1167,79 @@ describe Bookings do
body = JSON.parse(client.post("#{BOOKINGS_BASE}/#{booking.id}/check_in?state=false", headers: headers).body).as_h
body["checked_in"].should eq(false)
end

it "#create and #update parent child" do
WebMock.stub(:post, "#{ENV["PLACE_URI"]}/auth/oauth/token")
.to_return(body: File.read("./spec/fixtures/tokens/placeos_token.json"))
WebMock.stub(:post, "#{ENV["PLACE_URI"]}/api/engine/v2/signal?channel=staff/booking/changed")
.to_return(body: "")
WebMock.stub(:post, "#{ENV["PLACE_URI"]}/api/engine/v2/signal?channel=staff/guest/attending")
.to_return(body: "")

user_name = Faker::Internet.user_name
user_email = Faker::Internet.email
starting = Random.new.rand(5..19).minutes.from_now.to_unix
ending = Random.new.rand(25..39).minutes.from_now.to_unix

created = JSON.parse(client.post(BOOKINGS_BASE, headers: headers,
body: %({"asset_id":"some_desk","booking_start":#{starting},"booking_end":#{ending},"booking_type":"desk","attendees": [
{
"name": "#{user_name}",
"email": "#{user_email}",
"checked_in": true,
"visit_expected": true
}]})
).body)
created["asset_id"].should eq("some_desk")
created["booking_start"].should eq(starting)
created["booking_end"].should eq(ending)

parent_id = created["id"]

child = JSON.parse(client.post(BOOKINGS_BASE, headers: headers,
body: %({"parent_id": #{parent_id},"asset_id":"some_locker","booking_start":#{starting},"booking_end":#{ending},"booking_type":"desk","attendees": [
{
"name": "#{user_name}",
"email": "#{user_email}",
"checked_in": true,
"visit_expected": true
}]})
).body)
child["asset_id"].should eq("some_locker")
child["booking_start"].should eq(starting)
child["booking_end"].should eq(ending)
child["parent_id"].should eq(parent_id)

child_id = child["id"]

# Changing start/end time should be cascaded to children
starting = Random.new.rand(5..19).minutes.from_now.to_unix
ending = Random.new.rand(25..39).minutes.from_now.to_unix

updated = JSON.parse(client.patch("#{BOOKINGS_BASE}/#{parent_id}", headers: headers,
body: %({"asset_id":"some_desk","booking_start":#{starting},"booking_end":#{ending},"booking_type":"desk"})).body)

updated["booking_start"].should eq(starting)
updated["booking_end"].should eq(ending)
updated["linked_bookings"][0]["booking_start"].should eq(starting)
updated["linked_bookings"][0]["booking_end"].should eq(ending)

# Updating start/end on child should fail
starting = Random.new.rand(5..19).minutes.from_now.to_unix
ending = Random.new.rand(25..39).minutes.from_now.to_unix

updated = client.patch("#{BOOKINGS_BASE}/#{child_id}", headers: headers,
body: %({"asset_id":"some_locker","booking_start":#{starting},"booking_end":#{ending},"booking_type":"desk"})).status_code

updated.should eq(405)

# Deleting parent booking should delete all its children as well
deleted = client.delete("#{BOOKINGS_BASE}/#{parent_id}/", headers: headers).status_code
deleted.should eq(202)
booking = Booking.find(parent_id.as_i64)
booking.children.not_nil!.size.should be > 0
# check that it was deleted
booking.deleted.should be_true
booking.children.not_nil!.all? { |b| b.deleted == true }.should be_true
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- +micrate Up
-- SQL in section 'Up' is executed when this migration is applied
ALTER TABLE "bookings" ADD COLUMN IF NOT EXISTS parent_id bigint DEFAULT NULL;

-- +micrate Down
-- SQL section 'Down' is executed when this migration is rolled back
ALTER TABLE "bookings" DROP COLUMN IF EXISTS parent_id;
2 changes: 2 additions & 0 deletions src/controllers/bookings.cr
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ class Bookings < Application
# reset the checked-in state if asset is different, or booking times are outside the originally approved window
reset_state = existing_booking.asset_id_changed? && original_asset != existing_booking.asset_id
if existing_booking.booking_start_changed? || existing_booking.booking_end_changed?
raise Error::NotAllowed.new("editing booking times is allowed on parent bookings only.") unless existing_booking.parent?

reset_state = true if existing_booking.booking_start < original_start || existing_booking.booking_end > original_end
end

Expand Down