Skip to content

Commit

Permalink
feat(bookings): update_induction endpoint (#331)
Browse files Browse the repository at this point in the history
* test(bookings): visitor-kiosk visitor checkin flow

* test(bookings): match observed flow

* chore(shards): update shards

* test(induction): test update_induction endpoint

* feat(bookings): add update_induction endpoint

* fix(bookings): enum name

* doc(openapi): doc gen

* test(bookings): test visitor checking flow

* chore(ameba): update ameba config

* doc(bookings): lowercase example
  • Loading branch information
chillfox authored Aug 21, 2024
1 parent 1bd5edd commit 6408aa7
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 6 deletions.
23 changes: 22 additions & 1 deletion .ameba.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,25 @@ Style/PredicateName:
Enabled: false

Lint/LiteralsComparison:
Enabled: false
Enabled: false

Naming/BlockParameterName:
Enabled: false

Naming/AccessorMethodName:
Enabled: false

Naming/PredicateName:
Enabled: false

Documentation/DocumentationAdmonition:
Enabled: false

Lint/SpecFilename:
Excluded:
- spec/controllers/helpers/*
- spec/migration/**/*

Lint/UselessAssign:
Excluded:
- spec/**/*
127 changes: 125 additions & 2 deletions OPENAPI_DOC.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2375,6 +2375,119 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Bookings__BookingError'
/api/staff/v1/bookings/{id}/update_induction:
post:
summary: update the induction status
tags:
- Bookings
operationId: Bookings_update_induction
parameters:
- name: id
in: path
required: true
schema:
type: integer
format: Int64
- name: induction
in: query
description: the induction status of the booking
example: accepted
required: true
schema:
type: string
enum:
- tentative
- accepted
- declined
- name: utm_source
in: query
description: provided for use with analytics
example: mobile
required: false
schema:
type: string
nullable: true
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/PlaceOS__Model__Booking'
429:
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/Application__CommonError'
400:
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/Application__CommonError'
401:
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Application__CommonError'
403:
description: Forbidden
404:
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/Application__CommonError'
511:
description: Network Authentication Required
content:
application/json:
schema:
$ref: '#/components/schemas/Application__CommonError'
406:
description: Not Acceptable
content:
application/json:
schema:
$ref: '#/components/schemas/Application__ContentError'
415:
description: Unsupported Media Type
content:
application/json:
schema:
$ref: '#/components/schemas/Application__ContentError'
422:
description: Unprocessable Entity
content:
application/json:
schema:
$ref: '#/components/schemas/Application__ValidationError'
500:
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/Application__CommonError'
405:
description: Method Not Allowed
content:
application/json:
schema:
$ref: '#/components/schemas/Application__CommonError'
409:
description: Conflict
content:
application/json:
schema:
$ref: '#/components/schemas/Bookings__BookingError'
410:
description: Gone
content:
application/json:
schema:
$ref: '#/components/schemas/Bookings__BookingError'
/api/staff/v1/bookings/{id}/guests:
get:
summary: returns a list of guests associated with a booking
Expand Down Expand Up @@ -9651,7 +9764,12 @@ components:
type: string
nullable: true
induction:
type: boolean
type: string
enum:
- tentative
- accepted
- declined
description: The induction status of the booking. Defaults to TENTATIVE.
nullable: true
permission:
type: string
Expand Down Expand Up @@ -12073,7 +12191,12 @@ components:
type: string
nullable: true
induction:
type: boolean
type: string
enum:
- tentative
- accepted
- declined
description: The induction status of the booking. Defaults to TENTATIVE.
nullable: true
permission:
type: string
Expand Down
2 changes: 1 addition & 1 deletion shard.lock
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ shards:

placeos-models:
git: https://github.com/placeos/models.git
version: 9.56.5
version: 9.57.5

pool:
git: https://github.com/ysbaddaden/pool.git
Expand Down
42 changes: 42 additions & 0 deletions spec/controllers/bookings_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2234,4 +2234,46 @@ describe Bookings do
booking.deleted.should be_true
booking.children.not_nil!.all? { |b| b.deleted == true }.should be_true
end

context "[visitor-kiosk]", tags: ["visitor-kiosk"] do
it "checks in a visitor" 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: "")

tenant = get_tenant

starting = Random.new.rand(5..19).minutes.from_now.to_unix
ending = Random.new.rand(25..39).minutes.from_now.to_unix

visitor_email = Faker::Internet.email

# Create booking with attendee
create_booking_response = client.post(BOOKINGS_BASE, headers: headers,
body: %({"asset_id":"room_one","booking_start":#{starting},"booking_end":#{ending},"booking_type":"room","attendees": [
{
"name": "#{Faker::Name.first_name}",
"email": "#{visitor_email}",
"checked_in": false,
"visit_expected": true
}]})
)
create_booking_response.status_code.should eq(201)
booking_id = JSON.parse(create_booking_response.body)["id"]

# Find guest by email
guest_response = client.get("#{GUESTS_BASE}/#{visitor_email}", headers: headers)
guest_response.status_code.should eq(200)
guest_id = JSON.parse(guest_response.body)["id"]

# update induction state on booking
update_induction_response = client.post("#{BOOKINGS_BASE}/#{booking_id}/update_induction?induction=accepted", headers: headers)
update_induction_response.status_code.should eq(200)
booking = Booking.from_json(update_induction_response.body)
booking.induction.should eq(PlaceOS::Model::Booking::Induction::ACCEPTED)
end
end
end
17 changes: 15 additions & 2 deletions src/controllers/bookings.cr
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Bookings < Application
.limit(1).to_a.first { raise Error::NotFound.new("could not find booking with id: #{id}") }
end

@[AC::Route::Filter(:before_action, only: [:update, :update_alt, :destroy, :update_state])]
@[AC::Route::Filter(:before_action, only: [:update, :update_alt, :destroy, :update_state, :update_induction])]
private def confirm_access
return if is_support?
if user = current_user
Expand Down Expand Up @@ -515,7 +515,7 @@ class Bookings < Application
original_assets = existing_booking.asset_ids
existing_booking.instance = instance

{% for key in [:asset_id, :asset_ids, :zones, :booking_start, :booking_end, :title, :description, :images] %}
{% for key in [:asset_id, :asset_ids, :zones, :booking_start, :booking_end, :title, :description, :images, :induction] %}
begin
existing_booking.{{key.id}} = changes.{{key.id}} if changes.{{key.id}}_present?
rescue NilAssertionError
Expand Down Expand Up @@ -807,6 +807,19 @@ class Bookings < Application
update_booking(booking, "process_state")
end

# update the induction status
@[AC::Route::POST("/:id/update_induction")]
def update_induction(
@[AC::Param::Info(description: "the induction status of the booking", example: "accepted")]
induction : PlaceOS::Model::Booking::Induction,
@[AC::Param::Info(description: "provided for use with analytics", example: "mobile")]
utm_source : String? = nil
) : Booking
booking.induction = induction
booking.utm_source = utm_source
update_booking(booking, "induction")
end

# returns a list of guests associated with a booking
@[AC::Route::GET("/:id/guests")]
def guest_list : Array(Guest)
Expand Down

0 comments on commit 6408aa7

Please sign in to comment.