codecov[bot]: # [Codecov](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70?src=pr&el=h1) Report
> Merging [#70](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70?src=pr&el=desc) into [master](https://codecov.io/gh/ingresso-group/pyticketswitch/commit/a22c4a3679174b1798acda89e59559930eb1f1a3?src=pr&el=desc) will **increase** coverage by `0.02%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70/graphs/tree.svg?height=150&width=650&token=LsKUTNdnRb&src=pr)](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master      #70      +/-   ##
==========================================
+ Coverage   99.48%   99.51%   +0.02%     
==========================================
  Files          37       37              
  Lines        1764     2046     +282     
==========================================
+ Hits         1755     2036     +281     
- Misses          9       10       +1
```


| [Impacted Files](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pyticketswitch/reservation.py](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70/diff?src=pr&el=tree#diff-cHl0aWNrZXRzd2l0Y2gvcmVzZXJ2YXRpb24ucHk=) | `100% <100%> (ø)` | :arrow_up: |
| [pyticketswitch/exceptions.py](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70/diff?src=pr&el=tree#diff-cHl0aWNrZXRzd2l0Y2gvZXhjZXB0aW9ucy5weQ==) | `100% <100%> (ø)` | :arrow_up: |
| [pyticketswitch/trolley.py](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70/diff?src=pr&el=tree#diff-cHl0aWNrZXRzd2l0Y2gvdHJvbGxleS5weQ==) | `94.73% <100%> (+0.09%)` | :arrow_up: |
| [pyticketswitch/client.py](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70/diff?src=pr&el=tree#diff-cHl0aWNrZXRzd2l0Y2gvY2xpZW50LnB5) | `99.31% <100%> (+0.13%)` | :arrow_up: |
| [pyticketswitch/availability.py](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70/diff?src=pr&el=tree#diff-cHl0aWNrZXRzd2l0Y2gvYXZhaWxhYmlsaXR5LnB5) | `100% <0%> (ø)` | :arrow_up: |
| [pyticketswitch/mixins.py](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70/diff?src=pr&el=tree#diff-cHl0aWNrZXRzd2l0Y2gvbWl4aW5zLnB5) | `100% <0%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70?src=pr&el=footer). Last update [a22c4a3...3a2e91d](https://codecov.io/gh/ingresso-group/pyticketswitch/pull/70?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

diff --git a/pyticketswitch/client.py b/pyticketswitch/client.py
index 8b00be5..7726b43 100644
--- a/pyticketswitch/client.py
+++ b/pyticketswitch/client.py
@@ -1081,7 +1081,8 @@ class Client(object):
     def get_trolley(self, token=None, number_of_seats=None, discounts=None,
                     seats=None, send_codes=None, ticket_type_code=None,
                     performance_id=None, price_band_code=None,
-                    item_numbers_to_remove=None, **kwargs):
+                    item_numbers_to_remove=None,
+                    raise_on_unavailable_order=False, **kwargs):
 
         """Retrieve the contents of a trolley from the API.
 
@@ -1097,14 +1098,17 @@ class Client(object):
             seats (list): list of seat IDs.
             send_codes (dict): send codes indexed on backend source
                 code.
-            ticket_type_code: (string): code of ticket type to add to
+            ticket_type_code (string): code of ticket type to add to
                 the trolley.
-            performance_id: (string): id of the performance to add to
+            performance_id (string): id of the performance to add to
                 the trolley.
-            price_band_code: (string): code of price band to add to
+            price_band_code (string): code of price band to add to
                 the trolley.
-            item_numbers_to_remove: (list): list of item numbers to
+            item_numbers_to_remove (list): list of item numbers to
                 remove from trolley.
+            raise_on_unavailable_order (bool): When set to ``True`` this method
+                will raise an exception when the API was not able to add an
+                order to the trolley as it was unavailable.
             **kwargs: arbitary additional raw keyword arguments to add the
                 parameters.
 
@@ -1116,6 +1120,9 @@ class Client(object):
         Raises:
             InvalidParametersError: when there is an issue with the provided
                 parameters.
+            OrderUnavailableError: when ``raise_on_unavailable_order`` is set
+                to ``True`` and the requested addition to a trolley was
+                unavailable.
 
         .. _`/f13/trolley.v1`: http://docs.ingresso.co.uk/#trolley
 
@@ -1133,6 +1140,11 @@ class Client(object):
         trolley = Trolley.from_api_data(response)
         meta = CurrencyMeta.from_api_data(response)
 
+        if raise_on_unavailable_order:
+            if trolley and trolley.input_contained_unavailable_order:
+                raise exceptions.OrderUnavailableError(
+                    "inputs contained unavailable order")
+
         return trolley, meta
 
     def get_upsells(self, token=None, number_of_seats=None, discounts=None,
@@ -1278,7 +1290,8 @@ class Client(object):
     def make_reservation(self, token=None, number_of_seats=None, discounts=None,
                          seats=None, send_codes=None, ticket_type_code=None,
                          performance_id=None, price_band_code=None,
-                         item_numbers_to_remove=None, **kwargs):
+                         item_numbers_to_remove=None,
+                         raise_on_unavailable_order=False, **kwargs):
 
         """Attempt to reserve all the items in the given trolley
 
@@ -1314,6 +1327,9 @@ class Client(object):
                 the trolley
             item_numbers_to_remove: (list): list of item numbers to
                 remove from trolley.
+            raise_on_unavailable_order (bool): When set to ``True`` this method
+                will raise an exception when the API was not able to add an
+                order to the trolley as it was unavailable.
             **kwargs: arbitary additional raw keyword arguments to add the
                 parameters.
 
@@ -1325,6 +1341,9 @@ class Client(object):
         Raises:
             InvalidParametersError: when there is an issue with the provided
                 parameters.
+            OrderUnavailableError: when ``raise_on_unavailable_order`` is set
+                to ``True`` and the requested addition to a trolley was
+                unavailable.
 
         .. _`/f13/reserve.v1`: http://docs.ingresso.co.uk/#reserve
 
@@ -1342,15 +1361,22 @@ class Client(object):
         reservation = Reservation.from_api_data(response)
         meta = CurrencyMeta.from_api_data(response)
 
+        if raise_on_unavailable_order:
+            if reservation and reservation.input_contained_unavailable_order:
+                raise exceptions.OrderUnavailableError(
+                    "inputs contained unavailable order")
+
         return reservation, meta
 
-    def release_reservation(self, transaction_uuid):
+    def release_reservation(self, transaction_uuid, **kwargs):
         """Release an existing reservation.
 
         Wraps `/f13/release.v1`_
 
         Args:
             transaction_uuid (str): the identifier of the reservaiton.
+            **kwargs: arbitary additional raw keyword arguments to add the
+                parameters.
 
         Returns:
             bool: :obj:`True` if the reservation was successfully released
@@ -1361,7 +1387,8 @@ class Client(object):
         """
 
         params = {'transaction_uuid': transaction_uuid}
-        response = self.make_request('release.v1', params, method=POST)
+        kwargs.update(params)
+        response = self.make_request('release.v1', kwargs, method=POST)
 
         return response.get('released_ok', False)
 
diff --git a/pyticketswitch/exceptions.py b/pyticketswitch/exceptions.py
index f88f636..3aef367 100644
--- a/pyticketswitch/exceptions.py
+++ b/pyticketswitch/exceptions.py
@@ -51,3 +51,7 @@ class BackendThrottleError(BackendError):
 
 class CallbackGoneError(APIError):
     pass
+
+
+class OrderUnavailableError(PyticketswitchError):
+    pass
diff --git a/pyticketswitch/reservation.py b/pyticketswitch/reservation.py
index b12d2bb..a75087e 100644
--- a/pyticketswitch/reservation.py
+++ b/pyticketswitch/reservation.py
@@ -46,9 +46,12 @@ class Reservation(Status):
 
     """
 
-    def __init__(self, unreserved_orders=None, *args, **kwargs):
+    def __init__(self, unreserved_orders=None,
+                 input_contained_unavailable_order=False, *args, **kwargs):
+
         super(Reservation, self).__init__(*args, **kwargs)
         self.unreserved_orders = unreserved_orders
+        self.input_contained_unavailable_order = input_contained_unavailable_order
 
     @classmethod
     def from_api_data(cls, data):
@@ -75,7 +78,9 @@ class Reservation(Status):
                 for order in raw_unreserved_orders
             ]
 
-        inst.unreserved_orders=unreserved_orders
+        inst.unreserved_orders = unreserved_orders
+        inst.input_contained_unavailable_order = data.get(
+            'input_contained_unavailable_order', False)
 
         return inst
 
diff --git a/pyticketswitch/trolley.py b/pyticketswitch/trolley.py
index 0a78e2e..df54c75 100644
--- a/pyticketswitch/trolley.py
+++ b/pyticketswitch/trolley.py
@@ -25,11 +25,14 @@ class Trolley(JSONMixin, object):
         order_count (int): the number of orders in the trolley.
         purchase_result (:class:`PurchaseResult <pyticketswitch.callout.Callout>`):
             the result of the purchase attempt when available.
-
+        input_contained_unavailable_order (bool): indicates that the call used
+            to create or modify this trolley object included at least one order
+            that was not available.
     """
     def __init__(self, token=None, transaction_uuid=None, transaction_id=None,
                  bundles=None, discarded_orders=None, minutes_left=None,
-                 order_count=None, purchase_result=None):
+                 order_count=None, purchase_result=None,
+                 input_contained_unavailable_order=False):
         self.token = token
         self.transaction_uuid = transaction_uuid
         self.transaction_id = transaction_id
@@ -38,6 +41,7 @@ class Trolley(JSONMixin, object):
         self.minutes_left = minutes_left
         self.order_count = order_count
         self.purchase_result = purchase_result
+        self.input_contained_unavailable_order = input_contained_unavailable_order
 
     @classmethod
     def from_api_data(cls, data):
@@ -82,6 +86,8 @@ class Trolley(JSONMixin, object):
             'transaction_uuid': raw_contents.get('transaction_uuid'),
             'transaction_id': raw_contents.get('transaction_id'),
             'order_count': data.get('trolley_order_count'),
+            'input_contained_unavailable_order': data.get(
+                'input_contained_unavailable_order', False),
         }
 
         minutes = data.get('minutes_left_on_reserve')

missing "input_contained_unavailable_order" flag in trolley/reservation response
Currently when you attempt to add something to a trolley that is not available (sold out, performance in the past, max tickets per order exceeded, etc) it just appears as an empty trolley without any indication that something has gone wrong.

The API returns the `input_contained_unavailable_order` flag in it's response from `trolley.v1` and `reserve.v1`, and this should be added to the trolley object. I would suggest we should look at raising an exception as well.
diff --git a/tests/test_client.py b/tests/test_client.py
index 6dfc234..c339059 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -1320,6 +1320,34 @@ class TestClient:
         assert 'gbp' in meta.currencies
         assert meta.default_currency_code == 'gbp'
 
+    def test_get_trolley_with_unavailable_order(self, client, monkeypatch):
+        """
+        This test is to check that an unavailable order doesn't raise
+        any exceptions unless `raise_on_unavailable_order` is set to true
+        """
+        response = {
+            'trolley_contents': {},
+            'trolley_token': 'DEF456',
+            'currency_code': 'gbp',
+            'input_contained_unavailable_order': True,
+            'currency_details': {
+                'gbp': {
+                    'currency_code': 'gbp',
+                }
+            }
+        }
+
+        mock_make_request = Mock(return_value=response)
+        monkeypatch.setattr(client, 'make_request', mock_make_request)
+
+        # this should not raise any exceptions
+        client.get_trolley()
+
+        # but this should
+        with pytest.raises(exceptions.OrderUnavailableError):
+            client.get_trolley(raise_on_unavailable_order=True)
+
+
     def test_get_upsells(self, client, monkeypatch):
         # fakes
         response = {
@@ -1409,6 +1437,26 @@ class TestClient:
         assert 'gbp' in meta.currencies
         assert meta.default_currency_code == 'gbp'
 
+    def test_make_reservation_with_unavailable_order(self, client, monkeypatch):
+        """
+        This test is to check that an unavailable order doesn't raise
+        any exceptions unless `raise_on_unavailable_order` is set to true
+        """
+        data = {
+            "input_contained_unavailable_order": True,
+            "unreserved_orders": [],
+        }
+
+        mock_make_request = Mock(return_value=data)
+        monkeypatch.setattr(client, 'make_request', mock_make_request)
+
+        # this should not raise any exceptions
+        client.make_reservation()
+
+        # but this should
+        with pytest.raises(exceptions.OrderUnavailableError):
+            client.make_reservation(raise_on_unavailable_order=True)
+
     def test_get_status(self, client, monkeypatch):
         response = {
             'trolley_contents': {
diff --git a/tests/test_reservation.py b/tests/test_reservation.py
index 91c0895..28bbf74 100644
--- a/tests/test_reservation.py
+++ b/tests/test_reservation.py
@@ -59,3 +59,13 @@ class TestReservation:
 
         assert len(reservation.unreserved_orders) == 1
         assert reservation.minutes_left == 15
+
+    def test_from_api_data_with_unavailable_orders(self):
+        data = {
+            "input_contained_unavailable_order": True,
+            "unreserved_orders": [],
+        }
+
+        reservation = Reservation.from_api_data(data)
+
+        assert reservation.input_contained_unavailable_order is True
diff --git a/tests/test_trolley.py b/tests/test_trolley.py
index fb9b9df..0370757 100644
--- a/tests/test_trolley.py
+++ b/tests/test_trolley.py
@@ -68,6 +68,23 @@ class TestTrolley:
         assert trolley.discarded_orders[0].item == 3
         assert trolley.discarded_orders[1].item == 6
 
+    def test_from_api_data_with_empty_trolley(self):
+        data = {
+            "discarded_orders": [],
+            "input_contained_unavailable_order": True,
+            "trolley_token": "abc123",
+            "trolley_token_contents": {
+                "trolley_bundle_count": 0,
+                "trolley_order_count": 0
+            }
+        }
+
+        trolley = Trolley.from_api_data(data)
+
+        assert trolley.token == 'abc123'
+        assert trolley.input_contained_unavailable_order is True
+
+
     def test_get_events(self):
 
         event_one = Event(id_='abc123')

pip install -e .
parse_log_pytest
requirements.txt
flake8 pylint pytest behave
apt-get update apt-get install -y gcc
3.6
requirements/test.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
astroid==2.11.7
attrs==22.2.0
behave==1.2.6
certifi==2021.5.30
coverage==6.2
dill==0.3.4
distlib==0.3.9
filelock==3.4.1
flake8==5.0.4
idna==3.10
importlib-metadata==1.7.0
importlib-resources==5.4.0
iniconfig==1.1.1
isort==5.10.1
lazy-object-proxy==1.7.1
mccabe==0.7.0
mock==5.2.0
multidict==5.2.0
packaging==21.3
parse==1.20.2
parse-type==0.6.0
platformdirs==2.4.0
pluggy==0.13.1
py==1.11.0
pycodestyle==2.9.1
pyflakes==2.5.0
PyHamcrest==2.1.0
pylint==2.13.9
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
python-dateutil==2.9.0.post0
-e git+https://github.com/ingresso-group/pyticketswitch.git@a22c4a3679174b1798acda89e59559930eb1f1a3#egg=pyticketswitch
PyYAML==6.0.1
requests==2.9.1
requests-mock==1.11.0
six==1.11.0
toml==0.10.2
tomli==1.2.3
tox==3.14.3
typed-ast==1.5.5
typing_extensions==4.1.1
vcrpy==4.1.1
virtualenv==20.16.2
wrapt==1.16.0
yarl==1.7.2
zipp==3.6.0

name: pyticketswitch
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - astroid==2.11.7
      - attrs==22.2.0
      - behave==1.2.6
      - coverage==6.2
      - dill==0.3.4
      - distlib==0.3.9
      - filelock==3.4.1
      - flake8==5.0.4
      - idna==3.10
      - importlib-metadata==1.7.0
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - isort==5.10.1
      - lazy-object-proxy==1.7.1
      - mccabe==0.7.0
      - mock==5.2.0
      - multidict==5.2.0
      - packaging==21.3
      - parse==1.20.2
      - parse-type==0.6.0
      - platformdirs==2.4.0
      - pluggy==0.13.1
      - py==1.11.0
      - pycodestyle==2.9.1
      - pyflakes==2.5.0
      - pyhamcrest==2.1.0
      - pylint==2.13.9
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - python-dateutil==2.9.0.post0
      - pyyaml==6.0.1
      - requests==2.9.1
      - requests-mock==1.11.0
      - six==1.11.0
      - toml==0.10.2
      - tomli==1.2.3
      - tox==3.14.3
      - typed-ast==1.5.5
      - typing-extensions==4.1.1
      - vcrpy==4.1.1
      - virtualenv==20.16.2
      - wrapt==1.16.0
      - yarl==1.7.2
      - zipp==3.6.0
prefix: /opt/conda/envs/pyticketswitch

tests/test_client.py::TestClient::test_get_trolley_with_unavailable_order tests/test_client.py::TestClient::test_make_reservation_with_unavailable_order tests/test_reservation.py::TestReservation::test_from_api_data_with_unavailable_orders tests/test_trolley.py::TestTrolley::test_from_api_data_with_empty_trolley
tests/test_client.py::TestClient::test_get_url tests/test_client.py::TestClient::test_make_request tests/test_client.py::TestClient::test_make_request_with_timeout tests/test_client.py::TestClient::test_make_request_with_post tests/test_client.py::TestClient::test_make_request_with_subuser tests/test_client.py::TestClient::test_make_request_with_tracking_id tests/test_client.py::TestClient::test_make_request_when_using_per_request_tracking_id tests/test_client.py::TestClient::test_make_request_bad_response_with_auth_error tests/test_client.py::TestClient::test_make_request_bad_response_with_error tests/test_client.py::TestClient::test_make_request_bad_response_without_error tests/test_client.py::TestClient::test_make_request_410_gone_response tests/test_client.py::TestClient::test_make_request_no_contents_raises tests/test_client.py::TestClient::test_add_optional_kwargs_extra_info tests/test_client.py::TestClient::test_add_optional_kwargs_reviews tests/test_client.py::TestClient::test_add_optional_kwargs_media tests/test_client.py::TestClient::test_add_optional_kwargs_cost_range tests/test_client.py::TestClient::test_add_optional_kwargs_best_value_offer tests/test_client.py::TestClient::test_add_optional_kwargs_max_saving_offer tests/test_client.py::TestClient::test_add_optional_kwargs_min_cost_offer tests/test_client.py::TestClient::test_add_optional_kwargs_top_price_offer tests/test_client.py::TestClient::test_add_optional_kwargs_no_singles_data tests/test_client.py::TestClient::test_add_optional_kwargs_cost_range_details tests/test_client.py::TestClient::test_add_optional_kwargs_avail_details tests/test_client.py::TestClient::test_add_optional_kwargs_avail_details_with_perfs tests/test_client.py::TestClient::test_add_optional_kwargs_source_info tests/test_client.py::TestClient::test_list_events tests/test_client.py::TestClient::test_list_events_with_keywords tests/test_client.py::TestClient::test_list_events_with_start_date tests/test_client.py::TestClient::test_list_events_with_end_date tests/test_client.py::TestClient::test_list_events_with_start_and_end_date tests/test_client.py::TestClient::test_list_events_country_code tests/test_client.py::TestClient::test_list_events_city_code tests/test_client.py::TestClient::test_list_events_geolocation tests/test_client.py::TestClient::test_list_events_invalid_geolocation tests/test_client.py::TestClient::test_list_events_include_dead tests/test_client.py::TestClient::test_list_events_sort_order tests/test_client.py::TestClient::test_list_events_pagination tests/test_client.py::TestClient::test_list_events_no_results tests/test_client.py::TestClient::test_list_events_misc_kwargs tests/test_client.py::TestClient::test_get_events tests/test_client.py::TestClient::test_get_events_event_list tests/test_client.py::TestClient::test_get_events_no_results tests/test_client.py::TestClient::test_get_events_misc_kwargs tests/test_client.py::TestClient::test_get_events_with_upsell tests/test_client.py::TestClient::test_get_events_with_addons tests/test_client.py::TestClient::test_get_event tests/test_client.py::TestClient::test_get_months tests/test_client.py::TestClient::test_get_months_no_results tests/test_client.py::TestClient::test_get_months_misc_kwargs tests/test_client.py::TestClient::test_list_performances_no_results tests/test_client.py::TestClient::test_list_performances tests/test_client.py::TestClient::test_list_performances_cost_range tests/test_client.py::TestClient::test_list_performances_best_value_offer tests/test_client.py::TestClient::test_list_performances_max_saving_offer tests/test_client.py::TestClient::test_list_performances_min_cost_offer tests/test_client.py::TestClient::test_list_performances_top_price_offer tests/test_client.py::TestClient::test_list_performances_no_singles_data tests/test_client.py::TestClient::test_list_performances_availability tests/test_client.py::TestClient::test_list_performances_pagination tests/test_client.py::TestClient::test_list_performances_with_start_date tests/test_client.py::TestClient::test_list_performancess_with_end_date tests/test_client.py::TestClient::test_list_performances_with_start_and_end_date tests/test_client.py::TestClient::test_list_performances_misc_kwargs tests/test_client.py::TestClient::test_get_performances tests/test_client.py::TestClient::test_get_performances_no_performances tests/test_client.py::TestClient::test_get_performances_misc_kwargs tests/test_client.py::TestClient::test_get_performance tests/test_client.py::TestClient::test_get_availability tests/test_client.py::TestClient::test_get_availability_with_number_of_seats tests/test_client.py::TestClient::test_get_availability_with_discounts tests/test_client.py::TestClient::test_get_availability_with_example_seats tests/test_client.py::TestClient::test_get_availability_with_seat_blocks tests/test_client.py::TestClient::test_get_availability_with_user_commission tests/test_client.py::TestClient::test_get_availability_no_availability tests/test_client.py::TestClient::test_get_send_methods tests/test_client.py::TestClient::test_get_send_methods_bad_data tests/test_client.py::TestClient::test_get_discounts tests/test_client.py::TestClient::test_get_discounts_bad_data tests/test_client.py::TestClient::test_trolley_params_with_trolley_token tests/test_client.py::TestClient::test_trolley_params_with_performance_id tests/test_client.py::TestClient::test_trolley_params_with_number_of_seats tests/test_client.py::TestClient::test_trolley_params_with_ticket_type_code tests/test_client.py::TestClient::test_trolley_params_with_price_band_code tests/test_client.py::TestClient::test_trolley_params_with_item_numbers_to_remove tests/test_client.py::TestClient::test_trolley_params_with_item_numbers_to_remove_with_no_token tests/test_client.py::TestClient::test_trolley_params_with_seats tests/test_client.py::TestClient::test_trolley_params_with_discounts tests/test_client.py::TestClient::test_trolley_params_with_send_codes tests/test_client.py::TestClient::test_trolley_params_with_invalid_send_codes tests/test_client.py::TestClient::test_get_trolley tests/test_client.py::TestClient::test_get_upsells tests/test_client.py::TestClient::test_get_addons tests/test_client.py::TestClient::test_make_reservation tests/test_client.py::TestClient::test_get_status tests/test_client.py::TestClient::test_get_status_with_trans tests/test_client.py::TestClient::test_test tests/test_client.py::TestClient::test_release_reservation tests/test_client.py::TestClient::test_make_purchase_card_details tests/test_client.py::TestClient::test_make_purchase_redirection tests/test_client.py::TestClient::test_make_purchase_credit tests/test_client.py::TestClient::test_make_purchase_opting_out_of_confirmation_email tests/test_client.py::TestClient::test_next_callout tests/test_client.py::TestClient::test_next_callout_with_additional_callout tests/test_client.py::TestClient::test_auth_can_be_overridden_with_subclass tests/test_client.py::TestClient::test_extra_params_can_be_overriden_by_subclass tests/test_client.py::TestClient::test_get_auth_params_raises_deprecation_warning tests/test_client.py::TestClient::test_make_request_using_decimal_parsing tests/test_client.py::TestClient::test_make_request_using_float_parsing tests/test_reservation.py::TestReservation::test_from_api_data tests/test_trolley.py::TestTrolley::test_from_api_data_with_trolley_data tests/test_trolley.py::TestTrolley::test_from_api_data_with_reservation_data tests/test_trolley.py::TestTrolley::test_get_events tests/test_trolley.py::TestTrolley::test_get_events_with_no_bundles tests/test_trolley.py::TestTrolley::test_get_event_ids tests/test_trolley.py::TestTrolley::test_get_bundle tests/test_trolley.py::TestTrolley::test_get_bundle_when_none tests/test_trolley.py::TestTrolley::test_get_bundle_when_no_match tests/test_trolley.py::TestTrolley::test_get_item tests/test_trolley.py::TestTrolley::test_get_orders
pyticketswitch/reservation.py pyticketswitch/client.py pyticketswitch/exceptions.py pyticketswitch/trolley.py
pyticketswitch/reservation.py pyticketswitch/client.py pyticketswitch/exceptions.py pyticketswitch/trolley.py