Files
theHarvester/tests/discovery/test_githubcode.py
T

149 lines
5.8 KiB
Python

from unittest.mock import MagicMock
import pytest
from httpx import Response
from theHarvester.discovery import githubcode
from theHarvester.discovery.constants import MissingKey
from theHarvester.lib.core import Core
class TestSearchGithubCode:
class OkResponse:
response = Response(status_code=200)
# Mocking the json method properly
def __init__(self):
self.response = Response(status_code=200)
object.__setattr__(
self.response,
"json",
MagicMock(
return_value={
"items": [
{"text_matches": [{"fragment": "test1"}]},
{"text_matches": [{"fragment": "test2"}]},
]
}
),
)
class FailureResponse:
def __init__(self):
self.response = Response(status_code=401)
object.__setattr__(self.response, "json", MagicMock(return_value={}))
class RetryResponse:
def __init__(self):
self.response = Response(status_code=403)
object.__setattr__(self.response, "json", MagicMock(return_value={}))
class MalformedResponse:
def __init__(self):
self.response = Response(status_code=200)
object.__setattr__(
self.response,
"json",
MagicMock(
return_value={
"items": [
{"fail": True},
{"text_matches": []},
{"text_matches": [{"weird": "result"}]},
]
}
),
)
@pytest.mark.asyncio
async def test_missing_key(self):
with pytest.raises(MissingKey):
Core.github_key = MagicMock(return_value=None) # type: ignore[method-assign]
githubcode.SearchGithubCode(word="test", limit=500)
@pytest.mark.asyncio
async def test_fragments_from_response(self):
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
test_result = await test_class_instance.fragments_from_response(
self.OkResponse().response.json()
)
assert test_result == ["test1", "test2"]
@pytest.mark.asyncio
async def test_invalid_fragments_from_response(self):
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
test_result = await test_class_instance.fragments_from_response(
self.MalformedResponse().response.json()
)
assert test_result == []
@pytest.mark.asyncio
async def test_next_page(self):
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
test_result = githubcode.SuccessResult(list(), next_page=2, last_page=4)
assert 2 == await test_class_instance.next_page_or_end(test_result)
@pytest.mark.asyncio
async def test_last_page(self):
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
test_result = githubcode.SuccessResult(list(), 0, 0)
assert await test_class_instance.next_page_or_end(test_result) == 0
@pytest.mark.asyncio
async def test_infinite_loop_fix_page_zero(self):
"""Stop pagination when the next page is zero."""
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
# Test the fixed condition: page != 0
page = 0
counter = 0
limit = 10
# The condition should be False when page is 0, preventing infinite loop
condition_result = counter <= limit and page != 0
assert condition_result is False, "Loop should exit when page is 0"
@pytest.mark.asyncio
async def test_infinite_loop_fix_page_nonzero(self):
"""Continue pagination while the next page is nonzero."""
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
# Test with non-zero page values
for page in [1, 2, 3, 10]:
counter = 0
limit = 10
# The condition should be True when page is non-zero
condition_result = counter <= limit and page != 0
assert condition_result is True, f"Loop should continue when page is {page}"
@pytest.mark.asyncio
async def test_infinite_loop_fix_old_vs_new_condition(self):
"""Treat zero as the end of pagination, not as another page."""
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
page = 0
counter = 0
limit = 10
# Old problematic condition (would cause infinite loop)
old_condition = counter <= limit and page is not None
# New fixed condition (properly exits)
new_condition = counter <= limit and page != 0
# Old condition would be True (causing infinite loop)
assert old_condition is True, "Old condition would cause infinite loop when page=0"
# New condition is False (properly exits)
assert new_condition is False, "New condition properly exits when page=0"
if __name__ == "__main__":
pytest.main()