def test_get_a_table(self): """ Try get a table utils """ now = datetime.datetime.now() with self.app.app_context(): booking = (now.replace(hour=13) + datetime.timedelta(days=1)) r = get_a_table(3, 1, booking) self.assertEqual(r, 6, msg=r) # expected table 6 r = get_a_table(3, 4, booking) self.assertEqual(r, 5, msg=r) # expected table 5 r = get_a_table(3, 5, booking) self.assertEqual(r, -1, msg=r) # expected table no table (no free tables with such capacity)
def new_booking(): """ Add a new booking. POST /bookings Returns the booking if it can be made, otherwise returns an error message. Requires a json object with: - number_of_people: the number of people for the booking - booking_datetime: the datetime of the booking - user_id: the id of the user who made the booking - restaurant_id: the id of the restaurant Status Codes: 201 - The booking has been created 400 - Wrong datetime 409 - Impossible to change the booking (it is full, it is closed ...) 500 - Error in communicating with the restaurant service or problem with the database (try again) """ req = request.json try: req["booking_datetime"] = dateutil.parser.parse( req["booking_datetime"]) except: return Error400("booking_datetime is not a valid datetime").get() timezone = req["booking_datetime"].tzinfo now = datetime.datetime.now(timezone) #timezone aware computation if req["booking_datetime"] <= now: return Error400("booking_datetime must be in the future").get() # try to get a table in the restaurant for the booking table = get_a_table(req["restaurant_id"], req["number_of_people"], req["booking_datetime"]) if table is None: # an error occured (problem during the connection with the restaurant's microservice) return Error500().get() elif table == -1: # The restaurant does not accept the booking because there are no free tables return Error( "about:blank", "Conflict", 409, "We are sorry! It is not possible to make the booking: there are no free tables!" ).get() elif table == -2: # The restaurant does not accept the booking because it is closed return Error( "about:blank", "Conflict", 409, "We are sorry! It is not possible to make the booking: the restaurant is closed on that datetime!" ).get() booking = add_booking(req["user_id"], req["restaurant_id"], req["number_of_people"], req["booking_datetime"], table) if booking is None: # DB error return Error500().get() booking, status_code = get_booking(booking) if status_code == 200: return booking, 201 else: # unexpected error return Error500().get()
def test_get_a_table_failure(self): """ Try get a table utils without mocks """ now = datetime.datetime.now() app = create_app("FAILURE_TEST") # Test without mocks (FAILURE_TEST is configuration in config.ini that disable mocks but maintains fake data) app = app.app app.config['TESTING'] = True with app.app_context(): booking = (now.replace(hour=13) + datetime.timedelta(days=1)) r = get_a_table(3, 1, booking) self.assertEqual(r, None, msg=r) # expected None in case of connections problems r = get_a_table(3, 4, booking) self.assertEqual(r, None, msg=r) # expected None in case of connections problems r = get_a_table(3, 5, booking) self.assertEqual(r, None, msg=r) # expected None in case of connections problems
def test_get_table_restaurant_closed(self): """ Try to get a free table in a closed restaurant with mocks """ now = datetime.datetime.now() booking = now.replace( year=2020, month=11, day=17, hour=11, minute=30, second=0, microsecond=0) with self.app.app_context(): r = get_a_table(1, 1, booking) self.assertEqual(r, -2) # -2 in case that the restaurant is closed booking = now.replace( year=2020, month=11, day=17, hour=23, minute=0, second=0, microsecond=0 ) for i in [1,2]: r = get_a_table(i, 1, booking) self.assertEqual(r, -2, msg=i) # -2 in case that the restaurant is closed booking = now.replace( year=2020, month=11, day=16, hour=23, minute=0, second=0, microsecond=0 ) for i in [1,2]: r = get_a_table(i, 1, booking) self.assertEqual(r, -2, msg=i) # -2 in case that the restaurant is closed
def test_get_table_restaurant_closed_failure(self): """ Try get a table utils without mocks """ app = create_app("FAILURE_TEST") # Test without mocks (FAILURE_TEST is configuration in config.ini that disable mocks but maintains fake data) app = app.app app.config['TESTING'] = True now = datetime.datetime.now() booking = now.replace( year=2020, month=11, day=17, hour=11, minute=30, second=0, microsecond=0) with app.app_context(): for i in [1,2,3,4]: r = get_a_table(i, 1, booking) self.assertEqual(r, None, msg=i) # expected None in case of connections problems
def put_booking(booking_id, entrance=False): """ Edit a booking. GET /bookings/{booking_id}?[entrance=true/false] Changes the number of people and/or the date of the booking. Or marks the user's entry. The request to mark the entrance is made through the query parameter entrance (a boolean) Change requests are made through json objects with the following properties (both optional) - booking_datetime: the new requested datetime - number_of_people: the new requested number of people If one of the two fields is not set, the one already entered is recovered. If both are not entered the request is void (unless required to mark the entry()in this case the json is ignored). If entry is marked, other requests for changes are ignored (if the user has already entered the changes no longer make sense). Likewise, if the entry is marked, no more changes can be made. The booking must not have already passed, in the event of a change. Change of a booking may not always be possible (on the requested date there are no seats available, the restaurant is closed on that date ...) Status Codes: 200 - OK 400 - Wrong datetime or bad request (entry already marked) 404 - Booking not found 409 - Impossible to change the booking 500 - Error in communicating with the restaurant service or problem with the database (try again) """ q = db.session.query(Booking).filter_by(id=booking_id).first() if q is None: return Error404("Booking not found").get() q = q.dump() if entrance: if q["entrance_datetime"] is not None: return Error400( "Entrance has already been marked for this booking").get() now = datetime.datetime.now() booking = update_booking(q["id"], q["number_of_people"], q["booking_datetime"], q["table_id"], now) if booking is None: # DB error return Error500().get() booking, status_code = get_booking(booking) if status_code == 200: return booking, 200 else: # unexpected error return Error500().get() if q["entrance_datetime"] is not None: return Error400( "The entry has already been marked, the reservation can no longer be changed" ).get() now = datetime.datetime.now() if q["booking_datetime"] < now: return Error400("You cannot change a past booking").get() req = request.json if "booking_datetime" in req and req["booking_datetime"] is not None: try: req["booking_datetime"] = dateutil.parser.parse( req["booking_datetime"]) except: return Error400("booking_datetime is not a valid datetime").get() else: # use the "old" datetime req["booking_datetime"] = q["booking_datetime"] timezone = req["booking_datetime"].tzinfo now = datetime.datetime.now(timezone) if req["booking_datetime"] <= now: return Error400("booking_datetime must be in the future").get() if "number_of_people" not in req or req["number_of_people"] is None: req["number_of_people"] = q["number_of_people"] if (q["booking_datetime"] != req["booking_datetime"]) or ( q["number_of_people"] != req["number_of_people"]): table = get_a_table(q["restaurant_id"], req["number_of_people"], req["booking_datetime"], excluded=booking_id) # try to get a table if table is None: # an error occured (problem during the connection with the restaurant's microservice) return Error500().get() elif table == -1: # The restaurant does not accept the changes because there are no free tables return Error( "about:blank", "Conflict", 409, "We are sorry! It is not possible to change the booking: there are no free tables!" ).get() elif table == -2: # The restaurant does not accept the changes because it is closed return Error( "about:blank", "Conflict", 409, "We are sorry! It is not possible to change the booking: the restaurant is closed on that datetime!" ).get() booking = update_booking(q["id"], req["number_of_people"], req["booking_datetime"], table) if booking is None: # DB error return Error500().get() booking, status_code = get_booking(booking) if status_code == 200: return booking, 200 else: # unexpected error return Error500().get() return Error400("No changes were requested").get()