mirror of
https://github.com/laramies/theHarvester.git
synced 2026-08-23 14:22:24 +02:00
149 lines
5.8 KiB
Python
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()
|