From be18c3090d2fe0e03c6452d4fa08447327aff268 Mon Sep 17 00:00:00 2001 From: Blaine Jester Date: Tue, 20 May 2025 11:12:15 -0700 Subject: [PATCH] Handle port default for CA API-- port 8000 --- .../tests/utils/test_recommendations.py | 37 +++++++++-------- .../contentcuration/utils/recommendations.py | 41 ++++++++++++++----- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/contentcuration/contentcuration/tests/utils/test_recommendations.py b/contentcuration/contentcuration/tests/utils/test_recommendations.py index 14e8aa53d0..c64e6ef489 100644 --- a/contentcuration/contentcuration/tests/utils/test_recommendations.py +++ b/contentcuration/contentcuration/tests/utils/test_recommendations.py @@ -122,7 +122,7 @@ def assert_backend_call( connect_value, make_request_value, method, - *args + *args, ): mock_response_exists.return_value = response_exists_value self.adapter.backend.connect.return_value = connect_value @@ -518,29 +518,34 @@ class RecommendationsBackendFactoryTestCases(TestCase): def setUp(self): self.factory = RecommendationsBackendFactory() - def test_ensure_url_has_scheme_with_no_scheme(self): - url = "example.com" - result = self.factory._ensure_url_has_scheme(url) - self.assertEqual(result, "http://example.com") + def test_prepare_url_with_no_scheme(self): + url = "example.com:8080" + result = self.factory._prepare_url(url) + self.assertEqual(result, f"http://{url}") - def test_ensure_url_has_scheme_with_http(self): + def test_prepare_url_with_no_port(self): url = "http://example.com" - result = self.factory._ensure_url_has_scheme(url) + result = self.factory._prepare_url(url) + self.assertEqual(result, f"{url}:8000") + + def test_prepare_url_with_http(self): + url = "http://example.com:8080" + result = self.factory._prepare_url(url) self.assertEqual(result, url) - def test_ensure_url_has_scheme_with_https(self): - url = "https://example.com" - result = self.factory._ensure_url_has_scheme(url) + def test_prepare_url_with_https(self): + url = "https://example.com:443" + result = self.factory._prepare_url(url) self.assertEqual(result, url) - def test_ensure_url_has_scheme_with_empty_url(self): + def test_prepare_url_with_empty_url(self): url = "" - result = self.factory._ensure_url_has_scheme(url) + result = self.factory._prepare_url(url) self.assertEqual(result, url) - def test_ensure_url_has_scheme_with_none(self): + def test_prepare_url_with_none(self): url = None - result = self.factory._ensure_url_has_scheme(url) + result = self.factory._prepare_url(url) self.assertEqual(result, url) @patch("contentcuration.utils.recommendations.settings") @@ -549,7 +554,7 @@ def test_create_backend_with_url_no_scheme(self, mock_settings): backend = self.factory.create_backend() self.assertIsInstance(backend, Recommendations) - self.assertEqual(backend.base_url, "http://api.example.com") + self.assertEqual(backend.base_url, "http://api.example.com:8000") self.assertEqual(backend.connect_endpoint, "/connect") @patch("contentcuration.utils.recommendations.settings") @@ -558,7 +563,7 @@ def test_create_backend_with_url_with_scheme(self, mock_settings): backend = self.factory.create_backend() self.assertIsInstance(backend, Recommendations) - self.assertEqual(backend.base_url, "https://api.example.com") + self.assertEqual(backend.base_url, "https://api.example.com:8000") self.assertEqual(backend.connect_endpoint, "/connect") @patch("contentcuration.utils.recommendations.settings") diff --git a/contentcuration/contentcuration/utils/recommendations.py b/contentcuration/contentcuration/utils/recommendations.py index 13679d9f41..241238199f 100644 --- a/contentcuration/contentcuration/utils/recommendations.py +++ b/contentcuration/contentcuration/utils/recommendations.py @@ -7,6 +7,7 @@ from typing import List from typing import Union from urllib.parse import urlparse +from urllib.parse import urlunparse from automation.models import RecommendationsCache from automation.utils.appnexus import errors @@ -73,24 +74,42 @@ def __init__(self, **kwargs): class RecommendationsBackendFactory(BackendFactory): - def _ensure_url_has_scheme(self, url): + def _prepare_url(self, url): """ - Checks whether the URL has a scheme. Default to http:// if no scheme exists. + Ensures the URL has a scheme and a port defined. + It defaults to http:// and port 8000 otherwise :param url: The URL to check - :return: A URL with a scheme + :return: A URL with a scheme and port """ - if url: - parsed_url = urlparse(url) - if not parsed_url.scheme: - url = "http://" + url - return url + if not url: + return url + + # avoid parsing URL until after adding scheme, because with and without a port defined, + # urlparse will return an empty netloc, but flip-flop between paths and schemes + if not url.startswith("http"): + url = "http://" + url + + parsed_url = urlparse(url) + netloc = parsed_url.netloc + + if not parsed_url.port: + netloc = f"{netloc}:8000" + + return urlunparse( + ( + parsed_url.scheme, + netloc, + "", + "", + "", + "", + ) + ) def create_backend(self) -> Backend: backend = Recommendations() - backend.base_url = self._ensure_url_has_scheme( - settings.CURRICULUM_AUTOMATION_API_URL - ) + backend.base_url = self._prepare_url(settings.CURRICULUM_AUTOMATION_API_URL) backend.connect_endpoint = "/connect" return backend