From 68fb74b7a688100960a014a1fb015b30d877a124 Mon Sep 17 00:00:00 2001
From: Manon Blanco <blanco@teklia.com>
Date: Tue, 29 Mar 2022 11:45:58 +0200
Subject: [PATCH] Support error responses in MockApiClient

---
 arkindex/mock.py   | 22 ++++++++++++++++++++++
 tests/test_mock.py | 18 +++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/arkindex/mock.py b/arkindex/mock.py
index 7fb0903..d634d3d 100644
--- a/arkindex/mock.py
+++ b/arkindex/mock.py
@@ -24,6 +24,26 @@ class MockApiClient(object):
         self.responses.append((request, response))
         return (request, response)
 
+    def add_error_response(
+        self,
+        operation_id: str,
+        status_code: int,
+        title="Mock error response",
+        content="Mock error response",
+        body=None,
+        *args,
+        **kwargs,
+    ):
+        """Store a new mock error response for a request on an endpoint"""
+        request = MockRequest(operation_id, body, args, kwargs)
+        error = apistar.exceptions.ErrorResponse(
+            title=title,
+            status_code=status_code,
+            content=content,
+        )
+        self.responses.append((request, error))
+        return (request, error)
+
     def next_response(self, request: MockRequest):
         """Find the next available response for a request, and remove it from the stack"""
         for request_cmp, response in self.responses:
@@ -46,6 +66,8 @@ class MockApiClient(object):
         response = next(self.next_response(request), None)
         if response is not None:
             logger.info(f"Sending mock response for {operation_id}")
+            if isinstance(response, Exception):
+                raise response
             return response
 
         # Throw exception when no response is found
diff --git a/tests/test_mock.py b/tests/test_mock.py
index 755c41c..74375be 100644
--- a/tests/test_mock.py
+++ b/tests/test_mock.py
@@ -54,6 +54,14 @@ def test_mock_client():
             "id": "5678-dog",
         },
     )
+    mock.add_error_response(
+        "DeleteTag",
+        name="Henri",
+        body={"tag": "yyy"},
+        status_code=403,
+        title="Forbidden",
+        content="You cannot perform this action",
+    )
 
     # Call the endpoints - this simulates business code
     animals = mock.paginate("ListAnimals")
@@ -76,16 +84,24 @@ def test_mock_client():
         "id": "1234-cat",
     }
 
+    with pytest.raises(apistar.exceptions.ErrorResponse) as e_info:
+        mock.request("DeleteTag", name="Henri", body={"tag": "yyy"})
+    _, error_response, _ = e_info._excinfo
+    assert error_response.status_code == 403
+    assert error_response.title == "Forbidden"
+    assert error_response.content == "You cannot perform this action"
+
     # A request not mocked should raise an exception
     with pytest.raises(apistar.exceptions.ErrorResponse):
         mock.request("DoSomething", parameter="value")
 
     # Check the mockup history
-    assert len(mock.history) == 4
+    assert len(mock.history) == 5
     assert [req.operation for req in mock.history] == [
         "ListAnimals",
         "CreateTag",
         "CreateTag",
+        "DeleteTag",
         "DoSomething",
     ]
 
-- 
GitLab