Add constraints to the SQL entities (#186)

This commit is contained in:
Philipp Horstenkamp 2023-10-06 18:48:58 +02:00 committed by GitHub
parent ea9c777217
commit 63325e7faa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 273 additions and 0 deletions

View File

@ -36,6 +36,18 @@ class Company(Base):
sa.UniqueConstraint("name", "city"),
sa.UniqueConstraint("name", "zip_code"),
sa.UniqueConstraint("name"),
sa.CheckConstraint(
"(longitude IS NULL AND latitude IS NULL AND pos_accuracy IS NULL) OR "
"(longitude IS NOT NULL AND latitude IS NOT NULL AND pos_accuracy IS NOT NULL)"
),
sa.CheckConstraint(
"longitude IS NULL OR (longitude >= -180 AND longitude <= 180)"
),
sa.CheckConstraint("latitude IS NULL OR (latitude >= -90 AND latitude <= 90)"),
sa.CheckConstraint(
"(capital_value IS NULL AND original_currency IS NULL AND capital_type IS NULL) OR "
"(capital_value IS NOT NULL AND original_currency IS NOT NULL AND capital_type IS NOT NULL)"
),
)
id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)

View File

@ -1,4 +1,11 @@
"""Tests for the sql entities."""
import datetime
from typing import Any
import pytest
import sqlalchemy as sa
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
from aki_prj23_transparenzregister.utils.sql import entities
@ -6,3 +13,257 @@ from aki_prj23_transparenzregister.utils.sql import entities
def test_import() -> None: #
"""Tests if the entities can be imported."""
assert entities
@pytest.mark.parametrize(
"company_data",
[
# Test case 1: All coordinates are set or all are null (Expect failure)
{
"hr": "HR124",
"court_id": 2,
"name": "Invalid Company",
"street": "456 Elm St",
"zip_code": "54321",
"city": "Invalid City",
"longitude": 1.23,
"latitude": None,
"pos_accuracy": 0.1,
"last_update": datetime.date.fromisoformat("2023-10-02"),
"sector": "Tech",
},
# Test case 2: Longitude must not be null if latitude is set (Expect failure)
{
"hr": "HR124",
"court_id": 2,
"name": "Invalid Company",
"street": "456 Elm St",
"zip_code": "54321",
"city": "Invalid City",
"longitude": None,
"latitude": 4.56,
"pos_accuracy": 0.1,
"last_update": datetime.date.fromisoformat("2023-10-02"),
"sector": "Tech",
},
# Test case 3: Unique name and city constraint (Expect failure)
{
"hr": "HR124",
"court_id": 2,
"name": "Unique Company",
"street": "456 Elm St",
"zip_code": "54321",
"city": "City A",
"longitude": 1.23,
"latitude": None,
"pos_accuracy": 0.1,
"last_update": datetime.date.fromisoformat("2023-10-02"),
"sector": "Tech",
},
{
"hr": "HR125",
"court_id": 3,
"name": "Unique Company",
"street": "789 Oak St",
"zip_code": "98765",
"city": "City B",
"longitude": 2.34,
"latitude": 5.67,
"pos_accuracy": None,
"last_update": datetime.date.fromisoformat("2023-10-03"),
"sector": "Tech",
},
],
)
def test_constraint_enforcement(
empty_db: sa.orm.Session, company_data: dict[str, Any]
) -> None:
"""Tests if the constraint around longitude and latitude passes."""
company = entities.Company(**company_data)
empty_db.add(company)
with pytest.raises(IntegrityError):
empty_db.commit()
@pytest.mark.parametrize(
("company_data", "expect_failure"),
[
# Test case 1: Valid longitude and latitude values (Expect success)
(
{
"hr": "HR124",
"court_id": 2,
"name": "Valid Company",
"street": "456 Elm St",
"zip_code": "54321",
"city": "Valid City",
"longitude": 45.0,
"latitude": -20.0,
"pos_accuracy": 0.1,
"last_update": datetime.date.fromisoformat("2023-10-03"),
"sector": "Tech",
},
False,
),
# Test case 2: Longitude out of range (Expect failure)
(
{
"hr": "HR124",
"court_id": 2,
"name": "Invalid Longitude",
"street": "456 Elm St",
"zip_code": "54321",
"city": "Invalid City",
"longitude": 200.0, # Out of valid range
"latitude": 30.0,
"pos_accuracy": 0.1,
"last_update": datetime.date.fromisoformat("2023-10-02"),
"sector": "Tech",
},
True,
),
# Test case 3: Latitude out of range (Expect failure)
(
{
"hr": "HR124",
"court_id": 2,
"name": "Invalid Latitude",
"street": "456 Elm St",
"zip_code": "54321",
"city": "Invalid City",
"longitude": 45.0,
"latitude": -100.0, # Out of valid range
"pos_accuracy": 0.1,
"last_update": datetime.date.fromisoformat("2023-10-02"),
"sector": "Tech",
},
True,
),
],
)
def test_coordinate_range_constraints(
empty_db: sa.orm.Session, company_data: dict[str, Any], expect_failure: bool
) -> None:
company = entities.Company(**company_data)
empty_db.add(company)
if expect_failure:
with pytest.raises(IntegrityError):
empty_db.commit()
else:
empty_db.commit()
@pytest.mark.parametrize(
("company_data", "expect_failure"),
[
# Test case 1: Valid data with all columns set (Expect success)
(
{
"hr": "HR124",
"court_id": 2,
"name": "Valid Company",
"street": "456 Elm St",
"zip_code": "54321",
"city": "Valid City",
"longitude": 45.0,
"latitude": -20.0,
"pos_accuracy": 0.1,
"capital_value": 1000000.0,
"original_currency": "EUR",
"capital_type": "Equity",
"last_update": datetime.date.fromisoformat("2023-10-02"),
"sector": "Tech",
},
False,
),
# Test case 2: All capital-related columns are NULL (Expect success)
(
{
"hr": "HR125",
"court_id": 3,
"name": "No Capital Info",
"street": "789 Oak St",
"zip_code": "98765",
"city": "No Capital City",
"longitude": None,
"latitude": None,
"pos_accuracy": None,
"capital_value": None,
"original_currency": None,
"capital_type": None,
"last_update": datetime.date.fromisoformat("2023-10-03"),
"sector": "Tech",
},
False,
),
# Test case 3: Only some of the capital-related columns are set (Expect failure)
(
{
"hr": "HR126",
"court_id": 4,
"name": "Partial Capital Info",
"street": "101 Elm St",
"zip_code": "54321",
"city": "Partial Capital City",
"longitude": None,
"latitude": None,
"pos_accuracy": None,
"capital_value": 500000.0,
"original_currency": None, # Invalid because not all columns are set
"capital_type": None, # Invalid because not all columns are set
"last_update": datetime.date.fromisoformat("2023-10-04"),
"sector": "Finance",
},
True,
),
(
{
"hr": "HR126",
"court_id": 4,
"name": "Partial Capital Info",
"street": "101 Elm St",
"zip_code": "54321",
"city": "Partial Capital City",
"longitude": None,
"latitude": None,
"pos_accuracy": None,
"capital_value": 500000.0,
"original_currency": "DM",
"capital_type": None, # Invalid because not all columns are set
"last_update": datetime.date.fromisoformat("2023-10-04"),
"sector": "Finance",
},
True,
),
(
{
"hr": "HR126",
"court_id": 4,
"name": "Partial Capital Info",
"street": "101 Elm St",
"zip_code": "54321",
"city": "Partial Capital City",
"longitude": None,
"latitude": None,
"pos_accuracy": None,
"capital_value": None,
"original_currency": "EUR", # Invalid because not all columns are set
"capital_type": "Hafteinlage", # Invalid because not all columns are set
"last_update": datetime.date.fromisoformat("2023-10-04"),
"sector": "Finance",
},
True,
),
],
)
def test_capital_columns_constraints(
empty_db: Session, company_data: dict[str, Any], expect_failure: bool
) -> None:
company = entities.Company(**company_data)
empty_db.add(company)
if expect_failure:
with pytest.raises(IntegrityError):
empty_db.commit()
else:
empty_db.commit()