diff --git a/capycli/bom/check_bom.py b/capycli/bom/check_bom.py index 6af5b20..de71554 100644 --- a/capycli/bom/check_bom.py +++ b/capycli/bom/check_bom.py @@ -66,7 +66,7 @@ def _find_by_id(self, component: Component) -> Optional[Dict[str, Any]]: print( " " + component.name + ", " + version + ", " + sw360id) - if swex.response: + if swex.response is not None: print(" Status Code: " + str(swex.response.status_code)) if swex.message: print(" Message: " + swex.message) @@ -105,7 +105,7 @@ def _find_by_name(self, component: Component) -> Optional[Dict[str, Any]]: print(Fore.LIGHTRED_EX + " Error retrieving release data: ") print( " " + component.name + ", " + version) - if swex.response: + if swex.response is not None: print(" Status Code: " + str(swex.response.status_code)) if swex.message: print(" Message: " + swex.message) diff --git a/capycli/project/create_project.py b/capycli/project/create_project.py index 61d45ce..be9dead 100644 --- a/capycli/project/create_project.py +++ b/capycli/project/create_project.py @@ -146,14 +146,7 @@ def update_project(self, project_id: str, project: Optional[Dict[str, Any]], if swex.response.status_code == requests.codes["forbidden"]: print_red(" You are not authorized - do you have a valid write token?") sys.exit(ResultCode.RESULT_AUTH_ERROR) - if swex.response: - print_red(" " + str(swex.response.status_code) + ": " + swex.response.text) - sys.exit(ResultCode.RESULT_ERROR_ACCESSING_SW360) - if swex.details: - print_red(" " + swex.details.get("error", "") + ": " + swex.details.get("message", "")) - sys.exit(ResultCode.RESULT_ERROR_ACCESSING_SW360) - - print_red(" Unknown error updating project: " + repr(swex)) + print_red(" " + str(swex.response.status_code) + ": " + swex.response.text) sys.exit(ResultCode.RESULT_ERROR_ACCESSING_SW360) def update_project_version(self, project_id: str, project: Dict[str, Any], new_version: str) -> None: diff --git a/tests/test_check_bom.py b/tests/test_check_bom.py index bfd1f34..da9b8e2 100644 --- a/tests/test_check_bom.py +++ b/tests/test_check_bom.py @@ -323,7 +323,7 @@ def test_simple_bom_without_id(self) -> None: self.assertTrue("wheel, 0.38.4" in out) @responses.activate - def xx_test_simple_bom_with_errors(self) -> None: + def test_simple_bom_with_errors(self) -> None: sut = CheckBom() # create argparse command line argument object @@ -361,7 +361,7 @@ def xx_test_simple_bom_with_errors(self) -> None: responses.GET, url=self.MYURL + "resource/api/releases/05c30bf89a512463260b57e84d99b38f", body='{"name": "python", "version": "3.8"}', - status=500, # internal server error + status=403, # forbidden (don't use 500 as this leads to multiple retries by urllib3) content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, ) @@ -370,7 +370,17 @@ def xx_test_simple_bom_with_errors(self) -> None: responses.add( responses.GET, url=self.MYURL + "resource/api/releases/fa0d21eb17574ba9ae17e5c9b432558e", - body='{"name": "tomli", "version": "2.0.1"}', + body=''' + { + "name": "tomli", + "version": "2.0.1", + "_links" : { + "self" : { + "href" : "https://my.server.com/resource/api/releases/fa0d21eb17574ba9ae17e5c9b432558e" + } + } + } + ''', status=200, content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, @@ -380,7 +390,17 @@ def xx_test_simple_bom_with_errors(self) -> None: responses.add( responses.GET, url=self.MYURL + "resource/api/releases/e0995819173d4ac8b1a4da3548935976", - body='{"name": "wheel", "version": "0.38.4"}', + body=''' + { + "name": "wheel", + "version": "0.38.4", + "_links" : { + "self" : { + "href" : "https://my.server.com/resource/api/releases/e0995819173d4ac8b1a4da3548935976" + } + } + } + ''', status=200, content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, @@ -391,9 +411,10 @@ def xx_test_simple_bom_with_errors(self) -> None: self.assertTrue("python, 3.8" in out) self.assertTrue("tomli, 2.0.1" in out) self.assertTrue("wheel, 0.38.4" in out) + self.assertTrue("Status Code: 403" in out) @responses.activate - def xx_test_simple_bom_without_id_with_errors(self) -> None: + def test_simple_bom_without_id_with_errors(self) -> None: sut = CheckBom() # create argparse command line argument object @@ -419,7 +440,17 @@ def xx_test_simple_bom_without_id_with_errors(self) -> None: responses.add( responses.GET, url=self.MYURL + "resource/api/releases/9a2373710bd44769a2560dd31280901d", - body='{"name": "colorama", "version": "0.4.6"}', + body=''' + { + "name": "colorama", + "version": "0.4.6", + "_links" : { + "self" : { + "href" : "https://my.server.com/resource/api/releases/9a2373710bd44769a2560dd31280901d" + } + } + } + ''', status=200, content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, @@ -429,7 +460,17 @@ def xx_test_simple_bom_without_id_with_errors(self) -> None: responses.add( responses.GET, url=self.MYURL + "resource/api/releases/05c30bf89a512463260b57e84d99b38f", - body='{"name": "python", "version": "3.8"}', + body=''' + { + "name": "python", + "version": "3.8", + "_links" : { + "self" : { + "href" : "https://my.server.com/resource/api/releases/05c30bf89a512463260b57e84d99b38f" + } + } + } + ''', status=200, content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, @@ -455,16 +496,6 @@ def xx_test_simple_bom_without_id_with_errors(self) -> None: adding_headers={"Authorization": "Token " + self.MYTOKEN}, ) - # for tomli (2) - responses.add( - responses.GET, - url=self.MYURL + "resource/api/releases/fa0d21eb17574ba9ae17e5c9b432558e", - body='{"name": "tomli", "version": "2.0.1"}', - status=200, - content_type="application/json", - adding_headers={"Authorization": "Token " + self.MYTOKEN}, - ) - # for wheel (1) responses.add( responses.GET, @@ -481,17 +512,7 @@ def xx_test_simple_bom_without_id_with_errors(self) -> None: } } ] }}''', - status=500, - content_type="application/json", - adding_headers={"Authorization": "Token " + self.MYTOKEN}, - ) - - # for wheel (2) - responses.add( - responses.GET, - url=self.MYURL + "resource/api/releases/e0995819173d4ac8b1a4da3548935976", - body='{"name": "wheel", "version": "0.38.4"}', - status=200, + status=403, # forbidden (don't use 500 as this leads to multiple retries by urllib3) content_type="application/json", adding_headers={"Authorization": "Token " + self.MYTOKEN}, ) @@ -501,6 +522,7 @@ def xx_test_simple_bom_without_id_with_errors(self) -> None: self.assertTrue("python, 3.8" in out) self.assertTrue("tomli, 2.0.1" in out) self.assertTrue("wheel, 0.38.4" in out) + self.assertIn("Status Code: 403", out) @responses.activate def xxx_test_simple_bom_show_all(self) -> None: diff --git a/tests/test_update_project.py b/tests/test_update_project.py index 2887731..99f0b2f 100644 --- a/tests/test_update_project.py +++ b/tests/test_update_project.py @@ -4,6 +4,7 @@ from cyclonedx.model.bom import Bom from pytest import fixture, raises +from requests import Response from sw360 import SW360Error from capycli.main.result_codes import ResultCode @@ -51,12 +52,13 @@ class DummyResp: @fixture -def dummy_response() -> Callable[[int, str], Callable[[int, str], MagicMock]]: - """Fixture to create a dummy response object.""" - def _dummy_response(status_code: int, text: str) -> Callable[[int, str], MagicMock]: - result = MagicMock() +def dummy_response() -> Callable[[int, str], Response]: + """Fixture to create a dummy response object with real requests.Response + so that bool(response) correctly returns False for non-2xx status codes.""" + def _dummy_response(status_code: int, text: str) -> Response: + result = Response() result.status_code = status_code - result.text = text + result._content = text.encode("utf-8") return result return _dummy_response