Skip to content

Commit 7c0b84a

Browse files
Diana StraussDiana Strauss
authored andcommitted
finished adding simple mock tests for web_api_testing
1 parent d2134d8 commit 7c0b84a

2 files changed

Lines changed: 69 additions & 30 deletions

File tree

tests/test_web_api_documentation.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33

44
from hackingBuddyGPT.usecases import SimpleWebAPITesting
55
from hackingBuddyGPT.usecases.web import MinimalWebTesting
6-
from hackingBuddyGPT.usecases.web_api_testing.simple_openapi_documentation import SimpleWebAPIDocumentationUseCase
6+
from hackingBuddyGPT.usecases.web_api_testing.simple_openapi_documentation import SimpleWebAPIDocumentationUseCase, \
7+
SimpleWebAPIDocumentation
78
from hackingBuddyGPT.utils import DbStorage, Console
89
from hackingBuddyGPT.utils.openai.openai_lib import OpenAILib
910

1011

11-
class TestSimpleWebAPITesting(unittest.TestCase):
12+
class TestSimpleWebAPIDocumentationTest(unittest.TestCase):
1213

1314
@patch('hackingBuddyGPT.utils.openai.openai_lib.OpenAILib')
1415
def setUp(self, MockOpenAILib):
@@ -18,20 +19,22 @@ def setUp(self, MockOpenAILib):
1819
console = Console()
1920

2021
log_db.init()
21-
self.agent = SimpleWebAPITesting(llm=self.mock_llm)
22+
self.agent = SimpleWebAPIDocumentation(llm=self.mock_llm)
2223
self.agent.init()
2324
self.simple_api_testing = SimpleWebAPIDocumentationUseCase(
2425
agent=self.agent,
2526
log_db=log_db,
2627
console=console,
27-
tag='integration_test_linuxprivesc',
28+
tag='webApiDocumentation',
2829
max_turns=len(self.mock_llm.responses)
2930
)
3031
self.simple_api_testing.init()
3132

3233
def test_initial_prompt(self):
3334
# Test if the initial prompt is set correctly
34-
self.assertIn("You're a seasoned API tester tasked with evaluating the REST APIs of a website hosted at https://jsonplaceholder.typicode.com. Your primary objective is to thoroughly explore the APIs, understanding their endpoints, parameters, and responses, and then devise and execute potential exploits. Be diligent in documenting your findings as you navigate through the APIs. Avoid resorting to brute-force tactics. All necessary information can be obtained from the API endpoints themselves. Remember, if you encounter an HTTP method (A string that represents an HTTP method (e.g., 'GET', 'POST', etc.).), promptly submit it as it is of utmost importance.", self.agent._prompt_history[0]['content'])
35+
expected_prompt = "You're tasked with documenting the REST APIs of a website hosted at https://jsonplaceholder.typicode.com. Start with an empty OpenAPI specification.\nMaintain meticulousness in documenting your observations as you traverse the APIs."
36+
37+
self.assertIn(expected_prompt, self.agent._prompt_history[0]['content'])
3538

3639
def test_all_flags_found(self):
3740
# Mock console.print to suppress output during testing
@@ -62,7 +65,7 @@ def test_perform_round(self, mock_perf_counter):
6265
result = self.agent.perform_round(1)
6366

6467
# Assertions
65-
self.assertFalse(result) # No flags found in this round
68+
self.assertTrue(result)
6669

6770
# Check if the LLM was called with the correct parameters
6871
mock_create_with_completion = self.agent.llm.instructor.chat.completions.create_with_completion

tests/test_web_api_testing.py

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,78 @@
1-
import argparse
21
import unittest
3-
from hackingBuddyGPT.usecases.base import use_cases
2+
from unittest.mock import MagicMock, patch
3+
4+
from hackingBuddyGPT.usecases import SimpleWebAPITesting
5+
from hackingBuddyGPT.usecases.web import MinimalWebTesting
6+
from hackingBuddyGPT.usecases.web_api_testing.simple_openapi_documentation import SimpleWebAPIDocumentationUseCase
47
from hackingBuddyGPT.usecases.web_api_testing.simple_web_api_testing import SimpleWebAPITestingUseCase
58
from hackingBuddyGPT.utils import DbStorage, Console
9+
from hackingBuddyGPT.utils.openai.openai_lib import OpenAILib
610

711

12+
class TestSimpleWebAPITestingTest(unittest.TestCase):
813

9-
class WebAPITestingTestCase(unittest.TestCase):
10-
def test_simple_web_api_testing(self):
11-
14+
@patch('hackingBuddyGPT.utils.openai.openai_lib.OpenAILib')
15+
def setUp(self, MockOpenAILib):
16+
# Mock the OpenAILib instance
17+
self.mock_llm = MockOpenAILib.return_value
1218
log_db = DbStorage(':memory:')
1319
console = Console()
1420

1521
log_db.init()
16-
parser = argparse.ArgumentParser()
17-
subparser = parser.add_subparsers(required=True)
18-
for name, use_case in use_cases.items():
19-
use_case.build_parser(subparser.add_parser(
20-
name=use_case.name,
21-
help=use_case.description
22-
))
23-
24-
parsed = parser.parse_args(["SimpleWebAPITesting"])
25-
instance = parsed.use_case(parsed)
26-
27-
agent = instance.agent
28-
simple_web_api_testing = SimpleWebAPITestingUseCase(
29-
agent=agent,
22+
self.agent = SimpleWebAPITesting(llm=self.mock_llm)
23+
self.agent.init()
24+
self.simple_api_testing = SimpleWebAPITestingUseCase(
25+
agent=self.agent,
3026
log_db=log_db,
3127
console=console,
32-
tag='web_api_testing',
33-
max_turns=20
28+
tag='integration_test_linuxprivesc',
29+
max_turns=len(self.mock_llm.responses)
3430
)
31+
self.simple_api_testing.init()
32+
33+
def test_initial_prompt(self):
34+
# Test if the initial prompt is set correctly
35+
self.assertIn("You're a seasoned API tester tasked with evaluating the REST APIs of a website hosted at https://jsonplaceholder.typicode.com. Your primary objective is to thoroughly explore the APIs, understanding their endpoints, parameters, and responses, and then devise and execute potential exploits. Be diligent in documenting your findings as you navigate through the APIs. Avoid resorting to brute-force tactics. All necessary information can be obtained from the API endpoints themselves. Remember, if you encounter an HTTP method (A string that represents an HTTP method (e.g., 'GET', 'POST', etc.).), promptly submit it as it is of utmost importance.", self.agent._prompt_history[0]['content'])
36+
37+
def test_all_flags_found(self):
38+
# Mock console.print to suppress output during testing
39+
with patch('rich.console.Console.print'):
40+
self.agent.all_http_methods_found()
41+
self.assertFalse(self.agent.all_http_methods_found())
42+
43+
@patch('time.perf_counter', side_effect=[1, 2]) # Mocking perf_counter for consistent timing
44+
def test_perform_round(self, mock_perf_counter):
45+
# Prepare mock responses
46+
mock_response = MagicMock()
47+
mock_completion = MagicMock()
48+
49+
# Setup completion response with mocked data
50+
mock_completion.choices[0].message.content = "Mocked LLM response"
51+
mock_completion.choices[0].message.tool_calls = [MagicMock(id="tool_call_1")]
52+
mock_completion.usage.prompt_tokens = 10
53+
mock_completion.usage.completion_tokens = 20
54+
55+
# Mock the OpenAI LLM response
56+
self.agent.llm.instructor.chat.completions.create_with_completion.return_value = (
57+
mock_response, mock_completion)
58+
59+
# Mock the tool execution result
60+
mock_response.execute.return_value = "Mocked tool execution result"
61+
62+
# Perform the round
63+
result = self.agent.perform_round(1)
64+
65+
# Assertions
66+
self.assertFalse(result) # No flags found in this round
67+
68+
# Check if the LLM was called with the correct parameters
69+
mock_create_with_completion = self.agent.llm.instructor.chat.completions.create_with_completion
3570

36-
simple_web_api_testing.init()
37-
result = simple_web_api_testing.run()
38-
# TODO: find condition for testing
71+
# if it can be called multiple times, use assert_called
72+
self.assertEqual( 2, mock_create_with_completion.call_count)
3973

74+
# Check if the prompt history was updated correctly
75+
self.assertEqual(5, len(self.agent._prompt_history)) # Initial message + LLM response + tool message
4076

4177
if __name__ == '__main__':
4278
unittest.main()

0 commit comments

Comments
 (0)