def test_get_remote_data_command_6_1_and_higher(mocker, params, offense: Dict, enriched_offense, expected: GetRemoteDataResponse): """ Given: - QRadar client. - Demisto params. - Demisto arguments. When: - Case a: Offense updated, not closed, no events. - Case b: Offense updated, closed, no events, close_incident is false. - Case c: Offense updated, closed, no events, close_incident is true. Then: - Case a: Ensure that offense is returned as is. - Case b: Ensure that offense is returned as is. - Case c: Ensure that offense is returned, along with expected entries. """ set_integration_context({'last_update': 1}) mocker.patch.object(client, 'offenses_list', return_value=offense) mocker.patch.object(QRadar_v3, 'enrich_offenses_result', return_value=enriched_offense) if 'close_incident' in params: mocker.patch.object(client, 'closing_reasons_list', return_value=command_test_data['closing_reasons_list']['response'][0]) result = get_remote_data_command(client, params, {'id': offense.get('id'), 'lastUpdate': 1}) assert result.mirrored_object == expected.mirrored_object assert result.entries == expected.entries
def test_reset_offset_command(requests_mock, offset_data, context_data, offset, expected_text, expected_offset): """ Given: - different stored offset configurations and desired offset parameters When: - running the reset offset command Then: - I am told what happened in a human-readable form - the new context has been stored in the integration context """ set_integration_context(context_data) feed = "ip_reputation" requests_mock.get(BASE_URL + "/info?format=jsonl&feedId={}_v2".format(feed), json=offset_data, request_headers=_expected_headers()) client = _create_client(feed) args = dict() if offset is not None: args["offset"] = offset result = reset_offset_command(client, args) assert result.readable_output == expected_text assert get_integration_context() == dict(offset=expected_offset)
def test_create_search_with_retry(mocker, search_exception, fetch_mode, query_expression, search_response): """ Given: - Client to perform API calls. - Query for creating search in QRadar service. When: - Case a: QRadar manages to create search, fetch_mode is all events. - Case b: Error occurred in request to QRadar search creation, fetch_mode is all events. - Case c: QRadar manages to create search, fetch_mode is correlation events only. - Case d: Error occurred in request to QRadar search creation, fetch_mode is correlation events only. Then: - Case a: Ensure that QRadar service response is returned. - Case b: Ensure that None is returned. - Case c: Ensure that QRadar service response is returned. - Case d: Ensure that None is returned. """ set_integration_context(dict()) if search_exception: mocker.patch.object(client, "search_create", side_effect=[search_exception]) else: mocker.patch.object(client, "search_create", return_value=search_response) assert create_search_with_retry(client, fetch_mode=fetch_mode, offense=command_test_data['offenses_list']['response'][0], event_columns=EVENT_COLUMNS_DEFAULT_VALUE, events_limit=20, max_retries=1) == search_response
def test_perform_long_running_loop(mocker, test_data, test_name): """ Given: - socket: Socket to retrieve Syslog messages from. - message_regex: Message regex to match if exists. When: - Performing one loop in the long-running execution Cases: Case 1: Log format is RFC 3164, no message regex. Case 2: Log format is RFC 3164, message regex, passes filter. Case 3: Log format is RFC 3164, message regex, doesn't pass filter. Case 4: Log format is RFC 5424, no message regex. Case 5: Log format is RFC 5424, message regex, passes filter. Case 6: Log format is RFC 5424, message regex, doesn't pass filter. Then: - Ensure incident is created if needed for each case, and exists in context data. """ import Syslogv2 tmp_reg = Syslogv2.MESSAGE_REGEX test_name_data = test_data[test_name] Syslogv2.MESSAGE_REGEX = test_name_data.get('message_regex') set_integration_context({}) incident_mock = mocker.patch.object(demisto, 'createIncidents') if test_name_data.get('expected'): perform_long_running_loop(test_data['log_message'].encode()) assert incident_mock.call_args[0][0] == test_name_data.get('expected') assert get_integration_context() == { 'samples': test_name_data.get('expected') } else: perform_long_running_loop(test_data['log_message'].encode()) assert not demisto.createIncidents.called assert not get_integration_context() Syslogv2.MESSAGE_REGEX = tmp_reg
def test_get_remote_data_command_pre_6_1(mocker, params, args, expected: GetRemoteDataResponse): """ Given: - QRadar client. - Demisto arguments. When: - Command 'get-get-remote-data' is being called. Then: - Ensure that command outputs the IDs of the offenses to update. """ set_integration_context(dict()) enriched_response = command_test_data['get_remote_data'][ 'enrich_offenses_result'] mocker.patch.object( client, 'offenses_list', return_value=command_test_data['get_remote_data']['response']) mocker.patch.object(QRadar_v3, 'enrich_offenses_result', return_value=enriched_response) result = get_remote_data_command(client, params, args) assert result.mirrored_object == expected.mirrored_object assert result.entries == expected.entries
def test_creds_changed(context, client_id, as_expected) -> None: """ Scenario: To detect changes in credentials. When: - When user changes credentials (identity_code). Then: - Change in credentials should be detected correctly. """ from Lansweeper import creds_changed set_integration_context(context) assert creds_changed(get_integration_context(), client_id) is as_expected
def test_reset_triggered_stops_enrichment_test(func, args, expected): """ Given: - Reset last run command was triggered. When: - Function given is executed. Then: - Ensure that function notices reset flag and stops its run. """ set_integration_context({RESET_KEY: True}) assert func(**args) == expected set_integration_context({})
def test_fetch_samples(samples: list[dict], mocker): """ Given: When: - Calling fetch samples Then: - Ensure samples in context are returned. """ set_integration_context({'samples': samples}) mock_incident = mocker.patch.object(demisto, 'incidents') fetch_samples() assert mock_incident.call_args[0][0] == samples
def test_invalidate_context(context) -> None: """ Scenario: Demisto integration context should be invalidated if credentials are changed. Given: - User has provided new credentials. When: - When user changes credentials (identity_code). Then: - Integration context should be invalidated. """ from Lansweeper import update_context set_integration_context(context) update_context("new_identity_code") assert get_integration_context() == {"identity_code": "new_identity_code"}
def test_get_modified_remote_data_command(mocker): """ Given: - QRadar client. - Demisto arguments. When: - Command 'get-modified-remote-data' is being called. Then: - Ensure that command outputs the IDs of the offenses to update. """ set_integration_context(dict()) expected = GetModifiedRemoteDataResponse(list(map(str, command_test_data['get_modified_remote_data']['outputs']))) mocker.patch.object(client, 'offenses_list', return_value=command_test_data['get_modified_remote_data']['response']) result = get_modified_remote_data_command(client, dict(), command_test_data['get_modified_remote_data']['args']) assert expected.modified_incident_ids == result.modified_incident_ids
def test_update_integration_context_samples(init_ctx, incident, sample_size, expected_context): """ Given: - incident: Incident. When: - Updating the samples with the given incident. Cases: Case 1: Context is empty. Case 2: Context is not empty, samples size not reached. Case 2: Context is not empty, samples size reached. Case 2: Context is not empty, samples size reached. Then: - Ensure context is updated as expected """ set_integration_context(init_ctx) update_integration_context_samples(incident, sample_size) assert get_integration_context() == {'samples': expected_context}
def test_perform_long_running_loop(mocker, test_data, test_name): """ Given: - socket: Socket to retrieve Syslog messages from. - message_regex: Message regex to match if exists. When: - Performing one loop in the long-running execution Cases: Case 1: Log format is RFC 3164, no message regex. Case 2: Log format is RFC 3164, message regex, passes filter. Case 3: Log format is RFC 3164, message regex, doesn't pass filter. Case 4: Log format is RFC 5424, no message regex. Case 5: Log format is RFC 5424, message regex, passes filter. Case 6: Log format is RFC 5424, message regex, doesn't pass filter. Then: - Ensure incident is created if needed for each case, and exists in context data. """ import Syslogv2 tmp_reg = Syslogv2.MESSAGE_REGEX test_name_data = test_data[test_name] Syslogv2.MESSAGE_REGEX = test_name_data.get('message_regex') set_integration_context({}) incident_mock = mocker.patch.object(demisto, 'createIncidents') if test_name_data.get('expected'): perform_long_running_loop(test_data['log_message'].encode()) # Deleting timestamp, because it is retrieved by current year. current_year = str(datetime.now().year) for res in test_name_data['expected']: for replace_field in ['rawJSON', 'name', 'details']: res[replace_field] = res[replace_field].replace( 'REPLACE_WITH_CURRENT_YEAR', current_year) assert incident_mock.call_args[0][0] == test_name_data.get('expected') assert get_integration_context() == { 'samples': test_name_data.get('expected') } else: perform_long_running_loop(test_data['log_message'].encode()) assert not demisto.createIncidents.called assert not get_integration_context() Syslogv2.MESSAGE_REGEX = tmp_reg
def test_get_indicators(requests_mock, phishing_urls, context_data, offsets, max_indicators, expected_offset, expected_count): """ Given: - the phishing URL feed When: - running get-indicators Then: - no adjustments made to the integration context - the number of indicators is taken from the response, meaning 4 entries """ set_integration_context(context_data) _, get = _create_instance(requests_mock, "phishing_urls", phishing_urls, offsets, expected_offset, expected_count) result = get(max_indicators) assert len(result.raw_response) == 8 assert get_integration_context() == context_data
def test_fetch_indicators_offsets(requests_mock, ip_reputation, context_data, offsets, initial_count, max_indicators, expected_offset, expected_count): """ Given: - the IP reputation feed When: - running fetch-indicators Then: - the new offset in the integration context is the max offset from the entries + 1 - the number of imported indicators is the number of IP's in the feed """ set_integration_context(context_data) fetch, _ = _create_instance(requests_mock, "ip_reputation", ip_reputation, offsets, expected_offset, expected_count) created = fetch(initial_count, max_indicators, True) assert len(created) == 8 assert get_integration_context() == dict(offset=50007)
def test_get_offset_command(requests_mock, offset_data, context_data, expected_text): """ Given: - different stored offset configurations When: - running the get offset command Then: - I am told what the offset is """ set_integration_context(context_data) feed = "ip_reputation" requests_mock.get(BASE_URL + "/info?format=jsonl&feedId={}_v2".format(feed), json=offset_data, request_headers=_expected_headers()) client = _create_client(feed) result = get_offset_command(client, dict()) assert result.readable_output == expected_text
def fixture_clean_integration_context(): set_integration_context({}) yield set_integration_context({})