From 734a5f0b0c384a513d2bd9bb8cd21858c1983d7e Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 18:00:07 +0000 Subject: [PATCH 1/3] Add tests for name2uniprot with mocked HTTP calls Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --- tests/test_pathwaycommons.py | 123 +++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 tests/test_pathwaycommons.py diff --git a/tests/test_pathwaycommons.py b/tests/test_pathwaycommons.py new file mode 100644 index 00000000..2e3749f1 --- /dev/null +++ b/tests/test_pathwaycommons.py @@ -0,0 +1,123 @@ +import pytest +from unittest.mock import patch, MagicMock +import urllib.error +import sys +import os +import importlib.util + +class DummyUtil: + @staticmethod + def logMess(*args, **kwargs): + pass + +# We use a pytest fixture to safely inject mock modules into sys.modules +# only for the duration of this test module. +@pytest.fixture(scope="module", autouse=True) +def mock_dependencies(): + with patch.dict('sys.modules', {"bionetgen.atomizer.utils.util": DummyUtil()}): + spec = importlib.util.spec_from_file_location( + "bionetgen.atomizer.utils.pathwaycommons", + os.path.abspath("bionetgen/atomizer/utils/pathwaycommons.py") + ) + pathwaycommons = importlib.util.module_from_spec(spec) + + with patch.dict('sys.modules', {"bionetgen.atomizer.utils.pathwaycommons": pathwaycommons}): + spec.loader.exec_module(pathwaycommons) + + # Make it accessible to the module via a global or by yielding it + yield pathwaycommons + + +# Because of memoization, we need to bypass it or clear cache between tests. +@pytest.fixture(autouse=True) +def clear_memoize_cache(mock_dependencies): + if hasattr(mock_dependencies.name2uniprot, "cache"): + mock_dependencies.name2uniprot.cache.clear() + yield + +def test_name2uniprot_with_organism(mock_dependencies): + with patch("urllib.request.urlopen") as mock_urlopen: + mock_response = MagicMock() + mock_response.read.return_value = "Entry name\tEntry\nEGFR_HUMAN\tP00533\nOther_HUMAN\tQ12345" + mock_urlopen.return_value = mock_response + + # Call with organism + result = mock_dependencies.name2uniprot("EGFR", organism=["NCBI:9606"]) + + assert result == ["P00533"] + + mock_urlopen.assert_called_once() + args, kwargs = mock_urlopen.call_args + assert "organism%3ANCBI%3A9606" in kwargs["data"].decode("utf-8") + +def test_name2uniprot_without_organism(mock_dependencies): + with patch("urllib.request.urlopen") as mock_urlopen: + mock_response = MagicMock() + mock_response.read.return_value = "Entry name\tEntry\nEGFR_MOUSE\tQ01279\n" + mock_urlopen.return_value = mock_response + + # Call without organism + result = mock_dependencies.name2uniprot("EGFR", organism=None) + + assert result == ["Q01279"] + + mock_urlopen.assert_called_once() + args, kwargs = mock_urlopen.call_args + assert "organism:" not in kwargs["data"].decode("utf-8") + +def test_name2uniprot_fallback(mock_dependencies): + with patch("urllib.request.urlopen") as mock_urlopen: + mock_response_empty = MagicMock() + mock_response_empty.read.return_value = "" + + mock_response_valid = MagicMock() + mock_response_valid.read.return_value = "Entry name\tEntry\nEGFR_RAT\tO00111\n" + + mock_urlopen.side_effect = [mock_response_empty, mock_response_valid] + + result = mock_dependencies.name2uniprot("EGFR", organism=["NCBI:9606"]) + + assert result == ["O00111"] + assert mock_urlopen.call_count == 2 + + args1, kwargs1 = mock_urlopen.call_args_list[0] + assert "organism%3ANCBI%3A9606" in kwargs1["data"].decode("utf-8") + + args2, kwargs2 = mock_urlopen.call_args_list[1] + assert "organism:" not in kwargs2["data"].decode("utf-8") + +def test_name2uniprot_http_error_first_call(mock_dependencies): + with patch("urllib.request.urlopen") as mock_urlopen: + mock_urlopen.side_effect = urllib.error.HTTPError( + url="http://www.uniprot.org/uniprot/?", + code=500, + msg="Internal Server Error", + hdrs={}, + fp=None + ) + + with patch.object(mock_dependencies, 'logMess') as mock_log: + result = mock_dependencies.name2uniprot("EGFR", organism=["NCBI:9606"]) + + assert result is None + mock_log.assert_called_once_with("ERROR:MSC03", "A connection could not be established to uniprot") + +def test_name2uniprot_http_error_second_call(mock_dependencies): + with patch("urllib.request.urlopen") as mock_urlopen: + mock_response_empty = MagicMock() + mock_response_empty.read.return_value = "" + + mock_urlopen.side_effect = [ + mock_response_empty, + urllib.error.HTTPError( + url="http://www.uniprot.org/uniprot/?", + code=500, + msg="Internal Server Error", + hdrs={}, + fp=None + ) + ] + + result = mock_dependencies.name2uniprot("EGFR", organism=["NCBI:9606"]) + + assert result is None From 91e1e221f1e79b7366c9fcbbaa45e11f57bee14f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 21:07:41 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=A7=AA=20Fix=20formatting=20in=20test?= =?UTF-8?q?=5Fpathwaycommons.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --- tests/test_pathwaycommons.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/tests/test_pathwaycommons.py b/tests/test_pathwaycommons.py index 2e3749f1..cba3d26a 100644 --- a/tests/test_pathwaycommons.py +++ b/tests/test_pathwaycommons.py @@ -5,23 +5,27 @@ import os import importlib.util + class DummyUtil: @staticmethod def logMess(*args, **kwargs): pass + # We use a pytest fixture to safely inject mock modules into sys.modules # only for the duration of this test module. @pytest.fixture(scope="module", autouse=True) def mock_dependencies(): - with patch.dict('sys.modules', {"bionetgen.atomizer.utils.util": DummyUtil()}): + with patch.dict("sys.modules", {"bionetgen.atomizer.utils.util": DummyUtil()}): spec = importlib.util.spec_from_file_location( "bionetgen.atomizer.utils.pathwaycommons", - os.path.abspath("bionetgen/atomizer/utils/pathwaycommons.py") + os.path.abspath("bionetgen/atomizer/utils/pathwaycommons.py"), ) pathwaycommons = importlib.util.module_from_spec(spec) - with patch.dict('sys.modules', {"bionetgen.atomizer.utils.pathwaycommons": pathwaycommons}): + with patch.dict( + "sys.modules", {"bionetgen.atomizer.utils.pathwaycommons": pathwaycommons} + ): spec.loader.exec_module(pathwaycommons) # Make it accessible to the module via a global or by yielding it @@ -35,10 +39,13 @@ def clear_memoize_cache(mock_dependencies): mock_dependencies.name2uniprot.cache.clear() yield + def test_name2uniprot_with_organism(mock_dependencies): with patch("urllib.request.urlopen") as mock_urlopen: mock_response = MagicMock() - mock_response.read.return_value = "Entry name\tEntry\nEGFR_HUMAN\tP00533\nOther_HUMAN\tQ12345" + mock_response.read.return_value = ( + "Entry name\tEntry\nEGFR_HUMAN\tP00533\nOther_HUMAN\tQ12345" + ) mock_urlopen.return_value = mock_response # Call with organism @@ -50,6 +57,7 @@ def test_name2uniprot_with_organism(mock_dependencies): args, kwargs = mock_urlopen.call_args assert "organism%3ANCBI%3A9606" in kwargs["data"].decode("utf-8") + def test_name2uniprot_without_organism(mock_dependencies): with patch("urllib.request.urlopen") as mock_urlopen: mock_response = MagicMock() @@ -65,6 +73,7 @@ def test_name2uniprot_without_organism(mock_dependencies): args, kwargs = mock_urlopen.call_args assert "organism:" not in kwargs["data"].decode("utf-8") + def test_name2uniprot_fallback(mock_dependencies): with patch("urllib.request.urlopen") as mock_urlopen: mock_response_empty = MagicMock() @@ -86,6 +95,7 @@ def test_name2uniprot_fallback(mock_dependencies): args2, kwargs2 = mock_urlopen.call_args_list[1] assert "organism:" not in kwargs2["data"].decode("utf-8") + def test_name2uniprot_http_error_first_call(mock_dependencies): with patch("urllib.request.urlopen") as mock_urlopen: mock_urlopen.side_effect = urllib.error.HTTPError( @@ -93,14 +103,17 @@ def test_name2uniprot_http_error_first_call(mock_dependencies): code=500, msg="Internal Server Error", hdrs={}, - fp=None + fp=None, ) - with patch.object(mock_dependencies, 'logMess') as mock_log: + with patch.object(mock_dependencies, "logMess") as mock_log: result = mock_dependencies.name2uniprot("EGFR", organism=["NCBI:9606"]) assert result is None - mock_log.assert_called_once_with("ERROR:MSC03", "A connection could not be established to uniprot") + mock_log.assert_called_once_with( + "ERROR:MSC03", "A connection could not be established to uniprot" + ) + def test_name2uniprot_http_error_second_call(mock_dependencies): with patch("urllib.request.urlopen") as mock_urlopen: @@ -114,8 +127,8 @@ def test_name2uniprot_http_error_second_call(mock_dependencies): code=500, msg="Internal Server Error", hdrs={}, - fp=None - ) + fp=None, + ), ] result = mock_dependencies.name2uniprot("EGFR", organism=["NCBI:9606"]) From 0e02dfdfd0b1b2bcd77849b67b794d9c4e2667ca Mon Sep 17 00:00:00 2001 From: akutuva21 Date: Mon, 13 Apr 2026 10:16:35 -0400 Subject: [PATCH 3/3] chore: PR #58 remove forbidden artifacts and run black --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 39aa9026..f9bf9c80 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ temp_testing/* build dist Issues/rule_keywords/test_DeleteMolecules_changed.bngl +.jules/ +__pycache__/