feat(assign): let leads manually assign operators + sync Jira; send platform as Jira label
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Adds GET /users/operators (leads+admin) and wires a lead-only assign
control into the test detail header, calling the existing but
previously unreachable POST /tests/{id}/assign endpoint. Manual
assignment now also pushes the Jira ticket assignee immediately
instead of waiting for the operator to start execution.
Also adds test.platform as a kebab-case label on Jira ticket creation.
This commit is contained in:
@@ -383,6 +383,44 @@ def test_auto_create_test_issue_maps_data_classification_to_real_jira_field(
|
||||
assert fields["customfield_11814"] == {"value": expected_jira_value}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"platform,expected_label",
|
||||
[
|
||||
("Windows", "windows"),
|
||||
("linux", "linux"),
|
||||
("macOS", "macos"),
|
||||
("Azure AD", "azure-ad"),
|
||||
(None, None),
|
||||
],
|
||||
)
|
||||
@patch("app.services.jira_service.has_admin_jira_configured", return_value=True)
|
||||
@patch("app.services.jira_service.get_jira_project_key", return_value="SEC")
|
||||
@patch("app.services.jira_service.get_jira_parent_ticket_standalone", return_value=None)
|
||||
@patch("app.services.jira_service.get_admin_jira_client")
|
||||
def test_auto_create_test_issue_adds_platform_label(
|
||||
mock_get_client, mock_parent, mock_project_key, mock_configured, db,
|
||||
platform, expected_label,
|
||||
):
|
||||
mock_jira = MagicMock()
|
||||
mock_jira.issue_create.return_value = {"key": "SEC-1", "id": "1"}
|
||||
mock_get_client.return_value = mock_jira
|
||||
from app.models.user import User
|
||||
test = _make_test_for_issue(platform=platform)
|
||||
technique = _make_technique()
|
||||
actor = User(username="gerardo-ruiz", email="gerardo.ruiz@kaseya.com", hashed_password="x")
|
||||
db.add(actor)
|
||||
db.commit()
|
||||
|
||||
jira_service.auto_create_test_issue(db, test, actor, technique=technique)
|
||||
|
||||
labels = mock_jira.issue_create.call_args.kwargs["fields"]["labels"]
|
||||
assert ["aegis", "security-test", "T1003-006"] == labels[:3]
|
||||
if expected_label:
|
||||
assert expected_label in labels
|
||||
else:
|
||||
assert len(labels) == 3
|
||||
|
||||
|
||||
def _make_user(**overrides):
|
||||
from app.models.user import User
|
||||
u = MagicMock(spec=User)
|
||||
@@ -428,4 +466,48 @@ def test_lookup_user_jira_account_id_no_match(mock_get_client, mock_configured,
|
||||
updated = jira_service.lookup_user_jira_account_id(db, user)
|
||||
|
||||
assert updated is False
|
||||
assert user.jira_account_id is None
|
||||
|
||||
|
||||
@patch("app.services.jira_service.has_admin_jira_configured", return_value=True)
|
||||
@patch("app.services.jira_service.get_admin_jira_client")
|
||||
def test_push_assignee_update_assigns_jira_issue(mock_get_client, mock_configured, db):
|
||||
mock_jira = MagicMock()
|
||||
mock_get_client.return_value = mock_jira
|
||||
test = _make_test()
|
||||
link = _make_link(test.id)
|
||||
db.add(link)
|
||||
db.commit()
|
||||
assignee = _make_user(jira_account_id="account-42")
|
||||
|
||||
jira_service.push_assignee_update(db, test, assignee)
|
||||
|
||||
mock_jira.assign_issue.assert_called_once_with(link.jira_issue_key, account_id="account-42")
|
||||
|
||||
|
||||
@patch("app.services.jira_service.has_admin_jira_configured", return_value=True)
|
||||
@patch("app.services.jira_service.get_admin_jira_client")
|
||||
def test_push_assignee_update_noop_without_jira_account_id(mock_get_client, mock_configured, db):
|
||||
mock_jira = MagicMock()
|
||||
mock_get_client.return_value = mock_jira
|
||||
test = _make_test()
|
||||
link = _make_link(test.id)
|
||||
db.add(link)
|
||||
db.commit()
|
||||
assignee = _make_user(jira_account_id=None)
|
||||
|
||||
jira_service.push_assignee_update(db, test, assignee)
|
||||
|
||||
mock_jira.assign_issue.assert_not_called()
|
||||
|
||||
|
||||
@patch("app.services.jira_service.has_admin_jira_configured", return_value=True)
|
||||
@patch("app.services.jira_service.get_admin_jira_client")
|
||||
def test_push_assignee_update_noop_without_link(mock_get_client, mock_configured, db):
|
||||
mock_jira = MagicMock()
|
||||
mock_get_client.return_value = mock_jira
|
||||
test = _make_test()
|
||||
assignee = _make_user(jira_account_id="account-42")
|
||||
|
||||
jira_service.push_assignee_update(db, test, assignee)
|
||||
|
||||
mock_jira.assign_issue.assert_not_called()
|
||||
|
||||
Reference in New Issue
Block a user