From 2449492aba0a7b1a0f92f4f0e9692e40c62d8d77 Mon Sep 17 00:00:00 2001 From: Alexander Hess Date: Mon, 13 Sep 2021 09:57:25 +0200 Subject: [PATCH] Add `Path.from_order()` convenience method Special case of `Path.from_addresses()` to create a single `Path` object from an `Order.restaurant` to the `Customer`. --- .../db/addresses_addresses.py | 19 ++++++ tests/db/test_addresses_addresses.py | 58 ++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/urban_meal_delivery/db/addresses_addresses.py b/src/urban_meal_delivery/db/addresses_addresses.py index 2f91e2c..9164f1b 100644 --- a/src/urban_meal_delivery/db/addresses_addresses.py +++ b/src/urban_meal_delivery/db/addresses_addresses.py @@ -156,6 +156,25 @@ class Path(meta.Base): return paths + @classmethod + def from_order(cls, order: db.Order, google_maps: bool = False) -> Path: + """Calculate the path for an `Order` object. + + The path goes from the `Order.pickup_address` to the `Order.delivery_address`. + + Args: + order: to calculate the path for + google_maps: if `.bicycle_distance` and `._directions` should be + populated with a query to the Google Maps Directions API; + by default, only the `.air_distance` is calculated with `geopy` + + Returns: + path + """ + return cls.from_addresses( + order.pickup_address, order.delivery_address, google_maps=google_maps, + )[0] + def sync_with_google_maps(self) -> None: """Fill in `.bicycle_distance` and `._directions` with Google Maps. diff --git a/tests/db/test_addresses_addresses.py b/tests/db/test_addresses_addresses.py index 2404eb4..b44ed08 100644 --- a/tests/db/test_addresses_addresses.py +++ b/tests/db/test_addresses_addresses.py @@ -197,7 +197,11 @@ class TestConstraints: @pytest.mark.db class TestFromAddresses: - """Test the alternative constructor `Path.from_addresses()`.""" + """Test the alternative constructor `Path.from_addresses()`. + + Includes tests for the convenience method `Path.from_order()`, + which redirects to `Path.from_addresses()`. + """ @pytest.fixture def _prepare_db(self, db_session, address): @@ -304,6 +308,58 @@ class TestFromAddresses: assert result == 6 + # Tests for the `Path.from_order()` convenience method. + + @pytest.mark.usefixtures('_prepare_db') + def test_make_path_instance_from_order( + self, db_session, order, + ): + """Test instantiation of a new `Path` instance.""" + assert db_session.query(db.Path).count() == 0 + + db.Path.from_order(order) + + assert db_session.query(db.Path).count() == 1 + + @pytest.mark.usefixtures('_prepare_db') + def test_make_the_same_path_instance_from_order_twice( + self, db_session, order, + ): + """Test instantiation of a new `Path` instance.""" + assert db_session.query(db.Path).count() == 0 + + db.Path.from_order(order) + + assert db_session.query(db.Path).count() == 1 + + db.Path.from_order(order) + + assert db_session.query(db.Path).count() == 1 + + @pytest.mark.usefixtures('_prepare_db') + def test_structure_of_return_value_from_order(self, db_session, order): + """Test instantiation of a new `Path` instance.""" + result = db.Path.from_order(order) + + assert isinstance(result, db.Path) + + @pytest.mark.usefixtures('_prepare_db') + def test_sync_instance_from_order_with_google_maps( + self, db_session, order, monkeypatch, + ): + """Test instantiation of a new `Path` instance.""" + + def sync(self): + self.bicycle_distance = 1.25 * self.air_distance + self.bicycle_duration = 300 + + monkeypatch.setattr(db.Path, 'sync_with_google_maps', sync) + + result = db.Path.from_order(order, google_maps=True) + + assert result.bicycle_distance is not None + assert result.bicycle_duration is not None + @pytest.mark.db class TestSyncWithGoogleMaps: