add airlines crud

This commit is contained in:
Brian Rosner 2025-01-19 20:23:42 -07:00
parent 5c8ccaa812
commit 607d4064a3
4 changed files with 273 additions and 0 deletions

132
tests/test_airline.py Normal file
View File

@ -0,0 +1,132 @@
from flask.testing import FlaskClient
from sqlalchemy.sql import func, select
from teufa import db as dbm
from teufa.ext import db
def test_create_airline(client: FlaskClient, tenant: dbm.Tenant):
response = client.post(
"/api/v1/airlines",
json={
"airline": {
"name": "Test Airline",
"iata": "TA",
"icao": "TST",
}
},
)
assert response.status_code == 201
assert response.json == {
"airline": {
"id": 1,
"name": "Test Airline",
"iata": "TA",
"icao": "TST",
}
}
def test_get_airline(client: FlaskClient, tenant: dbm.Tenant):
airline = dbm.Airline(
tenant_id=tenant.id,
name="Test Airline",
iata="TA",
icao="TST",
)
db.session.add(airline)
db.session.commit()
response = client.get(f"/api/v1/airlines/{airline.id}")
assert response.status_code == 200
assert response.json == {
"airline": {
"id": airline.id,
"name": "Test Airline",
"iata": "TA",
"icao": "TST",
}
}
def test_get_airline_not_found(client: FlaskClient):
response = client.get("/api/v1/airlines/1")
assert response.status_code == 404
assert response.json == {"message": "Airline not found"}
def test_update_airline(client: FlaskClient, tenant: dbm.Tenant):
airline = dbm.Airline(
tenant_id=tenant.id,
name="Test Airline",
iata="TA",
icao="TST",
)
db.session.add(airline)
db.session.commit()
response = client.put(
f"/api/v1/airlines/{airline.id}",
json={
"airline": {
"name": "Updated Airline",
"iata": "UA",
"icao": "UPD",
}
},
)
assert response.status_code == 200
assert response.json == {
"airline": {
"id": airline.id,
"name": "Updated Airline",
"iata": "UA",
"icao": "UPD",
}
}
def test_update_airline_not_found(client: FlaskClient):
response = client.put(
"/api/v1/airlines/1",
json={
"airline": {
"name": "Updated Airline",
"iata": "UA",
"icao": "UPD",
}
},
)
assert response.status_code == 404
assert response.json == {"message": "Airline not found"}
def test_delete_airline(client: FlaskClient, tenant: dbm.Tenant):
airline = dbm.Airline(
tenant_id=tenant.id,
name="Test Airline",
iata="TA",
icao="TST",
)
db.session.add(airline)
db.session.commit()
response = client.delete(f"/api/v1/airlines/{airline.id}")
assert response.status_code == 204
assert response.data == b""
with db.session.begin():
assert db.session.scalar(select(func.count(dbm.Airline.id))) == 0
def test_delete_airline_not_found(client: FlaskClient):
response = client.delete("/api/v1/airlines/1")
assert response.status_code == 404
assert response.json == {"message": "Airline not found"}

View File

@ -1,3 +1,5 @@
from datetime import datetime
from pydantic import BaseModel
empty = object()
@ -71,3 +73,37 @@ class UpdateFlightResponse(BaseModel):
class GetFlightResponse(BaseModel):
flight: Flight
class Airline(BaseModel):
id: int | None = None
name: str
iata: str
icao: str
class PartialAirline(BaseModel):
id: int | object = empty
name: str | object = empty
iata: str | object = empty
icao: str | object = empty
class CreateAirlineRequest(BaseModel):
airline: Airline
class CreateAirlineResponse(BaseModel):
airline: Airline
class UpdateAirlineRequest(BaseModel):
airline: PartialAirline
class UpdateAirlineResponse(BaseModel):
airline: Airline
class GetAirlineResponse(BaseModel):
airline: Airline

View File

@ -3,6 +3,7 @@ from sqlalchemy import select
from .. import db as dbm
from ..ext import db
from .airlines import bp as airlines_bp
from .flights import bp as flights_bp
from .tenants import bp as tenants_bp
@ -25,5 +26,6 @@ def before_request():
).first()
api_bp.register_blueprint(airlines_bp)
api_bp.register_blueprint(flights_bp)
v1_bp.register_blueprint(api_bp)

103
teufa/v1_api/airlines.py Normal file
View File

@ -0,0 +1,103 @@
from flask import Blueprint, g, jsonify, request
from .. import dao
from .. import db as dbm
from ..ext import db
bp = Blueprint("airlines", __name__, url_prefix="/airlines")
@bp.route("", methods=["POST"])
def create_airline():
data = request.get_json()
req = dao.CreateAirlineRequest(**data)
airline = dbm.Airline(
tenant_id=g.tenant.id,
name=req.airline.name,
iata=req.airline.iata,
icao=req.airline.icao,
)
db.session.add(airline)
db.session.commit()
res = dao.CreateAirlineResponse(
**{
"airline": {
"id": airline.id,
"name": airline.name,
"iata": airline.iata,
"icao": airline.icao,
}
}
)
return jsonify(res.model_dump()), 201
@bp.route("/<int:airline_id>", methods=["GET"])
def get_airline(airline_id):
airline = db.session.get(dbm.Airline, airline_id)
if not airline:
return jsonify(dao.Error(message="Airline not found").model_dump()), 404
res = dao.GetAirlineResponse(
**{
"airline": {
"id": airline.id,
"name": airline.name,
"iata": airline.iata,
"icao": airline.icao,
}
}
)
return jsonify(res.model_dump())
@bp.route("/<int:airline_id>", methods=["PUT"])
def update_airline(airline_id):
airline = db.session.get(dbm.Airline, airline_id)
if not airline:
return jsonify(dao.Error(message="Airline not found").model_dump()), 404
data = request.get_json()
req = dao.UpdateAirlineRequest(**data)
if req.airline.name is not dao.empty:
airline.name = req.airline.name
if req.airline.iata is not dao.empty:
airline.iata = req.airline.iata
if req.airline.icao is not dao.empty:
airline.icao = req.airline.icao
db.session.commit()
res = dao.UpdateAirlineResponse(
**{
"airline": {
"id": airline.id,
"name": airline.name,
"iata": airline.iata,
"icao": airline.icao,
}
}
)
return jsonify(res.model_dump())
@bp.route("/<int:airline_id>", methods=["DELETE"])
def delete_airline(airline_id):
airline = db.session.get(dbm.Airline, airline_id)
if not airline:
return jsonify(dao.Error(message="Airline not found").model_dump()), 404
db.session.delete(airline)
db.session.commit()
return "", 204