urban-meal-delivery/tests/db/test_addresses.py

155 lines
4.8 KiB
Python
Raw Normal View History

"""Test the ORM's `Address` model."""
import pytest
import sqlalchemy as sqla
from sqlalchemy import exc as sa_exc
from urban_meal_delivery import db
from urban_meal_delivery.db import utils
class TestSpecialMethods:
"""Test special methods in `Address`."""
def test_create_address(self, address):
"""Test instantiation of a new `Address` object."""
assert address is not None
def test_text_representation(self, address):
"""`Address` has a non-literal text representation."""
result = repr(address)
assert result == f'<Address({address.street} in {address.city_name})>'
@pytest.mark.db
@pytest.mark.no_cover
class TestConstraints:
"""Test the database constraints defined in `Address`."""
def test_insert_into_database(self, db_session, address):
"""Insert an instance into the (empty) database."""
assert db_session.query(db.Address).count() == 0
db_session.add(address)
db_session.commit()
assert db_session.query(db.Address).count() == 1
def test_delete_a_referenced_address(self, db_session, address, make_address):
"""Remove a record that is referenced with a FK."""
db_session.add(address)
# Fake another_address that has the same `.primary_id` as `address`.
db_session.add(make_address(primary_id=address.id))
db_session.commit()
db_session.delete(address)
with pytest.raises(
sa_exc.IntegrityError, match='fk_addresses_to_addresses_via_primary_id',
):
db_session.commit()
def test_delete_a_referenced_city(self, db_session, address):
"""Remove a record that is referenced with a FK."""
db_session.add(address)
db_session.commit()
# Must delete without ORM as otherwise an UPDATE statement is emitted.
stmt = sqla.delete(db.City).where(db.City.id == address.city.id)
with pytest.raises(
sa_exc.IntegrityError, match='fk_addresses_to_cities_via_city_id',
):
db_session.execute(stmt)
@pytest.mark.parametrize('latitude', [-91, 91])
def test_invalid_latitude(self, db_session, address, latitude):
"""Insert an instance with invalid data."""
address.latitude = latitude
db_session.add(address)
with pytest.raises(
sa_exc.IntegrityError, match='latitude_between_90_degrees',
):
db_session.commit()
@pytest.mark.parametrize('longitude', [-181, 181])
def test_invalid_longitude(self, db_session, address, longitude):
"""Insert an instance with invalid data."""
address.longitude = longitude
db_session.add(address)
with pytest.raises(
sa_exc.IntegrityError, match='longitude_between_180_degrees',
):
db_session.commit()
@pytest.mark.parametrize('zip_code', [-1, 0, 9999, 100000])
def test_invalid_zip_code(self, db_session, address, zip_code):
"""Insert an instance with invalid data."""
address.zip_code = zip_code
db_session.add(address)
with pytest.raises(sa_exc.IntegrityError, match='valid_zip_code'):
db_session.commit()
@pytest.mark.parametrize('floor', [-1, 41])
def test_invalid_floor(self, db_session, address, floor):
"""Insert an instance with invalid data."""
address.floor = floor
db_session.add(address)
with pytest.raises(sa_exc.IntegrityError, match='realistic_floor'):
db_session.commit()
class TestProperties:
"""Test properties in `Address`."""
def test_is_primary(self, address):
"""Test `Address.is_primary` property."""
assert address.id == address.primary_id
result = address.is_primary
assert result is True
def test_is_not_primary(self, address):
"""Test `Address.is_primary` property."""
address.primary_id = 999
result = address.is_primary
assert result is False
def test_location(self, address):
"""Test `Address.location` property."""
latitude = float(address.latitude)
longitude = float(address.longitude)
result = address.location
assert isinstance(result, utils.Location)
assert result.latitude == pytest.approx(latitude)
assert result.longitude == pytest.approx(longitude)
def test_location_is_cached(self, address):
"""Test `Address.location` property."""
result1 = address.location
result2 = address.location
assert result1 is result2
def test_x_is_positive(self, address):
"""Test `Address.x` property."""
result = address.x
assert result > 0
def test_y_is_positive(self, address):
"""Test `Address.y` property."""
result = address.y
assert result > 0