|
1 | 1 | import json |
2 | 2 | import unittest |
| 3 | +from unittest.mock import patch |
3 | 4 |
|
| 5 | +import gget.gget_reactome as gget_reactome |
4 | 6 | import pandas as pd |
5 | 7 | from gget.gget_reactome import reactome |
6 | 8 |
|
@@ -61,5 +63,113 @@ def test_reactome_pathways_no_results_network(self): |
61 | 63 | self.assertEqual(list(df.columns), ["stable_id", "name", "species", "schema_class", "in_disease"]) |
62 | 64 |
|
63 | 65 |
|
| 66 | +class TestReactomeOffline(unittest.TestCase): |
| 67 | + """Network-free tests of the Reactome parsing/branch logic (issue #114). |
| 68 | +
|
| 69 | + All HTTP access goes through gget_reactome.http_json, which is mocked here. |
| 70 | + """ |
| 71 | + |
| 72 | + def test_strip_html_passthrough(self): |
| 73 | + # Non-string values pass through unchanged. |
| 74 | + self.assertIsNone(gget_reactome._strip_html(None)) |
| 75 | + self.assertEqual(gget_reactome._strip_html(123), 123) |
| 76 | + self.assertEqual(gget_reactome._strip_html("<span>TP53</span>"), "TP53") |
| 77 | + |
| 78 | + @patch.object(gget_reactome, "http_json") |
| 79 | + def test_pathways_parsing_verbose(self, mock_http): |
| 80 | + mock_http.return_value = [ |
| 81 | + { |
| 82 | + "stId": "R-HSA-1", |
| 83 | + "displayName": "Pathway A", |
| 84 | + "speciesName": "Homo sapiens", |
| 85 | + "schemaClass": "Pathway", |
| 86 | + "isInDisease": False, |
| 87 | + } |
| 88 | + ] |
| 89 | + df = reactome("P04637", resource="pathways", species="Homo sapiens", verbose=True) |
| 90 | + self.assertEqual(df.iloc[0]["stable_id"], "R-HSA-1") |
| 91 | + self.assertEqual(df.iloc[0]["species"], "Homo sapiens") |
| 92 | + |
| 93 | + @patch.object(gget_reactome, "http_json") |
| 94 | + def test_pathways_404_returns_empty(self, mock_http): |
| 95 | + mock_http.side_effect = RuntimeError("Reactome returned HTTP 404") |
| 96 | + df = reactome("NOTREAL", resource="pathways", verbose=False) |
| 97 | + self.assertEqual(len(df), 0) |
| 98 | + |
| 99 | + @patch.object(gget_reactome, "http_json") |
| 100 | + def test_pathways_other_error_raises(self, mock_http): |
| 101 | + mock_http.side_effect = RuntimeError("Reactome returned HTTP 500") |
| 102 | + with self.assertRaises(RuntimeError): |
| 103 | + reactome("P04637", resource="pathways", verbose=False) |
| 104 | + |
| 105 | + @patch.object(gget_reactome, "http_json") |
| 106 | + def test_search_parsing_species_types_verbose(self, mock_http): |
| 107 | + mock_http.return_value = { |
| 108 | + "results": [ |
| 109 | + { |
| 110 | + "entries": [ |
| 111 | + { |
| 112 | + "stId": "R-HSA-9", |
| 113 | + "name": "<span class='highlighting'>TP53</span>", |
| 114 | + "exactType": "Protein", |
| 115 | + "species": ["Homo sapiens"], |
| 116 | + "id": 12345, |
| 117 | + } |
| 118 | + ] |
| 119 | + } |
| 120 | + ] |
| 121 | + } |
| 122 | + df = reactome("TP53", resource="search", species="9606", types="Protein", verbose=True) |
| 123 | + self.assertEqual(df.iloc[0]["stable_id"], "R-HSA-9") |
| 124 | + self.assertEqual(df.iloc[0]["name"], "TP53") # HTML stripped |
| 125 | + self.assertEqual(df.iloc[0]["species"], "Homo sapiens") # list flattened |
| 126 | + |
| 127 | + @patch.object(gget_reactome, "http_json") |
| 128 | + def test_search_404_returns_empty(self, mock_http): |
| 129 | + mock_http.side_effect = RuntimeError("Reactome returned HTTP 404") |
| 130 | + df = reactome("zzzz", resource="search", verbose=False) |
| 131 | + self.assertEqual(len(df), 0) |
| 132 | + |
| 133 | + @patch.object(gget_reactome, "http_json") |
| 134 | + def test_search_other_error_raises(self, mock_http): |
| 135 | + mock_http.side_effect = RuntimeError("Reactome returned HTTP 503") |
| 136 | + with self.assertRaises(RuntimeError): |
| 137 | + reactome("TP53", resource="search", verbose=False) |
| 138 | + |
| 139 | + @patch.object(gget_reactome, "http_json") |
| 140 | + def test_entity_name_fallback_and_summation(self, mock_http): |
| 141 | + # displayName missing -> fall back to first of name list; summation HTML stripped. |
| 142 | + mock_http.return_value = { |
| 143 | + "stId": "R-HSA-6804754", |
| 144 | + "displayName": None, |
| 145 | + "name": ["Regulation of TP53 Activity"], |
| 146 | + "schemaClass": "Pathway", |
| 147 | + "speciesName": "Homo sapiens", |
| 148 | + "isInDisease": False, |
| 149 | + "summation": [{"text": "<p>Some <b>summary</b>.</p>"}], |
| 150 | + } |
| 151 | + result = reactome("R-HSA-6804754", resource="entity", json=True, verbose=True) |
| 152 | + self.assertEqual(result[0]["name"], "Regulation of TP53 Activity") |
| 153 | + self.assertEqual(result[0]["summation"], "Some summary.") |
| 154 | + |
| 155 | + @patch.object(gget_reactome, "http_json") |
| 156 | + def test_entity_404_raises_valueerror(self, mock_http): |
| 157 | + mock_http.side_effect = RuntimeError("Reactome returned HTTP 404") |
| 158 | + with self.assertRaises(ValueError): |
| 159 | + reactome("R-HSA-0", resource="entity", verbose=False) |
| 160 | + |
| 161 | + @patch.object(gget_reactome, "http_json") |
| 162 | + def test_entity_other_error_raises(self, mock_http): |
| 163 | + mock_http.side_effect = RuntimeError("Reactome returned HTTP 500") |
| 164 | + with self.assertRaises(RuntimeError): |
| 165 | + reactome("R-HSA-6804754", resource="entity", verbose=False) |
| 166 | + |
| 167 | + def test_invalid_resource_and_empty_query(self): |
| 168 | + with self.assertRaises(ValueError): |
| 169 | + reactome("TP53", resource="banana", verbose=False) |
| 170 | + with self.assertRaises(ValueError): |
| 171 | + reactome(" ", resource="pathways", verbose=False) |
| 172 | + |
| 173 | + |
64 | 174 | if __name__ == "__main__": |
65 | 175 | unittest.main() |
0 commit comments