Skip to content

Commit

Permalink
fixup! feat: add command to get aggregate report
Browse files Browse the repository at this point in the history
  • Loading branch information
infinitewarp committed May 28, 2024
1 parent 933ebb0 commit 004139d
Showing 1 changed file with 93 additions and 92 deletions.
185 changes: 93 additions & 92 deletions qpc/tests/report/test_report_aggregate.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from qpc.tests.utilities import redirect_stdout
from qpc.utils import get_server_location

pytestmark = [pytest.mark.usefixtures("server_config")]


def get_scan_job_uri(scan_job_id: int) -> str:
"""Construct a scan job URI for testing."""
Expand All @@ -26,96 +28,95 @@ def get_aggregate_report_uri(report_id: int) -> str:
return f"{get_server_location()}{REPORT_URI}{report_id}{AGGREGATE_PATH_SUFFIX}"


@pytest.mark.usefixtures("server_config")
class TestReportAggregate:
"""Test the aggregate report command."""

def setup_method(self, _test_method):
"""Set up new command for each test."""
# Tests require command to be initialized for each test method because
# ReportAggregateCommand instance modifies req_path on the fly. This is
# definitely a bad code smell, but we are choosing to ignore it.
argument_parser = ArgumentParser()
subparser = argument_parser.add_subparsers(dest="subcommand")
self.command = ReportAggregateCommand(subparser)

@patch("qpc.report.aggregate.pretty_format")
def test_aggregate_report_success_via_report(self, mock_pretty_format, faker):
"""Test aggregate report with report id."""
report_out = StringIO()

report_id = faker.pyint()
report_uri = get_aggregate_report_uri(report_id)
report_json_data = {faker.slug(): faker.slug()}
with requests_mock.Mocker() as mocker:
mocker.get(report_uri, status_code=200, json=report_json_data)
args = Namespace(scan_job_id=None, report_id=report_id)
with redirect_stdout(report_out):
self.command.main(args)
mock_pretty_format.assert_called_once_with(report_json_data)

@patch("qpc.report.aggregate.pretty_format")
def test_aggregate_report_success_via_scan_job(self, mock_pretty_format, faker):
"""Test aggregate report with scan job id."""
report_out = StringIO()

report_id = faker.pyint()
scan_job_id = faker.pyint()
scan_job_uri = get_scan_job_uri(scan_job_id)
scan_job_json_data = {"id": scan_job_id, "report_id": report_id}
aggregate_report_uri = get_aggregate_report_uri(report_id)
aggregate_report_json_data = {faker.slug(): faker.slug()}
with requests_mock.Mocker() as mocker:
mocker.get(scan_job_uri, status_code=200, json=scan_job_json_data)
mocker.get(
aggregate_report_uri, status_code=200, json=aggregate_report_json_data
def get_command():
"""Set up new command for each test."""
# We can't use a fixture for this, even though that seems reasonable,
# because our command instances modify req_path on the fly. This is
# definitely a bad code smell, but we are choosing to ignore it because
# this design issue affects many of our commands the same way.
argument_parser = ArgumentParser()
subparser = argument_parser.add_subparsers(dest="subcommand")
return ReportAggregateCommand(subparser)


@patch("qpc.report.aggregate.pretty_format")
def test_aggregate_report_success_via_report(mock_pretty_format, faker):
"""Test aggregate report with report id."""
report_out = StringIO()

report_id = faker.pyint()
report_uri = get_aggregate_report_uri(report_id)
report_json_data = {faker.slug(): faker.slug()}
with requests_mock.Mocker() as mocker:
mocker.get(report_uri, status_code=200, json=report_json_data)
args = Namespace(scan_job_id=None, report_id=report_id)
with redirect_stdout(report_out):
get_command().main(args)
mock_pretty_format.assert_called_once_with(report_json_data)


@patch("qpc.report.aggregate.pretty_format")
def test_aggregate_report_success_via_scan_job(mock_pretty_format, faker):
"""Test aggregate report with scan job id."""
report_out = StringIO()

report_id = faker.pyint()
scan_job_id = faker.pyint()
scan_job_uri = get_scan_job_uri(scan_job_id)
scan_job_json_data = {"id": scan_job_id, "report_id": report_id}
aggregate_report_uri = get_aggregate_report_uri(report_id)
aggregate_report_json_data = {faker.slug(): faker.slug()}
with requests_mock.Mocker() as mocker:
mocker.get(scan_job_uri, status_code=200, json=scan_job_json_data)
mocker.get(
aggregate_report_uri, status_code=200, json=aggregate_report_json_data
)
args = Namespace(scan_job_id=scan_job_id, report_id=None)
with redirect_stdout(report_out):
get_command().main(args)
mock_pretty_format.assert_called_once_with(aggregate_report_json_data)


def test_aggregate_report_but_scan_job_does_not_exist(faker):
"""Test aggregate report with scan job id that does not exist."""
report_out = StringIO()

scan_job_id = faker.pyint()
scan_job_uri = get_scan_job_uri(scan_job_id)
with requests_mock.Mocker() as mocker:
mocker.get(scan_job_uri, status_code=400)
args = Namespace(scan_job_id=scan_job_id, report_id=None)
with pytest.raises(SystemExit), redirect_stdout(report_out):
get_command().main(args)
assert report_out.getvalue() == messages.REPORT_SJ_DOES_NOT_EXIST


def test_deployments_report_but_scan_job_has_no_report(faker):
"""Test aggregate report with scan job id that has no report id."""
report_out = StringIO()

scan_job_id = faker.pyint()
scan_job_uri = get_scan_job_uri(scan_job_id)
scan_job_json_data = {"id": scan_job_id}
with requests_mock.Mocker() as mocker:
mocker.get(scan_job_uri, status_code=200, json=scan_job_json_data)
args = Namespace(scan_job_id=scan_job_id, report_id=None)
with pytest.raises(SystemExit), redirect_stdout(report_out):
get_command().main(args)
assert report_out.getvalue() == messages.REPORT_NO_AGGREGATE_REPORT_FOR_SJ


def test_aggregate_report_but_report_does_not_exist(faker, caplog):
"""Test aggregate report with nonexistent report id."""
unknown_report_id = faker.pyint()
aggregate_report_uri = get_aggregate_report_uri(unknown_report_id)
with requests_mock.Mocker() as mocker:
mocker.get(aggregate_report_uri, status_code=400)
args = Namespace(scan_job_id=None, report_id=unknown_report_id)
with caplog.at_level(logging.ERROR):
with pytest.raises(SystemExit):
get_command().main(args)
err_msg = (
messages.REPORT_NO_AGGREGATE_REPORT_FOR_REPORT_ID % unknown_report_id
)
args = Namespace(scan_job_id=scan_job_id, report_id=None)
with redirect_stdout(report_out):
self.command.main(args)
mock_pretty_format.assert_called_once_with(aggregate_report_json_data)

def test_aggregate_report_but_scan_job_does_not_exist(self, faker):
"""Test aggregate report with scan job id that does not exist."""
report_out = StringIO()

scan_job_id = faker.pyint()
scan_job_uri = get_scan_job_uri(scan_job_id)
with requests_mock.Mocker() as mocker:
mocker.get(scan_job_uri, status_code=400)
args = Namespace(scan_job_id=scan_job_id, report_id=None)
with pytest.raises(SystemExit), redirect_stdout(report_out):
self.command.main(args)
assert report_out.getvalue() == messages.REPORT_SJ_DOES_NOT_EXIST

def test_deployments_report_but_scan_job_has_no_report(self, faker):
"""Test aggregate report with scan job id that has no report id."""
report_out = StringIO()

scan_job_id = faker.pyint()
scan_job_uri = get_scan_job_uri(scan_job_id)
scan_job_json_data = {"id": scan_job_id}
with requests_mock.Mocker() as mocker:
mocker.get(scan_job_uri, status_code=200, json=scan_job_json_data)
args = Namespace(scan_job_id=scan_job_id, report_id=None)
with pytest.raises(SystemExit), redirect_stdout(report_out):
self.command.main(args)
assert (
report_out.getvalue() == messages.REPORT_NO_AGGREGATE_REPORT_FOR_SJ
)

def test_aggregate_report_but_report_does_not_exist(self, faker, caplog):
"""Test aggregate report with nonexistent report id."""
unknown_report_id = faker.pyint()
aggregate_report_uri = get_aggregate_report_uri(unknown_report_id)
with requests_mock.Mocker() as mocker:
mocker.get(aggregate_report_uri, status_code=400)
args = Namespace(scan_job_id=None, report_id=unknown_report_id)
with caplog.at_level(logging.ERROR):
with pytest.raises(SystemExit):
self.command.main(args)
err_msg = (
messages.REPORT_NO_AGGREGATE_REPORT_FOR_REPORT_ID
% unknown_report_id
)
assert err_msg in caplog.text
assert err_msg in caplog.text

0 comments on commit 004139d

Please sign in to comment.