I wrote an app in Flask with Flask SQL Alchemy to book parking spots. The app doesn't allow a booking to be made in 2 cases: 1. if selected spot has already been booked for desired time, 2. if there is a reservation for given license plate in the given time. I would like to test all possible scenarios to make sure the double booking is detected but to be honest I don't know how to test POST method. Can anyone give me a hand?
from flask import Flask, render_template, request, redirect, flash
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime, timedelta
import pandas as pd
import numpy as np
app = Flask(__name__)
app.config['SESSION_TYPE'] = 'memcached'
app.config['SECRET_KEY'] = 'super secret key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///parking_booking.db'
db = SQLAlchemy(app)
time_now = datetime.now()
class Parking(db.Model):
id = db.Column(db.Integer, primary_key=True)
spot_number = db.Column(db.String(2))
license_plate = db.Column(db.String(10))
start = db.Column(db.String(20))
end = db.Column(db.String(20))
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<Parking %r>' % self.id
@app.route('/', methods=['POST', 'GET'])
def index():
df = pd.read_sql('parking', 'sqlite:///parking_booking.db')
df['start'] = pd.to_datetime(df['start'])
df['end'] = pd.to_datetime(df['end'])
print(df['start'])
if request.method == 'POST':
booking_spot_number = str(request.form['spot_number'])
booking_license_plate = str(request.form['license_plate'].replace(' ', '').upper())
booking_start = datetime(*[int(v) for v in request.form['start'].replace('T', '-').replace(':', '-').split('-')])
booking_end = datetime(*[int(v) for v in request.form['end'].replace('T', '-').replace(':', '-').split('-')])
license_plate_check = np.where((df['license_plate'] == booking_license_plate) & (((df['start'] <= booking_start) & (df['end'] >= booking_start) | ((df['end'] >= booking_end) & (df['start'] <= booking_end))) | ((booking_start <= df['start']) & (booking_end >= df['end']))))
spot_reserve_check = np.where((df['spot_number'] == booking_spot_number) & (((df['start'] <= booking_start) & (df['end'] >= booking_start) | ((df['end'] >= booking_end) & (df['start'] <= booking_end))) | ((booking_start <= df['start']) & (booking_end >= df['end']))))
print(license_plate_check)
print(spot_reserve_check)
if booking_end < booking_start:
flash('End time has to be later than start time', category='error')
elif booking_start < datetime.now():
flash('Start time can''t be in the past.', category='error')
elif (booking_end - booking_start) < timedelta(minutes=10):
flash('Minimum booking time is 10 minutes.', category='error')
elif np.size(license_plate_check) != 0:
flash(f'A car with license plate {booking_license_plate} has already booked a spot during selected time.', category='error' )
elif np.size(spot_reserve_check) != 0:
flash(f'The spot {booking_spot_number} has been booked during selected period.', category='error' )
else:
new_booking = Parking(spot_number = booking_spot_number, license_plate = booking_license_plate, start = booking_start, end = booking_end)
db.session.add(new_booking)
db.session.commit()
print(df)
flash('New booking has been added', category='success')
bookings = Parking.query.order_by(Parking.start.asc()).all()
time_now = str(datetime.now().strftime('%a %d %b %Y - %H:%M'))
free_spots = 10 - np.size(np.where((time_now >= df['start']) & (time_now <= df['end'])))
return render_template('index.html', bookings = bookings, time_now = time_now , free_spots = free_spots)