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 = ( "\n423 Invalid\n\n

423 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