kopia lustrzana https://github.com/jprochazka/adsb-receiver
Begun adding tests.
rodzic
f2ae197d7a
commit
ebe3ae8a13
|
|
@ -1,4 +1,6 @@
|
|||
.vscode
|
||||
.venv
|
||||
__pycache__
|
||||
instance
|
||||
instance
|
||||
.coverage
|
||||
htmlcov
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import os
|
||||
|
||||
from datetime import timedelta
|
||||
from flask import Flask, render_template
|
||||
from flask_apscheduler import APScheduler
|
||||
|
|
@ -13,8 +15,19 @@ from backend.routes.settings import settings
|
|||
from backend.routes.tokens import tokens
|
||||
from backend.routes.users import users
|
||||
|
||||
def create_app():
|
||||
def create_app(test_config=None):
|
||||
app = Flask(__name__)
|
||||
|
||||
if test_config is None:
|
||||
app.config.from_pyfile('config.py', silent=True)
|
||||
else:
|
||||
app.config.from_mapping(test_config)
|
||||
|
||||
try:
|
||||
os.makedirs(app.instance_path)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
app.json.sort_keys = False
|
||||
|
||||
app.config["JWT_SECRET_KEY"] = "CHANGE_THIS_IN_PRODUCTION" # Change this!
|
||||
|
|
|
|||
|
|
@ -1,47 +1,54 @@
|
|||
import click
|
||||
import MySQLdb
|
||||
import os
|
||||
import psycopg2
|
||||
import sqlite3
|
||||
import yaml
|
||||
|
||||
from flask import current_app, g
|
||||
|
||||
config=yaml.safe_load(open("config.yml"))
|
||||
|
||||
|
||||
def create_connection():
|
||||
match config['database']['use'].lower():
|
||||
case 'mysql':
|
||||
return MySQLdb.connect(
|
||||
host=config['database']['mysql']['host'],
|
||||
user=config['database']['mysql']['user'],
|
||||
password=config['database']['mysql']['password'],
|
||||
database=config['database']['mysql']['database']
|
||||
)
|
||||
case 'postgresql':
|
||||
return psycopg2.connect(
|
||||
host=config['database']['mysql']['host'],
|
||||
user=config['database']['mysql']['user'],
|
||||
password=config['database']['mysql']['password'],
|
||||
database=config['database']['mysql']['database']
|
||||
)
|
||||
case 'sqlite':
|
||||
return sqlite3.connect(config['database']['sqlite']['path'])
|
||||
|
||||
|
||||
def init_app(app):
|
||||
app.teardown_appcontext(close_db)
|
||||
app.cli.add_command(init_db_command)
|
||||
|
||||
def get_db():
|
||||
if 'db' not in g:
|
||||
match config['database']['use'].lower():
|
||||
case 'mysql':
|
||||
g.db = MySQLdb.connect(
|
||||
host=config['database']['mysql']['host'],
|
||||
user=config['database']['mysql']['user'],
|
||||
password=config['database']['mysql']['password'],
|
||||
database=config['database']['mysql']['database']
|
||||
)
|
||||
case 'postgresql':
|
||||
g.db = psycopg2.connect(
|
||||
host=config['database']['mysql']['host'],
|
||||
user=config['database']['mysql']['user'],
|
||||
password=config['database']['mysql']['password'],
|
||||
database=config['database']['mysql']['database']
|
||||
)
|
||||
case 'sqlite':
|
||||
g.db = sqlite3.connect(os.path.join(current_app.instance_path, 'adsbportal.sqlite3'))
|
||||
|
||||
return g.db
|
||||
|
||||
def close_db(e=None):
|
||||
db = g.pop('db', None)
|
||||
|
||||
if db is not None:
|
||||
db.close()
|
||||
|
||||
def init_db():
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db = get_db()
|
||||
|
||||
sql_file = open(f"./backend/schemas/{config['database']['use'].lower()}.sql", "r")
|
||||
sql_script = sql_file.read()
|
||||
cursor.executescript(sql_script)
|
||||
|
||||
connection.commit()
|
||||
connection.close()
|
||||
sql_file = os.path.join("schemas", f"{config['database']['use'].lower()}.sql")
|
||||
with current_app.open_resource(sql_file, "r") as f:
|
||||
db.executescript(f.read())
|
||||
|
||||
@click.command('init-db')
|
||||
def init_db_command():
|
||||
init_db()
|
||||
click.echo('Database inititalized')
|
||||
click.echo('Database initialized')
|
||||
|
|
@ -4,11 +4,11 @@ import logging
|
|||
from datetime import datetime
|
||||
from flask_apscheduler import APScheduler
|
||||
from urllib.request import urlopen
|
||||
from backend.db import create_connection
|
||||
from backend.db import get_db
|
||||
|
||||
scheduler = APScheduler()
|
||||
connection = None
|
||||
cursor = None
|
||||
db = None
|
||||
now = None
|
||||
|
||||
class DataProcessor(object):
|
||||
|
|
@ -42,8 +42,8 @@ class DataProcessor(object):
|
|||
for aircraft in aircraft_data:
|
||||
self.process_aircraft(aircraft)
|
||||
|
||||
connection.close()
|
||||
|
||||
db.commit()
|
||||
|
||||
return
|
||||
|
||||
# Process the aircraft
|
||||
|
|
@ -66,7 +66,6 @@ class DataProcessor(object):
|
|||
"UPDATE adsb_aircraft SET last_seen = %s WHERE icao = %s",
|
||||
(now, aircraft["hex"])
|
||||
)
|
||||
connection.commit()
|
||||
cursor.execute(
|
||||
"SELECT id FROM adsb_aircraft WHERE icao = %s",
|
||||
(aircraft["hex"],)
|
||||
|
|
@ -82,7 +81,6 @@ class DataProcessor(object):
|
|||
"INSERT INTO adsb_aircraft (icao, firstSeen, last_seen) VALUES (%s, %s, %s)",
|
||||
(aircraft["hex"], now, now)
|
||||
)
|
||||
connection.commit()
|
||||
aircraft_id = cursor.lastrowid
|
||||
except Exception as ex:
|
||||
logging.error(f'Error encountered while trying to insert aircraft {aircraft["hex"]}', exc_info=ex)
|
||||
|
|
@ -116,7 +114,6 @@ class DataProcessor(object):
|
|||
"UPDATE adsb_flights SET last_seen = %s WHERE flight = %s",
|
||||
(now, flight)
|
||||
)
|
||||
connection.commit()
|
||||
cursor.execute(
|
||||
"SELECT id FROM adsb_flights WHERE flight = %s",
|
||||
(flight,)
|
||||
|
|
@ -132,7 +129,6 @@ class DataProcessor(object):
|
|||
"INSERT INTO adsb_flights (aircraft, flight, firstSeen, last_seen) VALUES (%s, %s, %s, %s)",
|
||||
(aircraft_id, flight, now, now)
|
||||
)
|
||||
connection.commit()
|
||||
flight_id = cursor.lastrowid
|
||||
except Exception as ex:
|
||||
logging.error(f'Error encountered while trying to insert flight {flight}', exc_info=ex)
|
||||
|
|
@ -180,7 +176,6 @@ class DataProcessor(object):
|
|||
"INSERT INTO adsb_positions (flight, time, message, squawk, latitude, longitude, track, altitude, verticleRate, speed, aircraft) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
|
||||
(flight_id, now, aircraft["messages"], squawk, aircraft["lat"], aircraft["lon"], aircraft["track"], altitude, aircraft["geom_rate"], aircraft["gs"], aircraft_id)
|
||||
)
|
||||
connection.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f'Error encountered while inserting position data for message ID {aircraft["messages"]} related to flight {flight_id}', exc_info=ex)
|
||||
return
|
||||
|
|
@ -195,8 +190,8 @@ def data_collection_job():
|
|||
|
||||
# Setup and begin the data collection job
|
||||
processor.log("-- BEGINING FLIGHT RECORDER JOB")
|
||||
connection = create_connection()
|
||||
cursor = connection.cursor()
|
||||
now = datetime.now()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
now=datetime.now()
|
||||
processor.process_all_aircraft()
|
||||
processor.log("-- FLIGHT RECORD JOB COMPLETE")
|
||||
|
|
@ -2,11 +2,11 @@ import logging
|
|||
|
||||
from datetime import datetime, timedelta
|
||||
from flask_apscheduler import APScheduler
|
||||
from backend.db import create_connection
|
||||
from backend.db import get_db
|
||||
|
||||
scheduler = APScheduler()
|
||||
connection = None
|
||||
cursor = None
|
||||
db = None
|
||||
now = None
|
||||
|
||||
class MaintenanceProcessor(object):
|
||||
|
|
@ -39,14 +39,11 @@ class MaintenanceProcessor(object):
|
|||
cutoff_date = datetime.now() - timedelta(days = days_to_save)
|
||||
self.purge_aircraft(cutoff_date)
|
||||
self.purge_positions(cutoff_date)
|
||||
db.commit()
|
||||
|
||||
else:
|
||||
self.log("Maintenance is disabled")
|
||||
|
||||
connection.commit()
|
||||
|
||||
connection.close()
|
||||
|
||||
return
|
||||
|
||||
# Remove aircraft not seen since the specified date
|
||||
|
|
@ -141,7 +138,7 @@ def maintenance_job():
|
|||
|
||||
# Setup and begin the maintenance job
|
||||
processor.log("-- BEGINING PORTAL MAINTENANCE JOB")
|
||||
connection = create_connection()
|
||||
cursor = connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
processor.begin_maintenance()
|
||||
processor.log("-- PORTAL MAINTENANCE JOB COMPLETE")
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import logging
|
||||
|
||||
from flask import abort, Blueprint, jsonify, request
|
||||
from flask_jwt_extended import jwt_required
|
||||
from backend.db import create_connection
|
||||
from backend.db import get_db
|
||||
|
||||
aircraft = Blueprint('aircraft', __name__)
|
||||
|
||||
|
|
@ -12,9 +11,12 @@ def get_aircraft_by_icao(icao):
|
|||
data=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
cursor.execute("SELECT * FROM aircraft WHERE icao = %s", (icao,))
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
|
||||
cursor.execute("SELECT * FROM aircraft WHERE icao = ?", (icao,))
|
||||
#cursor.execute("SELECT * FROM aircraft WHERE icao = %s", (icao,))
|
||||
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
for result in result:
|
||||
|
|
@ -22,8 +24,6 @@ def get_aircraft_by_icao(icao):
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get aircraft using ICAO {icao}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
if not data:
|
||||
abort(404, description="Not Found")
|
||||
|
|
@ -40,11 +40,23 @@ def get_aircraft_positions(icao):
|
|||
positions=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
cursor.execute("SELECT id FROM aircraft WHERE icao = %s", (icao,))
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
|
||||
cursor.execute("SELECT COUNT(*) FROM aircraft WHERE icao = ?", (icao,))
|
||||
#cursor.execute("SELECT COUNT(*) FROM aircraft WHERE icao = %s", (icao,))
|
||||
|
||||
if cursor.fetchone()[0] == 0:
|
||||
return "Not Found", 404
|
||||
|
||||
cursor.execute("SELECT id FROM aircraft WHERE icao = ?", (icao,))
|
||||
#cursor.execute("SELECT id FROM aircraft WHERE icao = %s", (icao,))
|
||||
|
||||
aircraft_id = cursor.fetchone()[0]
|
||||
cursor.execute("SELECT * FROM positions WHERE aircraft = %s ORDER BY time LIMIT %s, %s", (aircraft_id, offset, limit))
|
||||
|
||||
cursor.execute("SELECT * FROM positions WHERE aircraft = ? ORDER BY time LIMIT ?, ?", (aircraft_id, offset, limit))
|
||||
#cursor.execute("SELECT * FROM positions WHERE aircraft = %s ORDER BY time LIMIT %s, %s", (aircraft_id, offset, limit))
|
||||
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
for result in result:
|
||||
|
|
@ -52,8 +64,6 @@ def get_aircraft_positions(icao):
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get flight positions for aircraft ICAO {icao}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
|
|
@ -67,15 +77,19 @@ def get_aircraft_positions(icao):
|
|||
def get_aircraft():
|
||||
offset = request.args.get('offset', default=0, type=int)
|
||||
limit = request.args.get('limit', default=50, type=int)
|
||||
|
||||
if offset < 0 or limit < 1 or limit > 100:
|
||||
abort(400, description="Bad Request")
|
||||
|
||||
|
||||
aircraft_data=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
cursor.execute("SELECT * FROM aircraft ORDER BY last_seen DESC, icao LIMIT %s, %s", (offset, limit))
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
|
||||
cursor.execute("SELECT * FROM aircraft ORDER BY last_seen DESC, icao LIMIT ?, ?", (offset, limit))
|
||||
#cursor.execute("SELECT * FROM aircraft ORDER BY last_seen DESC, icao LIMIT %s, %s", (offset, limit))
|
||||
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
for result in result:
|
||||
|
|
@ -83,8 +97,6 @@ def get_aircraft():
|
|||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to get aircraft', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
|
|
@ -99,15 +111,13 @@ def get_aircraft():
|
|||
@aircraft.route('/api/aircraft/count', methods=['GET'])
|
||||
def get_aircraft_count():
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM aircraft")
|
||||
count=cursor.fetchone()[0]
|
||||
count = cursor.fetchone()[0]
|
||||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to get aircraft count', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
response = jsonify(aircraft=count)
|
||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from datetime import datetime
|
|||
from flask import abort, Blueprint, jsonify, request
|
||||
from flask_jwt_extended import jwt_required
|
||||
from marshmallow import Schema, fields, ValidationError
|
||||
from backend.db import create_connection
|
||||
from backend.db import get_db
|
||||
|
||||
blog = Blueprint('blog', __name__)
|
||||
|
||||
|
|
@ -28,18 +28,16 @@ def post_blog_post():
|
|||
return jsonify(err.messages), 400
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute(
|
||||
"INSERT INTO blog_posts (date, title, author, content) VALUES (%s, %s, %s, %s)",
|
||||
(datetime.now(), payload['title'], payload['author'], payload['content'])
|
||||
)
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to add post blog post', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "Created", 201
|
||||
|
||||
|
|
@ -47,19 +45,17 @@ def post_blog_post():
|
|||
@jwt_required()
|
||||
def delete_blog_post(blog_post_id):
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM blog_posts WHERE id = %s", (blog_post_id,))
|
||||
if cursor.fetchone()[0] == 0:
|
||||
return "Not Found", 404
|
||||
else:
|
||||
cursor.execute("DELETE FROM blog_posts WHERE id = %s", (blog_post_id,))
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to delete blog post id {blog_post_id}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "No Content", 204
|
||||
|
||||
|
|
@ -68,8 +64,8 @@ def get_blog_post(blog_post_id):
|
|||
data=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM blog_posts WHERE id = %s", (blog_post_id,))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
results = cursor.fetchall()
|
||||
|
|
@ -78,8 +74,6 @@ def get_blog_post(blog_post_id):
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get blog post id {blog_post_id,}", blog_post_id, exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
if not data:
|
||||
abort(404, description="Not Found")
|
||||
|
|
@ -97,8 +91,8 @@ def put_blog_post(blog_post_id):
|
|||
return jsonify(err.messages), 400
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM blog_posts WHERE id = %s", (blog_post_id,))
|
||||
if cursor.fetchone()[0] == 0:
|
||||
return "Not Found", 404
|
||||
|
|
@ -107,12 +101,10 @@ def put_blog_post(blog_post_id):
|
|||
"UPDATE blog_posts SET date = %s, title = %s, content = %s WHERE id = %s",
|
||||
(datetime.now(), payload['title'], payload['content'], blog_post_id)
|
||||
)
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to put blog post id {blog_post_id}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "No Content", 204
|
||||
|
||||
|
|
@ -126,8 +118,8 @@ def get_blog_posts():
|
|||
blog_posts=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM blog_posts ORDER BY date DESC LIMIT %s, %s", (offset, limit))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
|
|
@ -136,8 +128,6 @@ def get_blog_posts():
|
|||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to get blog posts', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import logging
|
|||
|
||||
from flask import abort, Blueprint, jsonify, request
|
||||
from flask_jwt_extended import jwt_required
|
||||
from backend.db import create_connection
|
||||
from backend.db import get_db
|
||||
|
||||
flights = Blueprint('flights', __name__)
|
||||
|
||||
|
|
@ -12,8 +12,8 @@ def get_flight(flight):
|
|||
data=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM flights WHERE flight = %s", (flight,))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
|
|
@ -22,8 +22,6 @@ def get_flight(flight):
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get flight {flight}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
if not data:
|
||||
abort(404, description="Not Found")
|
||||
|
|
@ -40,8 +38,8 @@ def get_flight_positions(flight):
|
|||
positions=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM positions WHERE flight = %s ORDER BY time LIMIT %s, %s", (flight, offset, limit))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
|
|
@ -50,8 +48,6 @@ def get_flight_positions(flight):
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get flight positions for flight {flight}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
|
|
@ -71,8 +67,8 @@ def get_flights():
|
|||
flights=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM flights ORDER BY last_seen DESC, flight LIMIT %s, %s", (offset, limit))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
|
|
@ -81,8 +77,6 @@ def get_flights():
|
|||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to get flights', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
|
|
@ -97,15 +91,13 @@ def get_flights():
|
|||
@flights.route('/api/flights/count', methods=['GET'])
|
||||
def get_flights_count():
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM flights")
|
||||
count=cursor.fetchone()[0]
|
||||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to get flight count', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
response = jsonify(flights=count)
|
||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import logging
|
|||
from flask import abort, Blueprint, jsonify, request
|
||||
from flask_jwt_extended import jwt_required
|
||||
from marshmallow import Schema, fields, ValidationError
|
||||
from backend.db import create_connection
|
||||
from backend.db import get_db
|
||||
|
||||
links = Blueprint('links', __name__)
|
||||
|
||||
|
|
@ -26,18 +26,16 @@ def post_link():
|
|||
return jsonify(err.messages), 400
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute(
|
||||
"INSERT INTO links (name, address) VALUES (%s, %s)",
|
||||
(payload['name'], payload['address'])
|
||||
)
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to post link", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "Created", 201
|
||||
|
||||
|
|
@ -45,19 +43,17 @@ def post_link():
|
|||
@jwt_required()
|
||||
def delete_link(link_id):
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM links WHERE id = %s", (link_id,))
|
||||
if cursor.fetchone()[0] == 0:
|
||||
return "Not Found", 404
|
||||
else:
|
||||
cursor.execute("DELETE FROM links WHERE id = %s", (link_id,))
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to delete link id {link_id}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "No Content", 204
|
||||
|
||||
|
|
@ -67,8 +63,8 @@ def get_link(link_id):
|
|||
data=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM links WHERE id = %s", (link_id,))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
results = cursor.fetchall()
|
||||
|
|
@ -77,8 +73,6 @@ def get_link(link_id):
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get link id {link_id}", link_id, exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
if not data:
|
||||
abort(404, description="Not Found")
|
||||
|
|
@ -97,8 +91,8 @@ def put_link(id):
|
|||
return jsonify(err.messages), 400
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM links WHERE id = %s", (id))
|
||||
if cursor.fetchone()[0] == 0:
|
||||
abort(404, description="Not Found")
|
||||
|
|
@ -107,11 +101,10 @@ def put_link(id):
|
|||
"UPDATE links SET name = %s, address = %s WHERE id = %s",
|
||||
(payload_object['name'], payload_object['address'], id)
|
||||
)
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to put link id {id}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "No Content", 204
|
||||
|
||||
|
|
@ -125,8 +118,8 @@ def get_links():
|
|||
links=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM links ORDER BY name LIMIT %s, %s", (offset, limit))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
|
|
@ -135,8 +128,6 @@ def get_links():
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get links", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import logging
|
|||
|
||||
from flask import abort, Blueprint, jsonify, request
|
||||
from flask_jwt_extended import jwt_required
|
||||
from backend.db import create_connection
|
||||
from backend.db import get_db
|
||||
|
||||
notifications = Blueprint('notifications', __name__)
|
||||
|
||||
|
|
@ -11,19 +11,17 @@ notifications = Blueprint('notifications', __name__)
|
|||
@jwt_required()
|
||||
def delete_notification(flight):
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM notifications WHERE flight = %s", (flight,))
|
||||
if cursor.fetchone()[0] == 0:
|
||||
return "Not Found", 404
|
||||
else:
|
||||
cursor.execute("DELETE FROM notifications WHERE flight = %s", (flight,))
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to delete blog post id {flight}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "No Content", 204
|
||||
|
||||
|
|
@ -31,8 +29,8 @@ def delete_notification(flight):
|
|||
@jwt_required()
|
||||
def post_notification(flight):
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM notifications WHERE flight = %s", (flight,))
|
||||
if cursor.fetchone()[0] > 0:
|
||||
return "Bad Request", 400
|
||||
|
|
@ -41,12 +39,10 @@ def post_notification(flight):
|
|||
"INSERT INTO notifications (flight) VALUES (%s)",
|
||||
(flight,)
|
||||
)
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to add notification', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "Created", 201
|
||||
|
||||
|
|
@ -61,8 +57,8 @@ def get_notifications():
|
|||
notifications=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM notifications ORDER BY flight LIMIT %s, %s", (offset, limit))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
|
|
@ -71,8 +67,6 @@ def get_notifications():
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get notifications", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import logging
|
|||
from flask import abort, Blueprint, jsonify, request
|
||||
from flask_jwt_extended import jwt_required
|
||||
from marshmallow import Schema, fields, ValidationError
|
||||
from backend.db import create_connection
|
||||
from backend.db import get_db
|
||||
|
||||
settings = Blueprint('settings', __name__)
|
||||
|
||||
|
|
@ -22,8 +22,8 @@ def put_setting():
|
|||
return jsonify(err.messages), 400
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM settings WHERE name = %s", (payload['name'],))
|
||||
if cursor.fetchone()[0] == 0:
|
||||
abort(404, description="Not Found")
|
||||
|
|
@ -32,12 +32,10 @@ def put_setting():
|
|||
"UPDATE settings SET value = %s WHERE name = %s",
|
||||
(payload['value'], payload['name'])
|
||||
)
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to put setting named {payload['name']}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "No Content", 204
|
||||
|
||||
|
|
@ -47,8 +45,8 @@ def get_setting(name):
|
|||
data=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM settings WHERE name = %s", (name,))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
results = cursor.fetchall()
|
||||
|
|
@ -57,8 +55,6 @@ def get_setting(name):
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get setting named {name}", id, exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
if not data:
|
||||
abort(404, description="Not Found")
|
||||
|
|
@ -71,8 +67,8 @@ def get_settings():
|
|||
settings=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM settings ORDER BY name")
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
|
|
@ -81,7 +77,5 @@ def get_settings():
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get settings", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return jsonify(settings), 200
|
||||
|
|
@ -3,7 +3,7 @@ import logging
|
|||
from flask import abort, Blueprint, jsonify, request
|
||||
from flask_jwt_extended import jwt_required
|
||||
from marshmallow import Schema, fields, ValidationError
|
||||
from backend.db import create_connection
|
||||
from backend.db import get_db
|
||||
|
||||
users = Blueprint('users', __name__)
|
||||
|
||||
|
|
@ -29,18 +29,16 @@ def post_user():
|
|||
return jsonify(err.messages), 400
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute(
|
||||
"INSERT INTO users (name, email, password, administrator) VALUES (%s, %s, %s, %s)",
|
||||
(payload['name'], payload['email'], payload['password'], payload['administrator'])
|
||||
)
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to post user', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "Created", 201
|
||||
|
||||
|
|
@ -48,19 +46,17 @@ def post_user():
|
|||
@jwt_required()
|
||||
def delete_user(email):
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM users WHERE email = %s", (email,))
|
||||
if cursor.fetchone()[0] == 0:
|
||||
return "Not Found", 404
|
||||
else:
|
||||
cursor.execute("DELETE FROM users WHERE email = %s", (email,))
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to delete user related to email {email}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "No Content", 204
|
||||
|
||||
|
|
@ -70,8 +66,8 @@ def get_user(email):
|
|||
data=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
results = cursor.fetchall()
|
||||
|
|
@ -80,8 +76,6 @@ def get_user(email):
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get user related to email {email,}", email, exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
if not data:
|
||||
abort(404, description="Not Found")
|
||||
|
|
@ -97,8 +91,8 @@ def put_user(email):
|
|||
return jsonify(err.messages), 400
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM users WHERE email = %s", (email,))
|
||||
if cursor.fetchone()[0] == 0:
|
||||
return "Not Found", 404
|
||||
|
|
@ -107,12 +101,10 @@ def put_user(email):
|
|||
"UPDATE users SET name = %s, password = %s, administrator = %s WHERE email = %s",
|
||||
(payload['name'], payload['password'], payload['administrator'], email)
|
||||
)
|
||||
connection.commit()
|
||||
db.commit()
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to put user related to email {email}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
return "No Content", 204
|
||||
|
||||
|
|
@ -127,8 +119,8 @@ def get_users():
|
|||
users=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
db=get_db()
|
||||
cursor=db.cursor()
|
||||
cursor.execute("SELECT * FROM users ORDER BY name LIMIT %s, %s", (offset, limit))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
|
|
@ -137,8 +129,6 @@ def get_users():
|
|||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get users", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
|
|
|
|||
|
|
@ -7,16 +7,6 @@ DROP TABLE IF EXISTS links;
|
|||
DROP TABLE IF EXISTS positions;
|
||||
DROP TABLE IF EXISTS settings;
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`email` varchar(75) NOT NULL,
|
||||
`login` varchar(25) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`administrator` bit DEFAULT 0,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `aircraft` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`icao` varchar(24) NOT NULL,
|
||||
|
|
@ -80,4 +70,14 @@ CREATE TABLE `settings` (
|
|||
`name` varchar(50) NOT NULL,
|
||||
`value` varchar(100) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`email` varchar(75) NOT NULL,
|
||||
`login` varchar(25) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`administrator` bit DEFAULT 0,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
|
@ -7,16 +7,6 @@ DROP TABLE IF EXISTS links;
|
|||
DROP TABLE IF EXISTS positions;
|
||||
DROP TABLE IF EXISTS settings;
|
||||
|
||||
CREATE TABLE users (
|
||||
`id` int NOT NULL GENERATED ALWAYS AS IDENTITY,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`email` varchar(75) NOT NULL,
|
||||
`login` varchar(25) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`administrator` bit DEFAULT 0,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE aircraft (
|
||||
`id` int NOT NULL GENERATED ALWAYS AS IDENTITY,
|
||||
`icao` varchar(24) NOT NULL,
|
||||
|
|
@ -66,7 +56,7 @@ CREATE TABLE positions (
|
|||
`squawk` int DEFAULT NULL,
|
||||
`latitude` double precision NOT NULL,
|
||||
`longitude` double precision NOT NULL,
|
||||
`track int` NOT NULL,
|
||||
`track` int NOT NULL,
|
||||
`altitude` int NOT NULL,
|
||||
`verticle_rate` int NOT NULL,
|
||||
`speed` int DEFAULT NULL,
|
||||
|
|
@ -80,4 +70,14 @@ CREATE TABLE settings (
|
|||
`name` varchar(50) NOT NULL,
|
||||
`value` varchar(100) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
`id` int NOT NULL GENERATED ALWAYS AS IDENTITY,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`email` varchar(75) NOT NULL,
|
||||
`login` varchar(25) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`administrator` bit DEFAULT 0,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
|
@ -7,19 +7,11 @@ DROP TABLE IF EXISTS links;
|
|||
DROP TABLE IF EXISTS positions;
|
||||
DROP TABLE IF EXISTS settings;
|
||||
|
||||
CREATE TABLE users (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` TEXT NOT NULL,
|
||||
`email` TEXT NOT NULL,
|
||||
`password` TEXT,
|
||||
`token` TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE aircraft (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`icao` TEXT NOT NULL,
|
||||
`firstSeen` TEXT NOT NULL,
|
||||
`lastSeen` TEXT
|
||||
`first_seen` TEXT NOT NULL,
|
||||
`last_seen` TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE blog_posts (
|
||||
|
|
@ -71,4 +63,13 @@ CREATE TABLE settings (
|
|||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` TEXT NOT NULL,
|
||||
`value` TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` TEXT NOT NULL,
|
||||
`email` TEXT NOT NULL,
|
||||
`login` TEXT NOT NULL,
|
||||
`password` TEXT,
|
||||
`administrator` INTEGER DEFAULT 0
|
||||
);
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
database:
|
||||
use: "mysql"
|
||||
sqlite:
|
||||
path: "adsbportal.sqlite3"
|
||||
use: "sqlite"
|
||||
mysql:
|
||||
host: "127.0.0.1"
|
||||
user: "portaluser"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
|
||||
[tool.coverage.run]
|
||||
branch = true
|
||||
source = ["backend"]
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import os
|
||||
import pytest
|
||||
import tempfile
|
||||
|
||||
from backend import create_app
|
||||
from backend.db import get_db, init_db
|
||||
|
||||
with open(os.path.join(os.path.dirname(__file__), 'data.sql'), 'rb') as f:
|
||||
_data_sql = f.read().decode('utf8')
|
||||
|
||||
@pytest.fixture
|
||||
def app():
|
||||
db_fd, db_path = tempfile.mkstemp()
|
||||
|
||||
app = create_app({
|
||||
'TESTING': True,
|
||||
'DATABASE': db_path,
|
||||
})
|
||||
|
||||
with app.app_context():
|
||||
init_db()
|
||||
get_db().executescript(_data_sql)
|
||||
|
||||
yield app
|
||||
|
||||
os.close(db_fd)
|
||||
os.unlink(db_path)
|
||||
|
||||
@pytest.fixture
|
||||
def client(app):
|
||||
return app.test_client()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def runner(app):
|
||||
return app.test_cli_runner()
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
INSERT INTO aircraft (`icao`, `first_seen`, `last_seen`)
|
||||
VALUES
|
||||
('icao01', '2024-07-17 01:10:11', '2024-06-17 01:11:01'),
|
||||
('icao02', '2024-07-17 02:20:22', '2024-06-17 02:22:02'),
|
||||
('icao03', '2024-07-17 03:30:33', '2024-06-17 03:33:03'),
|
||||
('icao04', '2024-07-17 04:40:44', '2024-06-17 04:44:04'),
|
||||
('icao05', '2024-07-17 05:50:55', '2024-06-17 05:55:05');
|
||||
|
||||
INSERT INTO positions (`flight`, `aircraft`, `time`, `message`, `squawk`, `latitude`, `longitude`, `track`, `altitude`, `verticle_rate`, `speed`)
|
||||
VALUES
|
||||
(, 1, '2024-06-17 01:11:01', , , , , 5, , , )
|
||||
(, 1, '2024-06-17 01:11:46', , , , , 4, , , )
|
||||
(, 1, '2024-06-17 01:11:31', , , , , 3, , , )
|
||||
(, 1, '2024-06-17 01:11:16', , , , , 2, , , )
|
||||
(, 1, '2024-06-17 01:10:01', , , , , 1, , , )
|
||||
|
||||
(, 1, '2024-07-17 01:11:11', , , , , 5, , , )
|
||||
(, 1, '2024-07-17 01:10:56', , , , , 4, , , )
|
||||
(, 1, '2024-07-17 01:10:41', , , , , 3, , , )
|
||||
(, 1, '2024-07-17 01:10:26', , , , , 2, , , )
|
||||
(, 1, '2024-07-17 01:10:11', , , , , 1, , , )
|
||||
|
||||
(, 5, '2024-06-17 05:55:05', , , , , 4, , , )
|
||||
(, 5, '2024-07-17 05:50:20', , , , , 3, , , )
|
||||
(, 5, '2024-07-17 05:50:35', , , , , 2, , , )
|
||||
(, 5, '2024-07-17 05:50:55', , , , , 1, , , )
|
||||
|
||||
INSERT INTO users (`name`, `email`, `login`, `password`, `administrator`)
|
||||
VALUES
|
||||
('User One', 'noreply@adsbportal.com', 'login_one', '$2y$0htWdxS7PxTvIwJNo2COJ7Rywgif4En0TmJbDvrjLRfWZOBX526yJUKW', 1),
|
||||
('User Two', 'noreply@adsbreceiver.net', 'login_two', '$2y$ui7QK047JldTekx828J2rfSVQ7N5yo6ETQIYGoBqpfFRbNr3EvWzQzt6', 0);
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import pytest
|
||||
import sqlite3
|
||||
|
||||
from backend.db import get_db
|
||||
|
||||
def test_get_close_db(app):
|
||||
with app.app_context():
|
||||
db=get_db()
|
||||
assert db is get_db()
|
||||
|
||||
with pytest.raises(sqlite3.ProgrammingError) as e:
|
||||
db.execute('SELECT 1')
|
||||
|
||||
assert 'closed' in str(e.value)
|
||||
|
||||
def test_init_db_command(runner, monkeypatch):
|
||||
class Recorder(object):
|
||||
called = False
|
||||
|
||||
def fake_init_db():
|
||||
Recorder.called = True
|
||||
|
||||
monkeypatch.setattr('backend.db.init_db', fake_init_db)
|
||||
result = runner.invoke(args=['init-db'])
|
||||
assert 'initialized' in result.output
|
||||
assert Recorder.called
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
from backend import create_app
|
||||
|
||||
def test_config():
|
||||
assert not create_app().testing
|
||||
assert create_app({'TESTING': True}).testing
|
||||
|
||||
def test_api_docs(client):
|
||||
response = client.get('/api/docs')
|
||||
assert b'adsb_receiver_api_v1_oas3.yaml' in response.data
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
# GET /api/aircraft/{icao}
|
||||
|
||||
def test_get_aircraft_200(client):
|
||||
response = client.get('/api/aircraft/icao01')
|
||||
assert response.status_code == 200
|
||||
assert response.json['aircraft']['id'] == 1
|
||||
assert response.json['aircraft']['icao'] == "icao01"
|
||||
assert response.json['aircraft']['first_seen'] == "2024-07-17 01:10:11"
|
||||
assert response.json['aircraft']['last_seen'] == "2024-06-17 01:11:01"
|
||||
|
||||
def test_get_aircraft_404(client):
|
||||
response = client.get('/api/aircraft/icao00')
|
||||
assert response.status_code == 404
|
||||
|
||||
# GET /api/aircraft/{icao}/positions
|
||||
|
||||
def test_get_aircraft_200(client):
|
||||
response = client.get('/api/aircraft/icao00/positions')
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_get_aircraft_404(client):
|
||||
response = client.get('/api/aircraft/icao00/positions')
|
||||
assert response.status_code == 404
|
||||
|
||||
# GET /api/aircraft
|
||||
|
||||
def test_get_aircraft_200(client):
|
||||
response = client.get('/api/aircraft')
|
||||
assert response.status_code == 200
|
||||
assert response.json['offset'] == 0
|
||||
assert response.json['limit'] == 50
|
||||
assert response.json['count'] == 5
|
||||
assert response.json['aircraft'][0]['id'] == 5
|
||||
assert response.json['aircraft'][0]['icao'] == "icao05"
|
||||
assert response.json['aircraft'][0]['first_seen'] == "2024-07-17 05:50:55"
|
||||
assert response.json['aircraft'][0]['last_seen'] == "2024-06-17 05:55:05"
|
||||
assert response.json['aircraft'][1]['id'] == 4
|
||||
assert response.json['aircraft'][1]['icao'] == "icao04"
|
||||
assert response.json['aircraft'][1]['first_seen'] == "2024-07-17 04:40:44"
|
||||
assert response.json['aircraft'][1]['last_seen'] == "2024-06-17 04:44:04"
|
||||
assert response.json['aircraft'][2]['id'] == 3
|
||||
assert response.json['aircraft'][2]['icao'] == "icao03"
|
||||
assert response.json['aircraft'][2]['first_seen'] == "2024-07-17 03:30:33"
|
||||
assert response.json['aircraft'][2]['last_seen'] == "2024-06-17 03:33:03"
|
||||
assert response.json['aircraft'][3]['id'] == 2
|
||||
assert response.json['aircraft'][3]['icao'] == "icao02"
|
||||
assert response.json['aircraft'][3]['first_seen'] == "2024-07-17 02:20:22"
|
||||
assert response.json['aircraft'][3]['last_seen'] == "2024-06-17 02:22:02"
|
||||
assert response.json['aircraft'][4]['id'] == 1
|
||||
assert response.json['aircraft'][4]['icao'] == "icao01"
|
||||
assert response.json['aircraft'][4]['first_seen'] == "2024-07-17 01:10:11"
|
||||
assert response.json['aircraft'][4]['last_seen'] == "2024-06-17 01:11:01"
|
||||
|
||||
def test_get_aircraft_200_offset(client):
|
||||
response = client.get('/api/aircraft?offset=2')
|
||||
assert response.status_code == 200
|
||||
assert response.json['offset'] == 2
|
||||
assert response.json['limit'] == 50
|
||||
assert response.json['count'] == 3
|
||||
assert response.json['aircraft'][0]['id'] == 3
|
||||
assert response.json['aircraft'][0]['icao'] == "icao03"
|
||||
assert response.json['aircraft'][0]['first_seen'] == "2024-07-17 03:30:33"
|
||||
assert response.json['aircraft'][0]['last_seen'] == "2024-06-17 03:33:03"
|
||||
assert response.json['aircraft'][1]['id'] == 2
|
||||
assert response.json['aircraft'][1]['icao'] == "icao02"
|
||||
assert response.json['aircraft'][1]['first_seen'] == "2024-07-17 02:20:22"
|
||||
assert response.json['aircraft'][1]['last_seen'] == "2024-06-17 02:22:02"
|
||||
assert response.json['aircraft'][2]['id'] == 1
|
||||
assert response.json['aircraft'][2]['icao'] == "icao01"
|
||||
assert response.json['aircraft'][2]['first_seen'] == "2024-07-17 01:10:11"
|
||||
assert response.json['aircraft'][2]['last_seen'] == "2024-06-17 01:11:01"
|
||||
|
||||
def test_get_aircraft_200_limit(client):
|
||||
response = client.get('/api/aircraft?limit=2')
|
||||
assert response.status_code == 200
|
||||
assert response.json['offset'] == 0
|
||||
assert response.json['limit'] == 2
|
||||
assert response.json['count'] == 2
|
||||
assert response.json['aircraft'][0]['id'] == 5
|
||||
assert response.json['aircraft'][0]['icao'] == "icao05"
|
||||
assert response.json['aircraft'][0]['first_seen'] == "2024-07-17 05:50:55"
|
||||
assert response.json['aircraft'][0]['last_seen'] == "2024-06-17 05:55:05"
|
||||
assert response.json['aircraft'][1]['id'] == 4
|
||||
assert response.json['aircraft'][1]['icao'] == "icao04"
|
||||
assert response.json['aircraft'][1]['first_seen'] == "2024-07-17 04:40:44"
|
||||
assert response.json['aircraft'][1]['last_seen'] == "2024-06-17 04:44:04"
|
||||
|
||||
def test_get_aircraft_200_offset_and_limit(client):
|
||||
response = client.get('/api/aircraft?offset=1&limit=2')
|
||||
assert response.status_code == 200
|
||||
assert response.json['offset'] == 1
|
||||
assert response.json['limit'] == 2
|
||||
assert response.json['count'] == 2
|
||||
assert response.json['aircraft'][0]['id'] == 4
|
||||
assert response.json['aircraft'][0]['icao'] == "icao04"
|
||||
assert response.json['aircraft'][0]['first_seen'] == "2024-07-17 04:40:44"
|
||||
assert response.json['aircraft'][0]['last_seen'] == "2024-06-17 04:44:04"
|
||||
assert response.json['aircraft'][1]['id'] == 3
|
||||
assert response.json['aircraft'][1]['icao'] == "icao03"
|
||||
assert response.json['aircraft'][1]['first_seen'] == "2024-07-17 03:30:33"
|
||||
assert response.json['aircraft'][1]['last_seen'] == "2024-06-17 03:33:03"
|
||||
|
||||
def test_get_aircraft_400_offset_less_than_0(client):
|
||||
response = client.get('/api/aircraft?offset=-1')
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_get_aircraft_400_limit_less_than_0(client):
|
||||
response = client.get('/api/aircraft?limit=-1')
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_get_aircraft_400_limit_greater_than_100(client):
|
||||
response = client.get('/api/aircraft?limit=101')
|
||||
assert response.status_code == 400
|
||||
|
||||
# GET /api/aircraft/count
|
||||
|
||||
def test_get_aircraft_count(client):
|
||||
response = client.get('/api/aircraft/count')
|
||||
assert response.status_code == 200
|
||||
assert response.json["aircraft"] == 5
|
||||
Ładowanie…
Reference in New Issue