Skip to content

Commit 58011bb

Browse files
committed
add full test coverage and update README examples
1 parent e9cf5b7 commit 58011bb

12 files changed

+4105
-140
lines changed

README.md

Lines changed: 688 additions & 140 deletions
Large diffs are not rendered by default.

tests/test_alert_rule_methods.py

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
"""Test alert rule-related methods"""
2+
3+
import pytest
4+
import responses
5+
import time
6+
from unittest.mock import Mock, patch
7+
from jupiterone.client import JupiterOneClient
8+
from jupiterone.errors import JupiterOneApiError
9+
10+
11+
class TestAlertRuleMethods:
12+
"""Test alert rule-related methods"""
13+
14+
def setup_method(self):
15+
"""Set up test fixtures"""
16+
self.client = JupiterOneClient(account="test-account", token="test-token")
17+
18+
@patch('jupiterone.client.requests.post')
19+
def test_list_alert_rules(self, mock_post):
20+
"""Test list_alert_rules method"""
21+
# Mock first page response
22+
first_response = Mock()
23+
first_response.json.return_value = {
24+
"data": {
25+
"listRuleInstances": {
26+
"questionInstances": [{"id": "rule-1", "name": "Test Rule"}],
27+
"pageInfo": {
28+
"hasNextPage": True,
29+
"endCursor": "cursor-1"
30+
}
31+
}
32+
}
33+
}
34+
35+
# Mock second page response
36+
second_response = Mock()
37+
second_response.json.return_value = {
38+
"data": {
39+
"listRuleInstances": {
40+
"questionInstances": [{"id": "rule-2", "name": "Test Rule 2"}],
41+
"pageInfo": {
42+
"hasNextPage": False,
43+
"endCursor": None
44+
}
45+
}
46+
}
47+
}
48+
49+
mock_post.side_effect = [first_response, second_response]
50+
51+
result = self.client.list_alert_rules()
52+
53+
assert len(result) == 2
54+
assert result[0]["id"] == "rule-1"
55+
assert result[1]["id"] == "rule-2"
56+
assert mock_post.call_count == 2
57+
58+
@patch('jupiterone.client.requests.post')
59+
def test_get_alert_rule_details_found(self, mock_post):
60+
"""Test get_alert_rule_details method - rule found"""
61+
# Mock response with the target rule
62+
mock_response = Mock()
63+
mock_response.json.return_value = {
64+
"data": {
65+
"listRuleInstances": {
66+
"questionInstances": [
67+
{"id": "rule-1", "name": "Test Rule"},
68+
{"id": "rule-2", "name": "Test Rule 2"}
69+
],
70+
"pageInfo": {
71+
"hasNextPage": False,
72+
"endCursor": None
73+
}
74+
}
75+
}
76+
}
77+
mock_post.return_value = mock_response
78+
79+
result = self.client.get_alert_rule_details(rule_id="rule-1")
80+
81+
assert result["id"] == "rule-1"
82+
assert result["name"] == "Test Rule"
83+
84+
@patch('jupiterone.client.requests.post')
85+
def test_get_alert_rule_details_not_found(self, mock_post):
86+
"""Test get_alert_rule_details method - rule not found"""
87+
# Mock response without the target rule
88+
mock_response = Mock()
89+
mock_response.json.return_value = {
90+
"data": {
91+
"listRuleInstances": {
92+
"questionInstances": [
93+
{"id": "rule-1", "name": "Test Rule"}
94+
],
95+
"pageInfo": {
96+
"hasNextPage": False,
97+
"endCursor": None
98+
}
99+
}
100+
}
101+
}
102+
mock_post.return_value = mock_response
103+
104+
result = self.client.get_alert_rule_details(rule_id="nonexistent-rule")
105+
106+
assert result == "Alert Rule not found for provided ID in configured J1 Account"
107+
108+
@patch('jupiterone.client.JupiterOneClient._execute_query')
109+
def test_create_alert_rule_basic(self, mock_execute_query):
110+
"""Test create_alert_rule method - basic usage"""
111+
mock_response = {
112+
"data": {
113+
"createInlineQuestionRuleInstance": {
114+
"id": "rule-1",
115+
"name": "Test Alert Rule"
116+
}
117+
}
118+
}
119+
mock_execute_query.return_value = mock_response
120+
121+
result = self.client.create_alert_rule(
122+
name="Test Alert Rule",
123+
description="Test description",
124+
polling_interval="ONE_DAY",
125+
severity="HIGH",
126+
j1ql="FIND Host"
127+
)
128+
129+
assert result == mock_response["data"]["createInlineQuestionRuleInstance"]
130+
mock_execute_query.assert_called_once()
131+
132+
@patch('jupiterone.client.JupiterOneClient._execute_query')
133+
def test_create_alert_rule_with_resource_group(self, mock_execute_query):
134+
"""Test create_alert_rule method - with resource group"""
135+
mock_response = {
136+
"data": {
137+
"createInlineQuestionRuleInstance": {
138+
"id": "rule-1",
139+
"name": "Test Alert Rule",
140+
"resourceGroupId": "rg-1"
141+
}
142+
}
143+
}
144+
mock_execute_query.return_value = mock_response
145+
146+
result = self.client.create_alert_rule(
147+
name="Test Alert Rule",
148+
description="Test description",
149+
polling_interval="ONE_DAY",
150+
severity="HIGH",
151+
j1ql="FIND Host",
152+
resource_group_id="rg-1"
153+
)
154+
155+
assert result == mock_response["data"]["createInlineQuestionRuleInstance"]
156+
mock_execute_query.assert_called_once()
157+
158+
@patch('jupiterone.client.JupiterOneClient._execute_query')
159+
def test_create_alert_rule_with_action_configs(self, mock_execute_query):
160+
"""Test create_alert_rule method - with action configs"""
161+
mock_response = {
162+
"data": {
163+
"createInlineQuestionRuleInstance": {
164+
"id": "rule-1",
165+
"name": "Test Alert Rule"
166+
}
167+
}
168+
}
169+
mock_execute_query.return_value = mock_response
170+
171+
action_configs = {
172+
"type": "SEND_EMAIL",
173+
"recipients": ["test@example.com"]
174+
}
175+
176+
result = self.client.create_alert_rule(
177+
name="Test Alert Rule",
178+
description="Test description",
179+
polling_interval="ONE_DAY",
180+
severity="HIGH",
181+
j1ql="FIND Host",
182+
action_configs=action_configs
183+
)
184+
185+
assert result == mock_response["data"]["createInlineQuestionRuleInstance"]
186+
mock_execute_query.assert_called_once()
187+
188+
@patch('jupiterone.client.JupiterOneClient._execute_query')
189+
def test_delete_alert_rule(self, mock_execute_query):
190+
"""Test delete_alert_rule method"""
191+
mock_response = {
192+
"data": {
193+
"deleteRuleInstance": {
194+
"id": "rule-1",
195+
"deleted": True
196+
}
197+
}
198+
}
199+
mock_execute_query.return_value = mock_response
200+
201+
result = self.client.delete_alert_rule(rule_id="rule-1")
202+
203+
assert result == mock_response["data"]["deleteRuleInstance"]
204+
mock_execute_query.assert_called_once()
205+
206+
@patch('jupiterone.client.JupiterOneClient.get_alert_rule_details')
207+
@patch('jupiterone.client.JupiterOneClient._execute_query')
208+
def test_update_alert_rule_basic(self, mock_execute_query, mock_get_details):
209+
"""Test update_alert_rule method - basic update"""
210+
# Mock existing rule details
211+
mock_get_details.return_value = {
212+
"id": "rule-1",
213+
"version": 1,
214+
"name": "Old Name",
215+
"description": "Old description",
216+
"pollingInterval": "ONE_DAY",
217+
"tags": ["old-tag"],
218+
"labels": [],
219+
"operations": [{
220+
"__typename": "Operation",
221+
"when": {"type": "FILTER", "condition": ["AND", ["queries.query0.total", ">", 0]]},
222+
"actions": [{"type": "SET_PROPERTY", "targetProperty": "alertLevel", "targetValue": "MEDIUM"}]
223+
}],
224+
"question": {
225+
"__typename": "Question",
226+
"queries": [{"__typename": "Query", "query": "FIND Host"}]
227+
},
228+
"specVersion": 1
229+
}
230+
231+
mock_response = {
232+
"data": {
233+
"updateInlineQuestionRuleInstance": {
234+
"id": "rule-1",
235+
"name": "New Name"
236+
}
237+
}
238+
}
239+
mock_execute_query.return_value = mock_response
240+
241+
result = self.client.update_alert_rule(
242+
rule_id="rule-1",
243+
name="New Name",
244+
description="New description",
245+
labels=[] # Add labels parameter to avoid UnboundLocalError
246+
)
247+
248+
assert result == mock_response["data"]["updateInlineQuestionRuleInstance"]
249+
mock_execute_query.assert_called_once()
250+
251+
@patch('jupiterone.client.JupiterOneClient._execute_query')
252+
def test_evaluate_alert_rule(self, mock_execute_query):
253+
"""Test evaluate_alert_rule method"""
254+
mock_response = {
255+
"data": {
256+
"evaluateRuleInstance": {
257+
"id": "evaluation-1",
258+
"status": "COMPLETED"
259+
}
260+
}
261+
}
262+
mock_execute_query.return_value = mock_response
263+
264+
result = self.client.evaluate_alert_rule(rule_id="rule-1")
265+
266+
assert result == mock_response
267+
mock_execute_query.assert_called_once()
268+
269+
@patch('jupiterone.client.JupiterOneClient._execute_query')
270+
def test_list_alert_rule_evaluation_results(self, mock_execute_query):
271+
"""Test list_alert_rule_evaluation_results method"""
272+
mock_response = {
273+
"data": {
274+
"listCollectionResults": {
275+
"results": [{"id": "result-1", "status": "COMPLETED"}]
276+
}
277+
}
278+
}
279+
mock_execute_query.return_value = mock_response
280+
281+
result = self.client.list_alert_rule_evaluation_results(rule_id="rule-1")
282+
283+
assert result == mock_response
284+
mock_execute_query.assert_called_once()
285+
286+
@patch('jupiterone.client.JupiterOneClient._execute_query')
287+
def test_fetch_evaluation_result_download_url(self, mock_execute_query):
288+
"""Test fetch_evaluation_result_download_url method"""
289+
mock_response = {
290+
"data": {
291+
"getRawDataDownloadUrl": {
292+
"url": "https://example.com/download"
293+
}
294+
}
295+
}
296+
mock_execute_query.return_value = mock_response
297+
298+
result = self.client.fetch_evaluation_result_download_url(raw_data_key="test-key")
299+
300+
assert result == mock_response
301+
mock_execute_query.assert_called_once()
302+
303+
@patch('jupiterone.client.requests.get')
304+
def test_fetch_downloaded_evaluation_results_success(self, mock_get):
305+
"""Test fetch_downloaded_evaluation_results method - success"""
306+
mock_response = Mock()
307+
mock_response.json.return_value = {"data": [{"id": "result-1"}]}
308+
mock_get.return_value = mock_response
309+
310+
result = self.client.fetch_downloaded_evaluation_results(download_url="https://example.com/download")
311+
312+
assert result == {"data": [{"id": "result-1"}]}
313+
mock_get.assert_called_once()
314+
315+
@patch('jupiterone.client.requests.get')
316+
def test_fetch_downloaded_evaluation_results_exception(self, mock_get):
317+
"""Test fetch_downloaded_evaluation_results method - exception"""
318+
mock_get.side_effect = Exception("Network error")
319+
320+
result = self.client.fetch_downloaded_evaluation_results(download_url="https://example.com/download")
321+
322+
assert isinstance(result, Exception)
323+
assert str(result) == "Network error"

0 commit comments

Comments
 (0)