From 4ca2ccd5196a8130fbcda855ca43be8813b7fe6e Mon Sep 17 00:00:00 2001
From: Lennard Strohmeyer <lennard.strohmeyer@digitallearning.gmbh>
Date: Fri, 20 Dec 2024 09:48:12 +0100
Subject: [PATCH] hotfix for broken test case

---
 src/xapi/tasks.py       |  2 +-
 src/xapi/tests/tests.py | 13 ++++++++-----
 src/xapi/views.py       | 11 +++++------
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/src/xapi/tasks.py b/src/xapi/tasks.py
index 7751a55..2040180 100644
--- a/src/xapi/tasks.py
+++ b/src/xapi/tasks.py
@@ -7,4 +7,4 @@ def retry_forward_statements(self, data, token_type, token, url):
     headers = {"Authorization": token_type + " " + token}
     res = requests.post(url, json=data, headers=headers)
     if not res:
-        raise RuntimeError(f"Could not submit {len(data)} statements to {url}.")
\ No newline at end of file
+        raise RuntimeError(f"Could not forward {len(data)} statements to {url}.")
\ No newline at end of file
diff --git a/src/xapi/tests/tests.py b/src/xapi/tests/tests.py
index 273eb68..c555f41 100644
--- a/src/xapi/tests/tests.py
+++ b/src/xapi/tests/tests.py
@@ -896,6 +896,7 @@ class TestxAPIObjectMatchingDefinitiondId(BaseTestCase):
             response.json()["message"], "xAPI statements couldn't be stored in LRS"
         )
 
+
 class TextxAPIAdditionalLrs(BaseTestCase):
     provider_schema = {
         "id": "h5p-0",
@@ -1016,15 +1017,16 @@ class TextxAPIAdditionalLrs(BaseTestCase):
         client = APIClient()
         client.credentials(HTTP_AUTHORIZATION="Basic " + access_token_h5p)
 
-        # side effect to immediately create a copy of the object to preserve original properties (since, apparently, the magic mock passes the json object by reference)
-        def capture_args(*args, **kwargs):
-            self.captured_json = copy.deepcopy(kwargs.get('json'))
-            self.captured_headers = copy.deepcopy(kwargs.get('headers'))
-
         # create mock response for external LRS
         mock_response = MagicMock()
         mock_response.status_code = 200
         mock_response.json.return_value = {'message': "xAPI statements successfully stored in LRS"}
+        mock_response.__bool__.return_value = True  # important since we check "if not res" in xapi.views
+        # side effect to immediately create a copy of the object to preserve original properties (since, apparently, the magic mock passes the json object by reference)
+        def capture_args(*args, **kwargs):
+            self.captured_json = copy.deepcopy(kwargs.get('json'))
+            self.captured_headers = copy.deepcopy(kwargs.get('headers'))
+            return mock_response
         mock_post.return_value = mock_response
         mock_post.side_effect = capture_args
 
@@ -1039,6 +1041,7 @@ class TextxAPIAdditionalLrs(BaseTestCase):
             response.json()["message"], "xAPI statements successfully stored in LRS"
         )
         mock_post.assert_called_once()
+        assert mock_response.status_code == 200
         if isinstance(self.captured_json, list): self.assertEqual(self.captured_json, [self.statement])
         else: self.assertEqual(self.captured_json, self.statement)
         self.assertEqual(self.captured_headers, self.additional_lrs_auth_headers)
diff --git a/src/xapi/views.py b/src/xapi/views.py
index 5de3b36..b127c46 100644
--- a/src/xapi/views.py
+++ b/src/xapi/views.py
@@ -327,18 +327,17 @@ class CreateStatement(APIView):
         if latest_schema.additional_lrs and isinstance(latest_schema.additional_lrs, list) and len(latest_schema.additional_lrs) > 0:
             for additional_lrs in latest_schema.additional_lrs:
                 headers = {"Authorization": additional_lrs["token_type"] + " " + additional_lrs["token"]}
-                res = None
                 try:
                     res = requests.post(additional_lrs["url"], json=x_api_statements, headers=headers)
+                    if res.status_code != 200:
+                        raise RuntimeError("Returned status code other than 200")
+                    if settings.DEBUG:
+                        print("Forwarded statement to ", additional_lrs["url"], ":", res.reason,
+                              "({})".format(res.status_code))
                 except Exception as e:
                     if settings.DEBUG:
                         print("Could not forward to ", additional_lrs["url"], ":", e)
-                if not res or res.status_code != 200:
                     retry_forward_statements.delay(x_api_statements, additional_lrs["token_type"], additional_lrs["token"], additional_lrs["url"])
-                    if settings.DEBUG:
-                        print("Could not forward to ", additional_lrs["url"], ":", res.reason if res is not None else "URL could not be reached", "({})".format(res.status_code) if res is not None else "")
-                elif res and settings.DEBUG:
-                    print("Forwarded statement to ", additional_lrs["url"], ":", res.reason, "({})".format(res.status_code))
 
         if settings.SHOW_XAPI_STATEMENTS:
            print(x_api_statements)
-- 
GitLab