from unittest.mock import mock_open, patch
import pytest
from PaloAltoNetworksAIOps import Client
from pytest_mock import MockerFixture
@pytest.fixture
def AIOps_client(
base_url="base_url",
api_key="api_key",
tsg_id="tsg_id",
client_id="client_id",
client_secret="client_secret",
verify=True,
proxy=False,
headers=None,
):
return Client(
base_url=base_url,
api_key=api_key,
tsg_id=tsg_id,
client_id=client_id,
client_secret=client_secret,
verify=verify,
proxy=proxy,
headers=headers,
)
""" COMMAND FUNCTIONS TESTS """
def test_generate_access_token_request_called_with(mocker, AIOps_client):
with patch("CommonServerPython.get_integration_context", return_value={}):
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
response_mock = mocker.MagicMock()
response_mock.return_value = {}
http_request_mock.return_value = response_mock
AIOps_client.generate_access_token_request()
http_request_mock.assert_called_once_with(
method="POST",
full_url="https://auth.apps.paloaltonetworks.com/auth/v1/oauth2/access_token",
auth=("client_id", "client_secret"),
resp_type="response",
headers={"Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json"},
data={"grant_type": "client_credentials", "scope": "tsg_id:tsg_id"},
)
def test_generate_access_token_request_check_return(mocker, AIOps_client):
with patch("PaloAltoNetworksAIOps.get_integration_context") as mock_get_integration_context:
mock_get_integration_context.return_value = {}
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
response_mock = mocker.Mock()
response_mock.json.return_value = {"access_token": "123", "expires_in": 899}
http_request_mock.return_value = response_mock
AIOps_client.generate_access_token_request()
assert AIOps_client._access_token == "123"
def test_generate_report_command(mocker, AIOps_client):
from PaloAltoNetworksAIOps import generate_report_command
args = {
"entry_id": "1234",
"requester_email": "test@gmail.com",
"requester_name": "test",
"export_as_file": "false",
"show_in_context": "false",
}
generate_access_token_request_mock = mocker.patch.object(AIOps_client, "generate_access_token_request")
generate_access_token_request_mock.return_value = {}
get_info_about_device_request_mock = mocker.patch.object(AIOps_client, "get_info_about_device_request")
get_info_about_device_request_mock.return_value = (
"test1test2test3"
"test"
"test41.1.1.1"
)
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
http_request_mock.return_value = {"upload-url": "url_test", "id": "1234"}
config_file_to_report_request_mock = mocker.patch.object(AIOps_client, "config_file_to_report_request")
config_file_to_report_request_mock.return_value = {}
with (
patch("PaloAltoNetworksAIOps.convert_config_to_bytes", return_value=(b'test')),
patch("PaloAltoNetworksAIOps.polling_until_upload_report_command", return_value=None),
):
generate_report_command(AIOps_client, args)
http_request_mock.assert_called_once_with(
method="POST",
full_url="https://api.stratacloud.paloaltonetworks.com/aiops/bpa/v1/requests",
headers={"Content-Type": "application/json", "Accept": "application/json", "Authorization": "Bearer None"},
json_data={
"requester-email": "test@gmail.com",
"requester-name": "test",
"serial": "test3",
"version": "test4",
"model": "test2",
"family": "test1",
},
)
def test_polling_until_upload_report_command_upload_initiated_status_first_round(mocker, AIOps_client):
from PaloAltoNetworksAIOps import polling_until_upload_report_command
check_upload_status_request_mock = mocker.patch.object(AIOps_client, "check_upload_status_request")
check_upload_status_request_mock.return_value = "UPLOAD_INITIATED"
generate_access_token_request_mock = mocker.patch.object(AIOps_client, "generate_access_token_request")
generate_access_token_request_mock.return_value = {}
args = {"report_id": "123456789", "first_round": "true"}
result = polling_until_upload_report_command(args, AIOps_client)
assert result.scheduled_command
assert result.readable_output == "The report with id 123456789 was sent successfully. Download in progress..."
def test_polling_until_upload_report_command_upload_initiated_status_not_first_round(mocker, AIOps_client):
from PaloAltoNetworksAIOps import polling_until_upload_report_command
check_upload_status_request_mock = mocker.patch.object(AIOps_client, "check_upload_status_request")
check_upload_status_request_mock.return_value = "UPLOAD_INITIATED"
generate_access_token_request_mock = mocker.patch.object(AIOps_client, "generate_access_token_request")
generate_access_token_request_mock.return_value = {}
args = {"report_id": "123456789", "first_round": "false"}
result = polling_until_upload_report_command(args, AIOps_client)
assert result.scheduled_command
assert result.readable_output == ""
def test_polling_until_upload_report_command_completed_with_error(mocker, AIOps_client):
from PaloAltoNetworksAIOps import polling_until_upload_report_command
check_upload_status_request_mock = mocker.patch.object(AIOps_client, "check_upload_status_request")
check_upload_status_request_mock.return_value = "COMPLETED_WITH_ERROR"
generate_access_token_request_mock = mocker.patch.object(AIOps_client, "generate_access_token_request")
generate_access_token_request_mock.return_value = {}
args = {"report_id": "123456789"}
result = polling_until_upload_report_command(args, AIOps_client)
assert not result.scheduled_command
assert result.readable_output == "The report with id 123456789 could not be generated- finished with an error."
def test_polling_until_upload_report_command_config_parsed(mocker, AIOps_client):
from PaloAltoNetworksAIOps import polling_until_upload_report_command
check_upload_status_request_mock = mocker.patch.object(AIOps_client, "check_upload_status_request")
check_upload_status_request_mock.return_value = "CONFIG_PARSED"
generate_access_token_request_mock = mocker.patch.object(AIOps_client, "generate_access_token_request")
generate_access_token_request_mock.return_value = {}
args = {"report_id": "123456789"}
result = polling_until_upload_report_command(args, AIOps_client)
assert result.scheduled_command
def test_polling_until_upload_report_command_completed_with_success(mocker, AIOps_client):
from PaloAltoNetworksAIOps import polling_until_upload_report_command
bpa_json = {
"best_practices": {
"device": {
"feature1": [
{
"warnings": [{"check_id": 1, "check_message": "Warning message 1"}],
"notes": [{"check_id": 2, "check_message": "Note message 1"}],
}
],
"feature2": [
{
"warnings": [{"check_id": 3, "check_message": "Warning message 2"}],
"notes": [{"check_id": 4, "check_message": "Note message 2"}],
}
],
}
}
}
check_upload_status_request_mock = mocker.patch.object(AIOps_client, "check_upload_status_request")
check_upload_status_request_mock.return_value = "COMPLETED_WITH_SUCCESS"
download_bpa_request_mock = mocker.patch.object(AIOps_client, "download_bpa_request")
download_bpa_request_mock.return_value = "cloud.com"
download_bpa_request_mock = mocker.patch.object(AIOps_client, "data_of_download_bpa_request")
download_bpa_request_mock.return_value = bpa_json
args = {"report_id": "123456789", "show_in_context": "true", "export_as_file": "true"}
generate_access_token_request_mock = mocker.patch.object(AIOps_client, "generate_access_token_request")
generate_access_token_request_mock.return_value = {}
mocker.patch("PaloAltoNetworksAIOps.fileResult", return_value={"File": "report-id-123456789.md"})
result = polling_until_upload_report_command(args, AIOps_client)
assert not result[0].scheduled_command
assert result[0].readable_output == (
"### BPA results:\n|Check Id|Check Category|Check Feature|Check Message|Check Type|\n"
"|---|---|---|---|---|\n| 1 | device | feature1 | Warning message 1 | warning |\n"
"| 2 | device | feature1 | Note message 1 | note |\n| 3 | device | feature2 | "
"Warning message 2 | warning |\n| 4 | device | feature2 | Note message 2 | note |\n"
)
assert result[0].outputs == [
{
"report_id": "123456789",
"report_status": "COMPLETED_WITH_SUCCESS",
"data": [
{
"check_id": 1,
"check_message": "Warning message 1",
"check_type": "warning",
"check_feature": "feature1",
"check_category": "device",
},
{
"check_id": 2,
"check_message": "Note message 1",
"check_type": "note",
"check_feature": "feature1",
"check_category": "device",
},
{
"check_id": 3,
"check_message": "Warning message 2",
"check_type": "warning",
"check_feature": "feature2",
"check_category": "device",
},
{
"check_id": 4,
"check_message": "Note message 2",
"check_type": "note",
"check_feature": "feature2",
"check_category": "device",
},
],
}
]
assert result[1].get("File") == "report-id-123456789.md"
def test_polling_until_upload_report_command_completed_with_success_no_context(mocker, AIOps_client):
from PaloAltoNetworksAIOps import polling_until_upload_report_command
bpa_json = {
"best_practices": {
"device": {
"feature1": [
{
"warnings": [{"check_id": 1, "check_message": "Warning message 1"}],
"notes": [{"check_id": 2, "check_message": "Note message 1"}],
}
],
"feature2": [
{
"warnings": [{"check_id": 3, "check_message": "Warning message 2"}],
"notes": [{"check_id": 4, "check_message": "Note message 2"}],
}
],
}
}
}
check_upload_status_request_mock = mocker.patch.object(AIOps_client, "check_upload_status_request")
check_upload_status_request_mock.return_value = "COMPLETED_WITH_SUCCESS"
download_bpa_request_mock = mocker.patch.object(AIOps_client, "download_bpa_request")
download_bpa_request_mock.return_value = "cloud.com"
download_bpa_request_mock = mocker.patch.object(AIOps_client, "data_of_download_bpa_request")
download_bpa_request_mock.return_value = bpa_json
args = {"report_id": "123456789", "show_in_context": "false", "export_as_file": "false"}
generate_access_token_request_mock = mocker.patch.object(AIOps_client, "generate_access_token_request")
generate_access_token_request_mock.return_value = {}
result = polling_until_upload_report_command(args, AIOps_client)
assert not result[0].scheduled_command
assert result[0].readable_output == (
"### BPA results:\n|Check Id|Check Category|Check Feature|Check Message|Check Type|\n"
"|---|---|---|---|---|\n| 1 | device | feature1 | Warning message 1 | warning |\n"
"| 2 | device | feature1 | Note message 1 | note |\n| 3 | device | feature2 | "
"Warning message 2 | warning |\n| 4 | device | feature2 | Note message 2 | note |\n"
)
assert not result[0].outputs
assert len(result) == 1
def test_get_info_about_device_request_called_with(mocker, AIOps_client):
"""
Given:
- All relevant arguments for the command that is executed
When:
- Calling get_info_about_device_request
Then:
- Checks the get_info_about_device_request request (the request that is calles)
"""
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
response_text = (
'test1.1.1.1'
""
)
response_mock = mocker.Mock()
response_mock.text = response_text
http_request_mock.return_value = response_mock
AIOps_client.get_info_about_device_request()
http_request_mock.assert_called_once_with(
"GET",
"/api",
params={"type": "op", "cmd": "", "key": "api_key"},
headers={"Content-Type": "application/xml"},
resp_type="xml",
)
def test_get_info_about_device_request_return(mocker, AIOps_client):
"""
Given:
- All relevant arguments for the command that is executed
When:
- Calling get_info_about_device_request
Then:
- Checks the get_info_about_device_request output (using adjust_xml_format)
"""
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
response_text = (
'test1.1.1.1'
""
)
response_mock = mocker.Mock()
response_mock.text = response_text
http_request_mock.return_value = response_mock
result = AIOps_client.get_info_about_device_request()
assert result == "test1.1.1.1"
def test_get_info_about_device_request_fails(mocker: MockerFixture, AIOps_client):
"""
Given:
- All relevant arguments for the command that is executed
When:
- Calling get_info_about_device_request
Then:
- Raise an error since response not in format
"""
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
from CommonServerPython import DemistoException
response_text = (
'test1.1.1.1'
""
)
response_mock = mocker.Mock()
response_mock.text = response_text
http_request_mock.return_value = response_mock
with pytest.raises(DemistoException) as e:
AIOps_client.get_info_about_device_request()
assert e.value.message == ("Request Succeeded, A parse error occurred- could not find system tag to adjust to AIOps API.")
def test_get_config_file_request_called_with(mocker, AIOps_client):
"""
Given:
- All relevant arguments for the command that is executed
When:
- Calling get_config_file_request
Then:
- Checks the get_config_file_request request (the request that is calles)
"""
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
response_text = (
'khbk,g\n'
)
response_mock = mocker.Mock()
response_mock.text = response_text
http_request_mock.return_value = response_mock
AIOps_client.get_config_file_request()
http_request_mock.assert_called_once_with(
"GET",
"/api",
params={"type": "config", "action": "show", "key": "api_key"},
headers={"Content-Type": "application/xml"},
resp_type="xml",
)
def test_get_config_file_request_return(mocker, AIOps_client):
"""
Given:
- All relevant arguments for the command that is executed
When:
- Calling get_config_file_request
Then:
- Checks the get_info_about_device_request output (using adjust_xml_format)
"""
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
response_text = (
'khbk,g\n'
)
response_mock = mocker.Mock()
response_mock.text = response_text
http_request_mock.return_value = response_mock
result = AIOps_client.get_config_file_request()
assert result == (
'khbk,g\n'
)
def test_get_config_file_request_fails(mocker: MockerFixture, AIOps_client):
"""
Given:
- All relevant arguments for the command that is executed
When:
- Calling get_config_file_request
Then:
- Raise an error since response not in format
"""
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
from CommonServerPython import DemistoException
response_text = (
'khbk,g\n'
)
response_mock = mocker.Mock()
response_mock.text = response_text
http_request_mock.return_value = response_mock
with pytest.raises(DemistoException) as e:
AIOps_client.get_config_file_request()
assert e.value.message == ("Request Succeeded, A parse error occurred- could not find config tag to adjust to AIOps API.")
def test_generate_bpa_report_request_called_with(mocker, AIOps_client):
"""
Given:
- All relevant arguments for the command that is executed
When:
- Calling generate_bpa_report_request
Then:
- Checks the generate_bpa_report_request request (the request that is calles)
"""
requester_email = "test@gmail.com"
requester_name = "test"
dict_for_request = {"family": "test1", "model": "test2", "serial": "test3", "sw-version": "test4"}
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
response = {"upload-url": "qejdhliqhjqo;jo'kqp", "id": "1"}
http_request_mock.return_value = response
AIOps_client.generate_bpa_report_request(requester_email, requester_name, dict_for_request)
http_request_mock.assert_called_once_with(
method="POST",
full_url="https://api.stratacloud.paloaltonetworks.com/aiops/bpa/v1/requests",
headers={"Content-Type": "application/json", "Accept": "application/json", "Authorization": "Bearer None"},
json_data={
"requester-email": "test@gmail.com",
"requester-name": "test",
"serial": "test3",
"version": "test4",
"model": "test2",
"family": "test1",
},
)
def test_generate_bpa_report_request_return(mocker, AIOps_client):
"""
Given:
- All relevant arguments for the command that is executed
When:
- Calling get_config_file_request
Then:
- Checks the generate_bpa_report_request output (using adjust_xml_format)
"""
requester_email = "test@gmail.com"
requester_name = "test"
dict_for_request = {"family": "test1", "model": "test2", "serial": "test3", "sw-version": "test4"}
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
response = {"upload-url": "qejdhliqhjqo;jo'kqp", "id": "1"}
http_request_mock.return_value = response
result = AIOps_client.generate_bpa_report_request(requester_email, requester_name, dict_for_request)
assert result == ("qejdhliqhjqo;jo'kqp", "1")
def test_generate_bpa_report_request_fails(mocker: MockerFixture, AIOps_client):
"""
Given:
- All relevant arguments for the command that is executed
When:
- Calling generate_bpa_report_request
Then:
- Raise an error since response not in format
"""
from CommonServerPython import DemistoException
requester_email = "test@gmail.com"
requester_name = "test"
dict_for_request = {"family": "test1", "model": "test2", "serial": "test3", "sw-version": "test4"}
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
response = {"upload-url1": "qejdhliqhjqo;jo'kqp", "id": "1"}
http_request_mock.return_value = response
with pytest.raises(DemistoException) as e:
AIOps_client.generate_bpa_report_request(requester_email, requester_name, dict_for_request)
res = {"upload-url1": "qejdhliqhjqo;jo'kqp", "id": "1"}
assert e.value.message == f"Response not in format, can not find uploaded-url or report id. With response {res}."
def test_config_file_to_report_request_called_with(mocker, AIOps_client):
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
uploaded_url = "cloud.test"
config_binary = b'\n test'
AIOps_client.config_file_to_report_request(uploaded_url, config_binary)
http_request_mock.assert_called_once_with(
method="PUT",
full_url="cloud.test",
headers={"Content-Type": "application/octet-stream", "Accept": "*/*", "Authorization": "Bearer None"},
data=b'\n test',
empty_valid_codes=[200],
return_empty_response=True,
)
def test_config_file_to_report_request_check_return(mocker, AIOps_client):
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
http_request_mock.return_value = {"reason": "OK", "ok": True}
uploaded_url = "cloud.test"
config_binary = b'\n test'
result = AIOps_client.config_file_to_report_request(uploaded_url, config_binary)
assert result["ok"]
assert result["reason"] == "OK"
def test_config_file_to_report_request_fails(mocker, AIOps_client):
from CommonServerPython import DemistoException
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
http_request_mock.side_effect = DemistoException(message="API ERROR - [404]")
uploaded_url = "cloud.test"
config_binary = b'\n test'
with pytest.raises(DemistoException) as e:
AIOps_client.config_file_to_report_request(uploaded_url, config_binary)
assert e.value.message == "API ERROR - [404]"
def test_check_upload_status_request_called_with(mocker, AIOps_client):
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
report_id = "123456789"
AIOps_client.check_upload_status_request(report_id)
http_request_mock.assert_called_once_with(
method="GET",
full_url="https://api.stratacloud.paloaltonetworks.com/aiops/bpa/v1/jobs/123456789",
headers={"Accept": "*/*", "Authorization": "Bearer None"},
)
def test_check_upload_status_request_check_return(mocker, AIOps_client):
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
http_request_mock.return_value = {"status": "COMPLETED_WITH_SUCCESS"}
report_id = "123456789"
result = AIOps_client.check_upload_status_request(report_id)
assert result in ["COMPLETED_WITH_SUCCESS", "UPLOAD_INITIATED", "COMPLETED_WITH_ERROR", "CONFIG_PARSED"]
def test_check_upload_status_request_invalid_response(mocker, AIOps_client):
from CommonServerPython import DemistoException
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
http_request_mock.return_value = {"statuss": "COMPLETED_WITH_SUCCESS"}
report_id = "123456789"
with pytest.raises(DemistoException) as e:
AIOps_client.check_upload_status_request(report_id)
assert e.value.message == "Missing upload status, Error: parse Error."
def test_download_bpa_request_called_with(mocker, AIOps_client):
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
report_id = "123456789"
AIOps_client.download_bpa_request(report_id)
http_request_mock.assert_called_once_with(
method="GET",
full_url=("https://api.stratacloud.paloaltonetworks.com/aiops/bpa/v1/reports/123456789"),
headers={"Accept": "application/json", "Authorization": "Bearer None"},
)
def test_download_bpa_request_check_return(mocker, AIOps_client):
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
http_request_mock.return_value = {"download-url": "cloud.com"}
report_id = "123456789"
result = AIOps_client.download_bpa_request(report_id)
assert result == "cloud.com"
def test_download_bpa_request_invalid_response(mocker, AIOps_client):
from CommonServerPython import DemistoException
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
http_request_mock.return_value = {}
report_id = "123456789"
with pytest.raises(DemistoException) as e:
AIOps_client.download_bpa_request(report_id)
assert e.value.message == "Missing download-url, Error: parse Error."
def test_data_of_download_bpa_request_called_with(mocker, AIOps_client):
http_request_mock = mocker.patch.object(AIOps_client, "_http_request")
downloaded_BPA_url = "cloud.com"
AIOps_client.data_of_download_bpa_request(downloaded_BPA_url)
http_request_mock.assert_called_once_with(method="GET", full_url="cloud.com", headers={"Authorization": "Bearer None"})
""" HELPER FUNCTIONS"""
def test_adjust_xml_format():
"""
Given:
- xml string
- new tag root
When:
- Calling adjust_xml_format
Then:
- Get the wanted result
"""
from PaloAltoNetworksAIOps import adjust_xml_format
xml_data = (
'test1.2.3.4'
""
)
new_root_tag = "system"
result = adjust_xml_format(xml_data, new_root_tag)
assert result == "test1.2.3.4"
def test_adjust_xml_format_invalid():
"""
Given:
- xml string
- new root tag
When:
- Calling adjust_xml_format
Then:
- raise an error since a mismatch with new root tag in xml_string
"""
from CommonServerPython import DemistoException
from PaloAltoNetworksAIOps import adjust_xml_format
xml_data = (
'test1.2.3.4'
""
)
new_root_tag = "systems"
with pytest.raises(DemistoException) as e:
adjust_xml_format(xml_data, new_root_tag)
assert e.value.message == "Request Succeeded, A parse error occurred- could not find systems tag to adjust to AIOps API."
def test_get_values_from_xml():
"""
Given:
- xml string
- array of tags
When:
- Calling get_values_from_xml
Then:
- Get the wanted result
"""
from PaloAltoNetworksAIOps import get_values_from_xml
tags = ["family", "model", "serial", "sw-version"]
xml_string = (
"test1test2test3test"
"test41.1.1.1"
)
result = get_values_from_xml(xml_string, tags)
assert result == ["test1", "test2", "test3", "test4"]
def test_get_values_from_xml_invalid():
"""
Given:
- xml string
- array of tags
When:
- Calling get_values_from_xml
Then:
- raise an error since a mismatch tags in xml_string
"""
from CommonServerPython import DemistoException
from PaloAltoNetworksAIOps import get_values_from_xml
tags = ["family", "model", "serial", "sw-version"]
xml_string = (
"test1test2test3test"
"test41.1.1.1"
)
with pytest.raises(DemistoException) as e:
get_values_from_xml(xml_string, tags)
assert e.value.message == (
"Could not find the required tags in the System file. Error: 'NoneType' object has no attribute 'text'"
)
def test_convert_config_to_bytes_with_user_flag(mocker, AIOps_client):
"""
Given:
- flag is User
- path to file from user
When:
- Calling convert_config_to_bytes with user flag
Then:
- succeed to convert into bytes
"""
from PaloAltoNetworksAIOps import convert_config_to_bytes
config_file_path = "/path/to/config_file.txt"
expected_bytes = b'test'
with (
patch("builtins.open", mock_open(read_data=expected_bytes)) as mock_open_func,
patch("demistomock.getFilePath", return_value={"path": config_file_path}),
):
result_bytes = convert_config_to_bytes("config_file.txt", "User")
assert result_bytes == expected_bytes
mock_open_func.assert_called_once_with(config_file_path, "rb")
def test_convert_config_to_bytes_get_path_exception():
"""
Given:
- flag is User
- path to file from user
When:
- Calling convert_config_to_bytes with user flag
Then:
- Raise a file convertion error
"""
from CommonServerPython import DemistoException
from PaloAltoNetworksAIOps import convert_config_to_bytes
with patch("demistomock.getFilePath", side_effect=Exception("invalid to parse")), pytest.raises(DemistoException) as e:
convert_config_to_bytes("config_file.txt", "User")
assert e.value.message == (
"The config file upload was unsuccessful or the file could not be converted. With error: invalid to parse."
)
def test_convert_config_to_bytes_invalid_getFilePath_response():
"""
Given:
- flag is User
- path to file from user
When:
- Calling convert_config_to_bytes with user flag
Then:
- Raise a file convertion error
"""
from CommonServerPython import DemistoException
from PaloAltoNetworksAIOps import convert_config_to_bytes
with patch("demistomock.getFilePath", return_value={}), pytest.raises(DemistoException) as e:
convert_config_to_bytes("config_file.txt", "User")
assert e.value.message == "The config file upload was unsuccessful or the file could not be converted. With error: 'path'."
def test_convert_config_to_bytes_with_download_flag(mocker, AIOps_client):
"""
Given:
- flag is Download
When:
- Calling convert_config_to_bytes with Download flag
Then:
- succeed to convert into bytes
"""
from PaloAltoNetworksAIOps import convert_config_to_bytes
config_file = "test"
expected_bytes = b'\n test'
result = convert_config_to_bytes(config_file, "Download")
assert result == expected_bytes
def test_convert_config_to_bytes_converted_with_exception():
"""
Given:
- flag is User
- path to file from user
When:
- Calling convert_config_to_bytes with user flag
Then:
- Raise a file convertion error
"""
from CommonServerPython import DemistoException
from PaloAltoNetworksAIOps import convert_config_to_bytes
config_file = "test"
with patch("io.StringIO", side_effect=Exception), pytest.raises(DemistoException) as e:
convert_config_to_bytes(config_file, "Download")
assert e.value.message == "The downloaded config file from Panorama/Pan-os could not be converted."
def test_create_readable_output_checks_result():
"""
Given:
- response dict
When:
- Calling convert_response_for_hr
Then:
- convert response to the right format
"""
from PaloAltoNetworksAIOps import convert_response_for_hr
bpa_dict = {
"best_practices": {
"device": {
"feature1": [
{
"warnings": [{"check_id": 1, "check_message": "Warning message 1"}],
"notes": [{"check_id": 2, "check_message": "Note message 1"}],
"random_field": [],
}
],
"feature2": [
{
"warnings": [{"check_id": 3, "check_message": "Warning message 2"}],
"notes": [{"check_id": 4, "check_message": "Note message 2"}],
}
],
}
},
"random_key": {},
}
result = convert_response_for_hr(bpa_dict)
assert result == [
{
"check_id": 1,
"check_message": "Warning message 1",
"check_type": "warning",
"check_feature": "feature1",
"check_category": "device",
},
{
"check_id": 2,
"check_message": "Note message 1",
"check_type": "note",
"check_feature": "feature1",
"check_category": "device",
},
{
"check_id": 3,
"check_message": "Warning message 2",
"check_type": "warning",
"check_feature": "feature2",
"check_category": "device",
},
{
"check_id": 4,
"check_message": "Note message 2",
"check_type": "note",
"check_feature": "feature2",
"check_category": "device",
},
]
def test_create_markdown():
"""
Given:
- response array
When:
- Calling create_markdown
Then:
- Create an HR from the response
"""
from PaloAltoNetworksAIOps import create_markdown
response_array = [
{
"check_id": 1,
"check_message": "Warning message 1",
"check_type": "warning",
"check_feature": "feature1",
"check_category": "device",
},
{
"check_id": 2,
"check_message": "Note message 1",
"check_type": "note",
"check_feature": "feature1",
"check_category": "device",
},
{
"check_id": 3,
"check_message": "Warning message 2",
"check_type": "warning",
"check_feature": "feature2",
"check_category": "device",
},
{
"check_id": 4,
"check_message": "Note message 2",
"check_type": "note",
"check_feature": "feature2",
"check_category": "device",
},
]
assert create_markdown(response_array) == (
"### BPA results:\n|Check Id|Check Category|Check Feature|Check Message|Check Type"
"|\n|---|---|---|---|---|\n| 1 | device | feature1 | Warning message 1 | warning |"
"\n| 2 | device | feature1 | Note message 1 "
"| note |\n| 3 | device | feature2 | Warning message 2 | warning |\n| 4 | device "
"| feature2 | Note message 2 | note |\n"
)
def test_create_markdown_empty_array():
"""
Given:
- response empty array
When:
- Calling create_markdown
Then:
- Create an HR from the response- no entries
"""
from PaloAltoNetworksAIOps import create_markdown
response_array = []
assert create_markdown(response_array) == "### BPA results:\n**No entries.**\n"
def test_generate_report_command_email_invalid(mocker, AIOps_client):
"""
Given:
- args with email invalid
When:
- Calling generate_report_command
Then:
- raise an error
"""
from CommonServerPython import DemistoException
from PaloAltoNetworksAIOps import generate_report_command
args = {
"entry_id": "1234",
"requester_email": "testgmail.com",
"requester_name": "test",
"export_as_file": "false",
"show_in_context": "false",
}
generate_access_token_request_mock = mocker.patch.object(AIOps_client, "generate_access_token_request")
generate_access_token_request_mock.return_value = {}
with pytest.raises(DemistoException) as e:
generate_report_command(AIOps_client, args)
assert e.value.message == "Invalid email testgmail.com, please make sure it is a valid email."