Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
laramies
GitHub Repository: laramies/theHarvester
Path: blob/master/tests/discovery/test_githubcode.py
884 views
1
from unittest.mock import MagicMock
2
import pytest
3
from httpx import Response
4
from theHarvester.discovery import githubcode
5
from theHarvester.discovery.constants import MissingKey
6
from theHarvester.lib.core import Core
7
8
9
class TestSearchGithubCode:
10
class OkResponse:
11
response = Response(status_code=200)
12
13
# Mocking the json method properly
14
def __init__(self):
15
self.response = Response(status_code=200)
16
object.__setattr__(
17
self.response,
18
"json",
19
MagicMock(
20
return_value={
21
"items": [
22
{"text_matches": [{"fragment": "test1"}]},
23
{"text_matches": [{"fragment": "test2"}]},
24
]
25
}
26
),
27
)
28
29
class FailureResponse:
30
def __init__(self):
31
self.response = Response(status_code=401)
32
object.__setattr__(self.response, "json", MagicMock(return_value={}))
33
34
class RetryResponse:
35
def __init__(self):
36
self.response = Response(status_code=403)
37
object.__setattr__(self.response, "json", MagicMock(return_value={}))
38
39
class MalformedResponse:
40
def __init__(self):
41
self.response = Response(status_code=200)
42
object.__setattr__(
43
self.response,
44
"json",
45
MagicMock(
46
return_value={
47
"items": [
48
{"fail": True},
49
{"text_matches": []},
50
{"text_matches": [{"weird": "result"}]},
51
]
52
}
53
),
54
)
55
56
@pytest.mark.asyncio
57
async def test_missing_key(self):
58
with pytest.raises(MissingKey):
59
Core.github_key = MagicMock(return_value=None) # type: ignore[method-assign]
60
githubcode.SearchGithubCode(word="test", limit=500)
61
62
@pytest.mark.asyncio
63
async def test_fragments_from_response(self):
64
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
65
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
66
test_result = await test_class_instance.fragments_from_response(
67
self.OkResponse().response.json()
68
)
69
print("test_result: ", test_result)
70
assert test_result == ["test1", "test2"]
71
72
@pytest.mark.asyncio
73
async def test_invalid_fragments_from_response(self):
74
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
75
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
76
test_result = await test_class_instance.fragments_from_response(
77
self.MalformedResponse().response.json()
78
)
79
assert test_result == []
80
81
@pytest.mark.asyncio
82
async def test_next_page(self):
83
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
84
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
85
test_result = githubcode.SuccessResult(list(), next_page=2, last_page=4)
86
assert 2 == await test_class_instance.next_page_or_end(test_result)
87
88
@pytest.mark.asyncio
89
async def test_last_page(self):
90
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
91
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
92
test_result = githubcode.SuccessResult(list(), 0, 0)
93
assert await test_class_instance.next_page_or_end(test_result) == 0
94
95
@pytest.mark.asyncio
96
async def test_infinite_loop_fix_page_zero(self):
97
"""Test that the loop condition properly exits when page becomes 0"""
98
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
99
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
100
101
# Test the fixed condition: page != 0
102
page = 0
103
counter = 0
104
limit = 10
105
106
# The condition should be False when page is 0, preventing infinite loop
107
condition_result = counter <= limit and page != 0
108
assert condition_result is False, "Loop should exit when page is 0"
109
110
@pytest.mark.asyncio
111
async def test_infinite_loop_fix_page_nonzero(self):
112
"""Test that the loop condition continues when page is non-zero"""
113
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
114
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
115
116
# Test with non-zero page values
117
for page in [1, 2, 3, 10]:
118
counter = 0
119
limit = 10
120
121
# The condition should be True when page is non-zero
122
condition_result = counter <= limit and page != 0
123
assert condition_result is True, f"Loop should continue when page is {page}"
124
125
@pytest.mark.asyncio
126
async def test_infinite_loop_fix_old_vs_new_condition(self):
127
"""Test that demonstrates the difference between old and new conditions"""
128
Core.github_key = MagicMock(return_value="test_key") # type: ignore[method-assign]
129
test_class_instance = githubcode.SearchGithubCode(word="test", limit=500)
130
131
page = 0
132
counter = 0
133
limit = 10
134
135
# Old problematic condition (would cause infinite loop)
136
old_condition = counter <= limit and page is not None
137
138
# New fixed condition (properly exits)
139
new_condition = counter <= limit and page != 0
140
141
# Old condition would be True (causing infinite loop)
142
assert old_condition is True, "Old condition would cause infinite loop when page=0"
143
144
# New condition is False (properly exits)
145
assert new_condition is False, "New condition properly exits when page=0"
146
147
148
if __name__ == "__main__":
149
pytest.main()
150
151