import pytest from Redmine import Client @pytest.fixture def redmine_client(url: str = "url", verify_certificate: bool = True, proxy: bool = False, auth=("username", "password")): return Client(url, verify_certificate, proxy, auth=auth) """ COMMAND FUNCTIONS TESTS """ def test_create_issue_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-create command is executed Then: - The http request is called with the right arguments """ from Redmine import create_issue_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue": {"id": "1"}} args = { "project_id": "1", "issue_id": "1", "subject": "changeFromCode", "priority_id": "1", "tracker_id": "1", "watcher_user_ids": "[1]", "custom_fields": '{"1":"https://test:appear"}', } create_issue_command(redmine_client, args=args) http_request.assert_called_with( "POST", "/issues.json", params={}, json_data={ "issue": { "issue_id": "1", "subject": "changeFromCode", "priority_id": "1", "tracker_id": "1", "custom_fields": [{"id": "1", "value": "https://test:appear"}], "project_id": "1", "watcher_user_ids": [1], } }, headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, ) def test_create_issue_command_with_multiselect_cf(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed (with multiselect custom field) When: - redmine-issue-create command is executed Then: - The http request is called with the right arguments """ from Redmine import create_issue_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue": {"id": "1"}} args = { "project_id": "1", "issue_id": "1", "subject": "changeFromCode", "priority_id": "1", "tracker_id": "1", "watcher_user_ids": "[1]", "custom_fields": '{"4":["a","b","c"],"1":"hello [], my name is paloalto, paloalto"}', } create_issue_command(redmine_client, args=args) http_request.assert_called_with( "POST", "/issues.json", params={}, json_data={ "issue": { "issue_id": "1", "subject": "changeFromCode", "priority_id": "1", "tracker_id": "1", "custom_fields": [ {"id": "4", "value": ["a", "b", "c"]}, {"id": "1", "value": ("hello [], my name is paloalto, paloalto")}, ], "project_id": "1", "watcher_user_ids": [1], } }, headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, ) def test_create_issue_command_not_url_cf(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed without list id When: - redmine-issue-create command is executed Then: - The http request is called with the right arguments """ from Redmine import create_issue_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue": {"id": "1"}} args = { "project_id": "1", "issue_id": "1", "subject": "changeFromCode", "tracker_id": "2", "priority_id": "2", "watcher_user_ids": "[1]", "custom_fields": '{"1":"hello"}', } create_issue_command(redmine_client, args=args) http_request.assert_called_with( "POST", "/issues.json", params={}, json_data={ "issue": { "issue_id": "1", "subject": "changeFromCode", "tracker_id": "2", "priority_id": "2", "custom_fields": [{"id": "1", "value": "hello"}], "project_id": "1", "watcher_user_ids": [1], } }, headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, ) def test_create_issue_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed without list id When: - redmine-issue-create command is executed Then: - The http request return with the expected response """ from Redmine import create_issue_command args = { "project_id": "1", "issue_id": "1", "subject": "testResponse", "tracker_id": "1", "custom_fields": '{"1":"https://test:appear,,,,"}', } create_issue_request_mock = mocker.patch.object(redmine_client, "create_issue_request") create_issue_request_mock.return_value = { "issue": { "id": "789", "project": {"name": "testing", "id": "1"}, "subject": "testResponse", "tracker": {"name": "bug", "id": "1"}, "custom_fields": {"name": "test", "value": "https://test:appear"}, } } result = create_issue_command(redmine_client, args) assert result.readable_output == ( "### The issue you created:\n|Id|Project|Tracker|Subject|Custom Fields|\n|---|---|---|" "---|---|\n| 789 | testing | bug | testResponse | ***name***: test
***value***: " "https://test:appear |\n" ) def test_create_issue_command_with_multiselect_cf_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed without list id (multiselect custom field) When: - redmine-issue-create command is executed Then: - The http request return with the expected response """ from Redmine import create_issue_command args = { "project_id": "1", "issue_id": "1", "subject": "testResponse", "tracker_id": "1", "custom_fields": '{"4":["a","b","c"],"1":"hello [], my name is paloalto, paloalto"}', } create_issue_request_mock = mocker.patch.object(redmine_client, "create_issue_request") create_issue_request_mock.return_value = { "issue": { "id": "789", "project": {"name": "testing", "id": "1"}, "subject": "testResponse", "tracker": {"name": "bug", "id": "1"}, "custom_fields": [ {"name": "test", "value": ["a", "b", "c"]}, {"name": "test2", "value": ("hello [], my name is paloalto, paloalto")}, ], } } result = create_issue_command(redmine_client, args) assert result.readable_output == ( "### The issue you created:\n|Id|Project|Tracker|Subject|Custom Fields|\n|---|---|---|---" "|---|\n| 789 | testing | bug | testResponse | **-**\t***name***: test
\t**value**:
" "\t\t***values***: a, b, c
**-**\t***name***: test2
\t***value***: hello [], my name" " is paloalto, paloalto |\n" ) def test_create_issue_command_invalid_custom_fields(redmine_client): """ Given: - All relevant arguments for the command that is executed and invalid custom field format When: - redmine-issue-create command is executed Then: - A DemistoException is raised- invalid custom field """ from Redmine import create_issue_command from CommonServerPython import DemistoException args = { "project_id": "1", "custom_fields": '{"1https://test:appear,111"}', "issue_id": "1", "subject": "testSub", "tracker": "bug", "watcher_user_ids": "[1]", "priority": "high", } with pytest.raises(DemistoException) as e: create_issue_command(redmine_client, args) assert e.value.message == ( 'Custom fields not in format, please follow this format: `{"customFieldID2": "value3", ' '"customFieldID1": ["value1","value2"]}` - Please use an array if the field is of multiselect type' ". with error: Expecting ':' delimiter: line 1 column 28 (char 27)" ) def test_create_issue_command_no_token_created_for_file(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-create command is executed Then: - The http request is called with the right arguments """ from Redmine import create_issue_command from CommonServerPython import DemistoException create_file_token_request_mock = mocker.patch.object(redmine_client, "create_file_token_request") create_file_token_request_mock.return_value = {"token": "token123"} args = { "project_id": "1", "status": "New", "file_entry_id": "a.png", "issue_id": "1", "subject": "testSub", "tracker": "Bug", "priority": "1", "watcher_user_ids": "[1]", } with pytest.raises(DemistoException) as e: create_issue_command(redmine_client, args) create_file_token_request_mock.assert_called_with({}, "a.png") assert e.value.message == "Could not upload file with entry id a.png, please try again." def test_create_issue_command_with_file(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-create command is executed Then: - The http request is called with the right arguments """ from Redmine import create_issue_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue": {"id": "1"}} create_file_token_request_mock = mocker.patch.object(redmine_client, "create_file_token_request") create_file_token_request_mock.return_value = {"upload": {"token": "token123"}} args = { "project_id": "1", "file_entry_id": "a.png", "issue_id": "1", "subject": "testSub", "tracker_id": "1", "watcher_user_ids": "[1]", "priority_id": "1", } create_issue_command(redmine_client, args=args) create_file_token_request_mock.assert_called_with({}, "a.png") http_request.assert_called_with( "POST", "/issues.json", params={}, json_data={ "issue": { "issue_id": "1", "subject": "testSub", "uploads": [{"token": "token123"}], "tracker_id": "1", "priority_id": "1", "project_id": "1", "watcher_user_ids": [1], } }, headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, ) def test_create_issue_command_with_file_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-create command is executed Then: - The http request return with the expected response with file """ from Redmine import create_issue_command args = { "project_id": "1", "subject": "testResponse", "tracker_id": "1", "file_entry_id": "139i401hivnaflkm", "file_name": "test file response", "priority_id": "1", } create_file_token_request_mock = mocker.patch.object(redmine_client, "create_file_token_request") create_file_token_request_mock.return_value = {"upload": {"token": "111111"}} create_issue_request_mock = mocker.patch.object(redmine_client, "create_issue_request") create_issue_request_mock.return_value = { "issue": { "id": "789", "project": {"name": "testing", "id": "1"}, "subject": "testResponse", "tracker": {"name": "bug", "id": "1"}, } } result = create_issue_command(redmine_client, args) assert args.get("uploads", {})[0].get("token") == "111111" assert args.get("uploads", {})[0].get("filename") == "test file response" assert result.readable_output == ( "### The issue you created:\n|Id|Project|Tracker|Subject|\n|---|---|---|---|\n| 789 | testing | bug | testResponse |\n" ) def test_create_issue_command_with_file_invalid_token_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-create command is executed Then: - Raises an error on token response - not valid """ from Redmine import create_issue_command from CommonServerPython import DemistoException args = { "project_id": "1", "subject": "testResponse", "tracker_id": "1", "file_entry_id": "139i401hivnaflkm", "file_name": "test file response", "priority_id": "1", } create_file_token_request_mock = mocker.patch.object(redmine_client, "create_file_token_request") create_file_token_request_mock.return_value = {"upload": {"tokens": "111111"}} with pytest.raises(DemistoException) as e: create_issue_command(redmine_client, args) assert e.value.message == "Could not upload file with entry id 139i401hivnaflkm, please try again." def test_update_issue_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-update command is executed Then: - The http request is called with the right arguments """ from Redmine import update_issue_command http_request = mocker.patch.object(redmine_client, "_http_request") args = { "issue_id": "1", "subject": "changeFromCode", "tracker_id": "1", "status_id": "1", "priority_id": "1", "watcher_user_ids": "[1]", } update_issue_command(redmine_client, args=args) http_request.assert_called_with( "PUT", "/issues/1.json", json_data={ "issue": { "subject": "changeFromCode", "tracker_id": "1", "status_id": "1", "priority_id": "1", "watcher_user_ids": [1], } }, headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, empty_valid_codes=[204], return_empty_response=True, ) def test_update_issue_command_with_multiselect_cf(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed (with multiselect custom field) When: - redmine-issue-update command is executed Then: - The http request is called with the right arguments """ from Redmine import update_issue_command http_request = mocker.patch.object(redmine_client, "_http_request") args = { "issue_id": "1", "subject": "changeFromCode", "tracker_id": "1", "status_id": "1", "priority_id": "1", "watcher_user_ids": "[1]", "custom_fields": '{"4":["a","b","c"],"1":"hello [], my name is paloalto, paloalto"}', } update_issue_command(redmine_client, args=args) http_request.assert_called_with( "PUT", "/issues/1.json", json_data={ "issue": { "subject": "changeFromCode", "tracker_id": "1", "status_id": "1", "priority_id": "1", "custom_fields": [ {"id": "4", "value": ["a", "b", "c"]}, {"id": "1", "value": ("hello [], my name is paloalto, paloalto")}, ], "watcher_user_ids": [1], } }, headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, empty_valid_codes=[204], return_empty_response=True, ) def test_update_issue_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-update command is executed Then: - The http request returns the right response """ from Redmine import update_issue_command update_issue_request_mock = mocker.patch.object(redmine_client, "update_issue_request") args = { "issue_id": "1", "subject": "changefortest", "tracker_id": "1", "status_id": "1", "priority_id": "1", "watcher_user_ids": "[1]", "custom_fields": '{"4":["a","b","c"],"1":"hello [], my name is paloalto, paloalto"}', } update_issue_request_mock.return_value = {} result = update_issue_command(redmine_client, args=args) assert result.readable_output == "Issue with id 1 was successfully updated." def test_update_issue_command_invalid_custom_fields(redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-update command is executed Then: - Raises a custom fields not in format error """ from Redmine import update_issue_command from CommonServerPython import DemistoException args = { "custom_fields": "jnlnj", "issue_id": "1", "subject": "testSub", "tracker_id": "1", "watcher_user_ids": "[1]", "status_id": "1", "priority_id": "high", } with pytest.raises(DemistoException) as e: update_issue_command(redmine_client, args) assert e.value.message == ( 'Custom fields not in format, please follow this format: `{"customFieldID2": "value3", ' '"customFieldID1": ["value1","value2"]}` - Please use an array if the field is of multiselect type' ". with error: Expecting value: line 1 column 1 (char 0)" ) def test_update_issue_command_no_token_created_for_file(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-delete command is executed Then: - The http request is called with the right arguments """ from Redmine import update_issue_command from CommonServerPython import DemistoException create_file_token_request_mock = mocker.patch.object(redmine_client, "create_file_token_request") create_file_token_request_mock.return_value = {"token": "token123"} args = { "status_id": "1", "file_entry_id": "a.png", "issue_id": "1", "subject": "testSub", "tracker_id": "bug", "priority_id": "1", "watcher_user_ids": "[1]", } with pytest.raises(DemistoException) as e: update_issue_command(redmine_client, args) create_file_token_request_mock.assert_called_with({}, "a.png") assert e.value.message == ("Could not upload file with entry id a.png, please try again.") def test_update_issue_command_with_file(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed without list id When: - redmine-issue-update command is executed Then: - The http request is called with the right arguments """ from Redmine import update_issue_command http_request = mocker.patch.object(redmine_client, "_http_request") create_file_token_request_mock = mocker.patch.object(redmine_client, "create_file_token_request") create_file_token_request_mock.return_value = {"upload": {"token": "token123"}} args = {"file_entry_id": "a.png", "issue_id": "1", "subject": "testSub", "tracker_id": "1", "watcher_user_ids": "[1]"} update_issue_command(redmine_client, args=args) create_file_token_request_mock.assert_called_with({}, "a.png") http_request.assert_called_with( "PUT", "/issues/1.json", json_data={ "issue": {"subject": "testSub", "tracker_id": "1", "uploads": [{"token": "token123"}], "watcher_user_ids": [1]} }, headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, empty_valid_codes=[204], return_empty_response=True, ) def test_field_from_name_to_id_list_command_for_tracker_called_with(mocker, redmine_client): """ Given: - 'trackers' field When: - field_from_name_to_id_list_command func is being called Then: - The http request is called with the right arguments """ from Redmine import field_from_name_to_id_list_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"trackers": [{"id": "1", "name": "bug"}, {"id": "2", "name": "task"}]} field_from_name_to_id_list_command(redmine_client, "trackers") http_request.assert_called_with("GET", "/trackers.json", headers={"X-Redmine-API-Key": True}) def test_field_from_name_to_id_list_command_for_tracker_invalid_response(mocker, redmine_client): """ Given: - 'trackers' field When: - field_from_name_to_id_list_command func is being called Then: - raise an error """ from Redmine import field_from_name_to_id_list_command from CommonServerPython import DemistoException http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"trackerss": [{"id": "1", "name": "bug"}, {"id": "2", "name": "task"}]} with pytest.raises(DemistoException) as e: field_from_name_to_id_list_command(redmine_client, "trackers") assert e.value.message == "Failed to retrieve tracker IDs due to a parsing error." def test_field_from_name_to_id_list_command_for_tracker_check_response(mocker, redmine_client): """ Given: - 'trackers' field When: - field_from_name_to_id_list_command is being called Then: - The expected hr is being shown """ from Redmine import field_from_name_to_id_list_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"trackers": [{"id": "1", "name": "bug"}, {"id": "2", "name": "task"}]} result = field_from_name_to_id_list_command(redmine_client, "trackers") assert result.readable_output == "### trackers name to id List:\n|ID|Name|\n|---|---|\n| 1 | bug |\n| 2 | task |\n" def test_field_from_name_to_id_list_command_for_status_called_with(mocker, redmine_client): """ Given: - 'statuses' field When: - field_from_name_to_id_list_command is being called Then: - The http request is called with the right arguments """ from Redmine import field_from_name_to_id_list_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue_statuses": [{"id": "1", "name": "new"}, {"id": "2", "name": "progress"}]} field_from_name_to_id_list_command(redmine_client, "statuses") http_request.assert_called_with("GET", "/issue_statuses.json", headers={"X-Redmine-API-Key": True}) def test_field_from_name_to_id_list_command_for_status_invalid_response(mocker, redmine_client): """ Given: - 'statuses' field When: - field_from_name_to_id_list_command is being called Then: - raise an error """ from Redmine import field_from_name_to_id_list_command from CommonServerPython import DemistoException http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"statuses": [{"id": "1", "name": "new"}, {"id": "2", "name": "progress"}]} with pytest.raises(DemistoException) as e: field_from_name_to_id_list_command(redmine_client, "statuses") assert e.value.message == "Failed to retrieve status IDs due to a parsing error." def test_field_from_name_to_id_list_command_for_status_check_response(mocker, redmine_client): """ Given: - 'statuses' field When: - field_from_name_to_id_list_command func is being called Then: - The expected hr is being shown """ from Redmine import field_from_name_to_id_list_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue_statuses": [{"id": "1", "name": "new"}, {"id": "2", "name": "progress"}]} result = field_from_name_to_id_list_command(redmine_client, "statuses") assert result.readable_output == "### statuses name to id List:\n|ID|Name|\n|---|---|\n| 1 | new |\n| 2 | progress |\n" def test_field_from_name_to_id_list_command_for_priority_called_with(mocker, redmine_client): """ Given: - 'priorities' field When: - field_from_name_to_id_list_command is being called Then: - The http request is called with the right arguments """ from Redmine import field_from_name_to_id_list_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue_priorities": [{"id": "1", "name": "low"}, {"id": "2", "name": "medium"}]} field_from_name_to_id_list_command(redmine_client, "priorities") http_request.assert_called_with("GET", "/enumerations/issue_priorities.json", headers={"X-Redmine-API-Key": True}) def test_field_from_name_to_id_list_command_for_priority_invalid_response(mocker, redmine_client): """ Given: - 'priorities' field When: - field_from_name_to_id_list_command is being called Then: - raise an error """ from Redmine import field_from_name_to_id_list_command from CommonServerPython import DemistoException http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue_prioritiess": [{"id": "1", "name": "low"}, {"id": "2", "name": "medium"}]} with pytest.raises(DemistoException) as e: field_from_name_to_id_list_command(redmine_client, "priorities") assert e.value.message == "Failed to retrieve priority IDs due to a parsing error." def test_field_from_name_to_id_list_command_for_priority_check_response(mocker, redmine_client): """ Given: - 'priorities' field When: - field_from_name_to_id_list_command func is being called Then: - The expected hr is being shown """ from Redmine import field_from_name_to_id_list_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue_priorities": [{"id": "1", "name": "low"}, {"id": "2", "name": "medium"}]} result = field_from_name_to_id_list_command(redmine_client, "priorities") assert result.readable_output == "### priorities name to id List:\n|ID|Name|\n|---|---|\n| 1 | low |\n| 2 | medium |\n" def test_get_issues_list_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-list command is executed Then: - The http request is called with the right arguments """ from Redmine import get_issues_list_command http_request = mocker.patch.object(redmine_client, "_http_request") args = {"sort": "priority:desc", "limit": "1", "custom_field": "1:https://tests"} get_issues_list_command(redmine_client, args) http_request.assert_called_with( "GET", "/issues.json", params={"status_id": "open", "offset": 0, "limit": 1, "sort": "priority:desc", "cf_1": "https://tests"}, headers={"X-Redmine-API-Key": True}, ) def test_get_issues_list_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-list command is executed Then: - The expected hr is being shown """ from Redmine import get_issues_list_command get_issues_list_request_mock = mocker.patch.object(redmine_client, "get_issues_list_request") get_issues_list_request_mock.return_value = { "issues": [ { "id": "1", "tracker": {"name": "Bug", "id": "1"}, "status": {"name": "new", "id": "1"}, "priority": {"name": "High", "id": "1"}, "subject": "helloTest", } ] } args = {"sort": "priority:desc", "limit": "1"} result = get_issues_list_command(redmine_client, args) assert result.readable_output == ( "#### Showing 1 results from page 1:\n### Issues Results:\n" "|Id|Tracker|Status|Priority|Subject|\n|---|---|---|---|---|\n" "| 1 | Bug | new | High | helloTest |\n" ) def test_get_issues_list_command_invalid_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-list command is executed Then: - raises a response format error """ from Redmine import get_issues_list_command from CommonServerPython import DemistoException get_issues_list_request_mock = mocker.patch.object(redmine_client, "get_issues_list_request") get_issues_list_request_mock.return_value = { "issue": [ { "id": "1", "tracker": {"name": "Bug", "id": "1"}, "status": {"name": "new", "id": "1"}, "priority": {"name": "High", "id": "1"}, "subject": "helloTest", } ] } args = {"sort": "priority:desc", "limit": "1"} with pytest.raises(DemistoException) as e: get_issues_list_command(redmine_client, args) assert e.value.message == "The request succeeded, but a parse error occurred." def test_get_issues_list_command_invalid_custom_field(redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-list command is executed Then: - Raises an exception for invalid custom field """ from Redmine import get_issues_list_command from CommonServerPython import DemistoException with pytest.raises(DemistoException) as e: get_issues_list_command(redmine_client, {"custom_field": "frf2rg2"}) assert e.value.message == ( "Invalid custom field format, please follow the command description. Error: list index out of range." ) def test_get_issues_list_command_use_both_exclude_subproject(redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-list command is executed Then: - Raises an exception for invalid usage of both exclude and subproject fields """ from Redmine import get_issues_list_command from CommonServerPython import DemistoException with pytest.raises(DemistoException) as e: get_issues_list_command(redmine_client, {"subproject_id": "1", "exclude": "2"}) assert e.value.message == "Specify only one of the following, subproject_id or exclude." def test_get_issues_list_command_invalid_status_using_request(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-list command is executed Then: - Raise an error since the status arg is not a number """ from Redmine import get_issues_list_command from CommonServerPython import DemistoException with pytest.raises(DemistoException) as e: mocker.patch.object( redmine_client, "_http_request", return_value={"issue_statuses": [{"id": "1", "name": "New"}, {"id": "2", "name": "Feedback"}]}, ) get_issues_list_command(redmine_client, {"status": "New"}) assert e.value.message == ( "Status argument has to be a predefined value (Open/Closed/All) or a valid status ID but got " 'New. with error: "New" is not a valid number.' ) def test_get_issue_by_id_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-show command is executed Then: - The http request is called with the right arguments """ from Redmine import get_issue_by_id_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"issue": {"id": "1"}} args = {"issue_id": "1", "include": "watchers,attachments"} get_issue_by_id_command(redmine_client, args) http_request.assert_called_with( "GET", "/issues/1.json", params={"include": "watchers,attachments"}, headers={"X-Redmine-API-Key": True} ) def test_get_issue_by_id_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-show command is executed Then: - The expected hr is being shown """ from Redmine import get_issue_by_id_command get_issue_by_id_request_mock = mocker.patch.object(redmine_client, "get_issue_by_id_request") get_issue_by_id_request_mock.return_value = { "issue": { "id": "1", "tracker": {"name": "Bug", "id": "1"}, "status": {"name": "new", "id": "1"}, "priority": {"name": "High", "id": "1"}, "subject": "helloTest", "watchers": [{"name": "testingWatch", "id": "1"}], } } args = {"issue_id": "1", "include": "watchers,attachments"} result = get_issue_by_id_command(redmine_client, args) assert result.readable_output == ( "### Issues List:\n|Id|Tracker|Status|Priority|Subject|Watchers|\n|---|---|---|---|---|---|" "\n| 1 | Bug | new | High | helloTest | **-** ***name***: testingWatch |\n" ) def test_get_issue_by_id_command_invalid_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-show command is executed Then: - raises a response format error """ from Redmine import get_issue_by_id_command from CommonServerPython import DemistoException get_issue_by_id_request_mock = mocker.patch.object(redmine_client, "get_issue_by_id_request") get_issue_by_id_request_mock.return_value = { "id": "1", "tracker": {"name": "Bug", "id": "1"}, "status": {"name": "new", "id": "1"}, "priority": {"name": "High", "id": "1"}, "subject": "helloTest", "watchers": {"name": "testingWatch", "id": "1"}, } args = {"issue_id": "1", "include": "watchers,attachments"} with pytest.raises(DemistoException) as e: get_issue_by_id_command(redmine_client, args) assert e.value.message == "The request succeeded, but a parse error occurred." def test_get_issue_by_id_command_invalid_include_argument(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-show command is executed Then: - No issue id raises a DemistoException """ from Redmine import get_issue_by_id_command from CommonServerPython import DemistoException args = {"sort": "priority:desc", "limit": "1", "include": "beikbfqi"} with pytest.raises(DemistoException) as e: get_issue_by_id_command(redmine_client, args) assert e.value.message == ( "The 'include' argument should only contain values from ['children', 'attachments', 'relations', " "'changesets', 'journals', 'watchers', 'allowed_statuses'], separated by commas. " "These values are not in options {'beikbfqi'}." ) def test_delete_issue_by_id_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-delete command is executed Then: - The expected hr is being shown """ from Redmine import delete_issue_by_id_command delete_issue_by_id_request_mock = mocker.patch.object(redmine_client, "delete_issue_by_id_request") delete_issue_by_id_request_mock.return_value = {} args = {"issue_id": "41"} result = delete_issue_by_id_command(redmine_client, args) assert result.readable_output == "Issue with id 41 was deleted successfully." def test_delete_issue_by_id_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-delete command is executed Then: - The http request is called with the right arguments """ from Redmine import delete_issue_by_id_command http_request = mocker.patch.object(redmine_client, "_http_request") args = {"issue_id": "41"} delete_issue_by_id_command(redmine_client, args) http_request.assert_called_with( "DELETE", "/issues/41.json", headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, empty_valid_codes=[200, 204, 201], return_empty_response=True, ) def test_delete_issue_by_id_command_invalid_issue_id(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-delete command is executed Then: - No issue id raises a DemistoException """ from Redmine import add_issue_watcher_command from CommonServerPython import DemistoException args = {"issue_id": "-1"} http_request = mocker.patch.object(redmine_client, "_http_request") http_request.side_effect = DemistoException( "Invalid ID for one or more fields that request IDs. Please make sure all IDs are correct." ) with pytest.raises(DemistoException) as e: add_issue_watcher_command(redmine_client, args) assert e.value.message == "Invalid ID for one or more fields that request IDs. Please make sure all IDs are correct." def test_add_issue_watcher_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-watcher-add command is executed Then: - The http request returns the right response """ from Redmine import add_issue_watcher_command add_issue_watcher_request_mock = mocker.patch.object(redmine_client, "add_issue_watcher_request") add_issue_watcher_request_mock.return_value = {} args = {"issue_id": "1", "watcher_id": "1"} result = add_issue_watcher_command(redmine_client, args) assert result.readable_output == "Watcher with id 1 was added successfully to issue with id 1." def test_add_issue_watcher_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-watcher-add command is executed Then: - The http request is called with the right arguments """ from Redmine import add_issue_watcher_command http_request = mocker.patch.object(redmine_client, "_http_request") args = {"issue_id": "1", "watcher_id": "1"} add_issue_watcher_command(redmine_client, args) http_request.assert_called_with( "POST", "/issues/1/watchers.json", params={"user_id": "1"}, headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, empty_valid_codes=[200, 204, 201], return_empty_response=True, ) def test_add_issue_watcher_command_invalid_issue_watcher_id(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-watcher-add command is executed Then: - No issue id raises a DemistoException """ from Redmine import add_issue_watcher_command from CommonServerPython import DemistoException args = {"issue_id": "-1", "watcher_id": "-20"} http_request = mocker.patch.object(redmine_client, "_http_request") http_request.side_effect = DemistoException( "Invalid ID for one or more fields that request IDs. Please make sure all IDs are correct." ) with pytest.raises(DemistoException) as e: add_issue_watcher_command(redmine_client, args) assert e.value.message == "Invalid ID for one or more fields that request IDs. Please make sure all IDs are correct." def test_remove_issue_watcher_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-watcher-remove command is executed Then: - The http request is called with the right arguments """ from Redmine import remove_issue_watcher_command http_request = mocker.patch.object(redmine_client, "_http_request") args = {"issue_id": "1", "watcher_id": "1"} remove_issue_watcher_command(redmine_client, args) http_request.assert_called_with( "DELETE", "/issues/1/watchers/1.json", headers={"Content-Type": "application/json", "X-Redmine-API-Key": True}, empty_valid_codes=[200, 204, 201], return_empty_response=True, ) def test_remove_issue_watcher_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-watcher-remove command is executed Then: - The expected hr is being shown """ from Redmine import remove_issue_watcher_command remove_issue_watcher_request_mock = mocker.patch.object(redmine_client, "remove_issue_watcher_request") remove_issue_watcher_request_mock.return_value = {} args = {"issue_id": "1", "watcher_id": "1"} result = remove_issue_watcher_command(redmine_client, args) assert result.readable_output == "Watcher with id 1 was removed successfully from issue with id 1." def test_remove_issue_watcher_command_invalid_issue_watcher_id(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-issue-watcher-remove command is executed Then: - No issue id raises a DemistoException """ from Redmine import remove_issue_watcher_command from CommonServerPython import DemistoException args = {"issue_id": "-1", "watcher_id": "-20"} http_request = mocker.patch.object(redmine_client, "_http_request") http_request.side_effect = DemistoException( "Invalid ID for one or more fields that request IDs. Please make sure all IDs are correct." ) with pytest.raises(DemistoException) as e: remove_issue_watcher_command(redmine_client, args) assert e.value.message == "Invalid ID for one or more fields that request IDs. Please make sure all IDs are correct." def test_get_project_list_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-project-list command is executed Then: - The http request is called with the right arguments """ from Redmine import get_project_list_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"projects": [{"id": "1", "status": "active", "is_public": "true"}]} args = {"include": "time_entry_activities"} get_project_list_command(redmine_client, args) http_request.assert_called_with( "GET", "/projects.json", params={"include": "time_entry_activities"}, headers={"X-Redmine-API-Key": True} ) def test_get_project_list_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-project-list command is executed Then: - The http request returns the right response """ from Redmine import get_project_list_command get_project_list_request_mock = mocker.patch.object(redmine_client, "get_project_list_request") get_project_list_request_mock.return_value = { "projects": [ { "id": "1", "name": "testProject", "issue_custom_fields": {"id": "1", "name": "custom"}, "status": "open", "is_public": True, } ] } args = {"include": "issue_custom_fields"} result = get_project_list_command(redmine_client, args) assert result.readable_output == ( "### Projects List:\n|Id|Name|Status|IsPublic|IssueCustomFields|\n|---|---|---|---|---|" "\n| 1 | testProject | open | True | ***id***: 1
***name***: custom |\n" ) def test_get_project_list_command_invalid_include(redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-project-list command is executed Then: - No issue id raises a DemistoException """ from Redmine import get_project_list_command from CommonServerPython import DemistoException args = {"include": "time_entry_activities,jissue_categories"} with pytest.raises(DemistoException) as e: get_project_list_command(redmine_client, args) assert e.value.message == ( "The 'include' argument should only contain values from ['trackers', 'issue_categories', " "'enabled_modules', 'time_entry_activities', 'issue_custom_fields'], separated by commas." " These values are not in options {'jissue_categories'}." ) def test_get_project_list_command_invalid_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-user-id-list command is executed Then: - The http request is called with the right arguments """ from Redmine import get_project_list_command from CommonServerPython import DemistoException args = {"status_id": "open"} mocker.patch.object(Client, "get_project_list_request", return_value={"projectsss": {}}) with pytest.raises(DemistoException) as e: get_project_list_command(redmine_client, args) assert e.value.message == "The request succeeded, but a parse error occurred." def test_get_custom_fields_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-custom-field-list command is executed Then: - The http request is called with the right arguments """ from Redmine import get_custom_fields_command http_request = mocker.patch.object(redmine_client, "_http_request") http_request.return_value = {"custom_fields": [{"id": "1", "is_required": True, "is_filter": False}]} get_custom_fields_command(redmine_client, {}) http_request.assert_called_with("GET", "/custom_fields.json", headers={"X-Redmine-API-Key": True}) def test_get_custom_fields_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-custom-field-list command is executed Then: - The http request returns the right response """ from Redmine import get_custom_fields_command get_custom_fields_request_mocker = mocker.patch.object(redmine_client, "get_custom_fields_request") get_custom_fields_request_mocker.return_value = { "custom_fields": [ {"id": "1", "name": "custom_test", "is_required": False, "is_filter": True, "trackers": {"name": "Bug", "id": "1"}} ] } result = get_custom_fields_command(redmine_client, {}) assert result.readable_output == ( "### Custom Fields List:\n|Id|Name|IsRequired|IsFilter|Trackers|\n|---|---|---|---|---|\n" "| 1 | custom_test | False | True | ***name***: Bug
***id***: 1 |\n" ) def test_get_custom_fields_command_invalid_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-custom-field-list command is executed Then: - raises a response format error """ from Redmine import get_custom_fields_command from CommonServerPython import DemistoException get_custom_fields_request_mocker = mocker.patch.object(redmine_client, "get_custom_fields_request") get_custom_fields_request_mocker.return_value = { "custom_fieldsss": [ {"id": "1", "name": "custom_test", "is_required": False, "is_filter": True, "trackers": {"name": "Bug", "id": "1"}} ] } args = {} with pytest.raises(DemistoException) as e: get_custom_fields_command(redmine_client, args) assert e.value.message == "The request succeeded, but a parse error occurred." def test_get_users_command(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-user-id-list command is executed Then: - The http request is called with the right arguments """ from Redmine import get_users_command http_request = mocker.patch.object(redmine_client, "_http_request") get_users_command(redmine_client, {"status": "Active"}) http_request.assert_called_with("GET", "/users.json", params={"status": "1"}, headers={"X-Redmine-API-Key": True}) def test_get_users_command_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-user-id-list command is executed Then: - The expected hr is being shown """ from Redmine import get_users_command get_users_request_mock = mocker.patch.object(redmine_client, "get_users_request") get_users_request_mock.return_value = { "users": [{"id": "1", "login": "admin", "admin": True, "firstname": "test", "lastname": "response"}] } result = get_users_command(redmine_client, {}) assert result.readable_output == ( "### Users List:\n|Id|Login|Admin|Firstname|Lastname|\n|---|---|---|---|---|\n| 1 | admin | True | test | response |\n" ) def test_get_users_command_invalid_response(mocker, redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-user-id-list command is executed Then: - Raise a parse error """ from Redmine import get_users_command from CommonServerPython import DemistoException args = {"status_id": "open"} mocker.patch.object(Client, "get_users_request", return_value={"usersss": {}}) with pytest.raises(DemistoException) as e: get_users_command(redmine_client, args) assert e.value.message == "The request succeeded, but a parse error occurred." def test_get_users_command_status_invalid(redmine_client): """ Given: - All relevant arguments for the command that is executed When: - redmine-user-id-list command is executed Then: - Raise an error since the status is invalid """ from Redmine import get_users_command from CommonServerPython import DemistoException with pytest.raises(DemistoException) as e: get_users_command(redmine_client, {"status": "new"}) assert e.value.message == "Invalid status value- please use the predefined options only." """ HELPER FUNCTIONS TESTS """ @pytest.mark.parametrize("page_size, page_number, expected_output", [(1, 10, "#### Showing 1 results from page 10:\n")]) def test_create_paging_header(page_size, page_number, expected_output): """ Given: - All relevant arguments for the command that is executed When: - redmine-user-id-list command is executed Then: - The http request is called with the right arguments """ from Redmine import create_paging_header assert create_paging_header(page_size, page_number) == expected_output @pytest.mark.parametrize("args, expected_output", [({"page_number": "2", "page_size": "20"}, (20, 20, 2))]) def test_adjust_paging_to_request(args, expected_output): """ Given: - All relevant arguments for the command that is executed When: - adjust_paging_to_request function is executed Then: - The http request is called with the right arguments """ from Redmine import adjust_paging_to_request assert adjust_paging_to_request(args["page_number"], args["page_size"], None) == expected_output