import json
import os
from unittest import mock
import pytest
from CommonServerPython import DemistoException
from test_data import input_data
BASE_URL = "https://mocked_url/v1/"
URL_SUFFIX = {"REPORTS": "reports", "PROGRAMS": "me/programs"}
def util_load_json(path):
with open(path, encoding="utf-8") as f:
return json.loads(f.read())
@pytest.fixture()
def client():
from HackerOne import Client
return Client(
"https://mocked_url/v1",
False,
False,
auth=("user", "user123"),
max_fetch=1,
first_fetch="2020-09-07T04:59:51Z",
program_handle=["checker_program_h1b"],
severity="",
state="",
filters="",
)
def test_test_module_when_valid_response_is_returned(client, requests_mock):
"""
Test test_module function for success cases.
Given
- A valid response
When
- The status code returned is 200
Then
- Ensure test module should return success
"""
from HackerOne import test_module
requests_mock.get(BASE_URL + URL_SUFFIX["PROGRAMS"], status_code=200, json="{}")
assert test_module(client) == "ok"
def test_test_module_when_isfetch_is_true(requests_mock, client):
"""
Test test_module function when isFetch is True.
Given
- A valid response
When
- The status code returned is 200 and is_fetch is true
Then
- Ensure test module should return success
"""
from HackerOne import test_module
requests_mock.get(BASE_URL + URL_SUFFIX["PROGRAMS"], json={"page_size": 1}, status_code=200)
requests_mock.get(BASE_URL + URL_SUFFIX["REPORTS"], json={"filter[program][]": ["abc"]}, status_code=200)
assert test_module(client) == "ok"
def test_test_module_when_authentication_error_is_returned(requests_mock, client):
"""
Test test_module function for failure cases.
Given
- an error status code
When
- the user can't be authenticated
Then
- raise DemistoException
"""
from HackerOne import test_module
requests_mock.get(BASE_URL + URL_SUFFIX["PROGRAMS"], status_code=400, json={})
with pytest.raises(DemistoException):
test_module(client)
@pytest.mark.parametrize("status_code, error_msg, expected_error_message", input_data.exception_handler_params)
def test_exception_handler_json(status_code, error_msg, expected_error_message, client):
"""
To test exception handler in various http error code.
Given
- a dictionary containing http error code.
When
- initializing client.
Then
- raise DemistoException
"""
mocked_response = mock.Mock()
mocked_response.status_code = status_code
mocked_response.json.return_value = error_msg
mocked_response.headers = {"Content-Type": "application/json"}
with pytest.raises(DemistoException) as err:
client.exception_handler(mocked_response)
assert str(err.value) == expected_error_message
def test_exception_handler_not_json(client):
"""
To test exception handler in various http error code.
Given
- 423 error code
When
- initializing client.
Then
- raise DemistoException
"""
status_code = 423
error_msg = (
"\n
423 Invalid\n\n423 Invalid
"
"\n
nginx\n\n"
)
expected_error_message = "Unable to retrieve the data based on arguments."
mocked_response = mock.Mock()
mocked_response.status_code = status_code
mocked_response.json.return_value = error_msg
mocked_response.headers = {"Content-Type": "text/html"}
with pytest.raises(DemistoException) as err:
client.exception_handler(mocked_response)
assert str(err.value) == expected_error_message
def test_hackerone_program_list_command_when_valid_response_is_returned(client, requests_mock):
"""
Test case scenario for successful execution of hackerone-program-list command.
Given:
- command arguments for list program command
When:
- Calling `hackerone-program-list` command
Then:
- Returns the response data
"""
from HackerOne import hackerone_program_list_command
response = util_load_json(os.path.join("test_data", "program/program_command_response.json"))
requests_mock.get(BASE_URL + URL_SUFFIX["PROGRAMS"], json=response, status_code=200)
context_output = util_load_json(os.path.join("test_data", "program/program_command_context.json"))
with open(os.path.join("test_data", "program/program_command_readable_output.md")) as f:
readable_output = f.read()
# Execute
command_response = hackerone_program_list_command(client, {})
# Assert
assert command_response.outputs_prefix == "HackerOne.Program"
assert command_response.outputs_key_field == "id"
assert command_response.outputs == context_output
assert command_response.readable_output == readable_output
def test_hackerone_program_list_command_when_empty_response_is_returned(client, requests_mock):
"""
Test case scenario for successful execution of hackerone-program-list command with an empty response.
Given:
- command arguments for list program command
When:
- Calling `hackerone-program-list` command
Then:
- Returns no records for the given input arguments
"""
from HackerOne import hackerone_program_list_command
expected_response = {"data": [], "links": []}
requests_mock.get(BASE_URL + URL_SUFFIX["PROGRAMS"], status_code=200, json=expected_response)
readable_output = "No programs were found for the given argument(s)."
# Execute
command_response = hackerone_program_list_command(client, {})
# Assert
assert command_response.readable_output == readable_output
@pytest.mark.parametrize("args, expected_error", input_data.invalid_args_for_program_list)
def test_hackerone_program_list_command_when_invalid_args_provided(client, args, expected_error):
"""
Test case scenario when invalid arguments are provided.
Given:
- invalid command arguments for list program command
When
- Calling `hackerone-program-list`
Then:
- Returns the response message of invalid input arguments
"""
from HackerOne import hackerone_program_list_command
with pytest.raises(ValueError) as err:
hackerone_program_list_command(client, args)
assert str(err.value) == expected_error
@pytest.mark.parametrize("args, expected_params", input_data.report_list_args)
def test_validate_report_list_args_when_valid_args_are_provided(args, expected_params):
"""
Test case scenario when report list valid arguments are provided.
Given:
- valid command arguments for list report command
When
- Calling `prepare_report_list_args`
Then:
- Returns the expected params.
"""
from HackerOne import prepare_report_list_args
assert prepare_report_list_args(args) == expected_params
def test_hackerone_report_list_command_when_empty_response_is_returned(client, requests_mock):
"""
Test case scenario for successful execution of hackerone-report-list command with an empty response.
Given:
- command arguments for list report command
When:
- Calling `hackerone-report-list` command
Then:
- Returns no records for the given input arguments
"""
from HackerOne import hackerone_report_list_command
expected_response = {"data": [], "links": []}
requests_mock.get(BASE_URL + URL_SUFFIX["REPORTS"], json=expected_response, status_code=200)
readable_output = "No reports were found for the given argument(s)."
# Execute
command_response = hackerone_report_list_command(client, {"program_handle": "abc"})
# Assert
assert command_response.readable_output == readable_output
def test_hackerone_report_list_command_when_valid_response_is_returned(client, requests_mock):
"""
Test case scenario for successful execution of hackerone-report-list command.
Given:
- command arguments for list report command
When:
- Calling `hackerone-report-list` command
Then:
- Returns the response data
"""
from HackerOne import hackerone_report_list_command
response = util_load_json(os.path.join("test_data", "report/report_command_response.json"))
requests_mock.get(BASE_URL + URL_SUFFIX["REPORTS"], json=response, status_code=200)
context_output = util_load_json(os.path.join("test_data", "report/report_command_context.json"))
with open(os.path.join("test_data", "report/report_command_readable_output.md")) as f:
readable_output = f.read()
# Execute
command_response = hackerone_report_list_command(client, {"program_handle": "abc"})
# Assert
assert command_response.outputs_prefix == "HackerOne.Report"
assert command_response.outputs_key_field == "id"
assert command_response.outputs == context_output
assert command_response.readable_output == readable_output
@pytest.mark.parametrize("args, expected_error", input_data.invalid_args_for_report_list)
def test_hackerone_report_list_command_when_invalid_args_provided(client, args, expected_error):
"""
Test case scenario when invalid arguments for report list command are provided.
Given:
- invalid command arguments for list report command
When
- Calling `hackerone-report-list`
Then:
- Returns the response message of invalid input arguments
"""
from HackerOne import hackerone_report_list_command
with pytest.raises(ValueError) as err:
hackerone_report_list_command(client, args)
assert str(err.value) == expected_error
def test_fetch_incident_when_empty_result_is_returned(client, requests_mock):
"""
test case scenario when the results are empty.
Given:
- Fetch incident parameters
When:
- Fetching incidents.
Then:
- Returns empty response for first time
"""
from HackerOne import fetch_incidents
last_run = {"current_created_at": "2020-09-07T04:59:51", "next_page": 2}
expected_response = {"data": [], "links": []}
requests_mock.get(BASE_URL + URL_SUFFIX["REPORTS"], json=expected_response, status_code=200)
fetched_incidents = fetch_incidents(client, last_run)
expected_next_run = {"current_created_at": "2020-09-07T04:59:51", "next_page": 2}
assert fetched_incidents == (expected_next_run, [])
def test_fetch_incident_when_valid_result_is_returned(client, requests_mock):
"""
test case scenario when the results are valid on fetching for the first time.
Given:
- Fetch incident parameters
When:
- Fetching incidents.
Then:
- Ensure that the incidents returned are as expected.
"""
from HackerOne import fetch_incidents
last_run = {}
incident_data = util_load_json(os.path.join("test_data", "incident/raw_response.json"))
requests_mock.get(BASE_URL + URL_SUFFIX["REPORTS"], json=incident_data, status_code=200)
fetched_incidents = fetch_incidents(client, last_run)
next_run = {"next_created_at": "2021-08-09T13:41:38.039Z", "report_ids": ["1295856"]}
incidents = [
{
"name": incident_data.get("data")[0].get("attributes").get("title"),
"occurred": incident_data.get("data")[0].get("attributes").get("created_at"),
"rawJSON": json.dumps(incident_data.get("data")[0]),
}
]
assert fetched_incidents == (next_run, incidents)
def test_fetch_incident_when_getting_already_fetched_report(client, requests_mock):
"""
test case scenario when the results are valid on fetching for the first time.
Given:
- Fetch incident parameters
When:
- Fetching incidents.
Then:
- Ensure that these reports are already fetched previously.
"""
from HackerOne import fetch_incidents
incident_data = util_load_json(os.path.join("test_data", "incident/raw_response.json"))
last_run = {"next_created_at": "2021-08-09T13:41:38.039Z", "report_ids": ["1295856"]}
requests_mock.get(BASE_URL + URL_SUFFIX["REPORTS"], json=incident_data, status_code=200)
fetched_incidents = fetch_incidents(client, last_run)
next_run = {"next_created_at": "2021-08-09T13:41:38.039Z", "report_ids": ["1295856"]}
assert fetched_incidents == (next_run, [])
def test_fetch_incident_when_report_ids_should_be_replaced(client, requests_mock):
"""
Test case scenario when report ids are replaced
Given:
- Fetch incident parameters
When:
- Fetching incidents.
Then:
- Ensure that the report ids are replaced.
"""
from HackerOne import fetch_incidents
incident_data = util_load_json(os.path.join("test_data", "incident/raw_response.json"))
last_run = {"next_created_at": "2020-09-07T04:59:51Z", "report_ids": ["1295852"]}
requests_mock.get(BASE_URL + URL_SUFFIX["REPORTS"], json=incident_data, status_code=200)
fetched_incidents = fetch_incidents(client, last_run)
next_run = {"next_created_at": "2021-08-09T13:41:38.039Z", "report_ids": ["1295856"]}
incidents = [
{
"name": incident_data.get("data")[0].get("attributes").get("title"),
"occurred": incident_data.get("data")[0].get("attributes").get("created_at"),
"rawJSON": json.dumps(incident_data.get("data")[0]),
}
]
assert fetched_incidents == (next_run, incidents)
@pytest.mark.parametrize(
"max_fetch, first_fetch, program_handle, severity, state, filters, page, expected_params",
input_data.valid_params_for_fetch_incidents,
)
def test_fetch_incident_when_valid_params_are_provided(
max_fetch, first_fetch, program_handle, severity, state, filters, page, expected_params
):
"""
test case scenario when valid parameters are provided for fetching the incidents.
Given:
- Valid fetch incident parameters
When:
- Fetching incidents.
Then:
- Prepare params to fetch incidents
"""
from HackerOne import prepare_fetch_incidents_parameters
assert (
prepare_fetch_incidents_parameters(max_fetch, first_fetch, program_handle, severity, state, filters, page)
== expected_params
)
@pytest.mark.parametrize("max_fetch, program_handle,filters, expected_error_msg", input_data.invalid_params_for_fetch_incidents)
def test_fetch_incident_when_invalid_params_are_provided(max_fetch, program_handle, filters, expected_error_msg):
"""
test case scenario when invalid parameters are provided for fetching the incidents.
Given:
- Invalid fetch incident parameters
When:
- Fetching incidents.
Then:
- Returns error for invalid arguments
"""
from HackerOne import validate_fetch_incidents_parameters
with pytest.raises(ValueError) as err:
validate_fetch_incidents_parameters(max_fetch, program_handle, filters)
assert str(err.value) == expected_error_msg