"""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'
' @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