def _test_reporter(api, analyzers):
        # Always use the same setup, only varies the analyzers
        revision = Revision(api, mock_try_task)
        revision.lines = {"test.cpp": [0, 41, 42, 43], "dom/test.cpp": [42]}
        reporter = PhabricatorReporter({"analyzers": analyzers}, api=api)

        issues = [
            ClangFormatIssue("dom/test.cpp", 42, 1, revision),
            ClangTidyIssue(
                revision,
                "test.cpp",
                "42",
                "51",
                "modernize-use-nullptr",
                "dummy message",
                "error",
            ),
            InferIssue(
                {
                    "file": "test.cpp",
                    "line": 42,
                    "column": 1,
                    "bug_type": "dummy",
                    "kind": "whatever",
                    "qualifier": "dummy message.",
                },
                revision,
            ),
            MozLintIssue("test.cpp", 1, "danger", 42, "flake8", "Python error",
                         "EXXX", revision),
            CoverageIssue("test.cpp", 0, "This file is uncovered", revision),
        ]

        assert all(i.is_publishable() for i in issues)

        revision.improvement_patches = [
            ImprovementPatch("dummy", repr(revision), "Whatever"),
            ImprovementPatch("clang-tidy", repr(revision), "Some C fixes"),
            ImprovementPatch("clang-format", repr(revision),
                             "Some lint fixes"),
            ImprovementPatch("infer", repr(revision), "Some java fixes"),
            ImprovementPatch("mozlint", repr(revision), "Some js fixes"),
        ]
        list(map(lambda p: p.write(),
                 revision.improvement_patches))  # trigger local write

        return reporter.publish(issues, revision)
def test_phabricator_clang_format(mock_config, mock_phabricator,
                                  mock_try_task):
    """
    Test Phabricator reporter publication on a mock clang-format issue
    """
    from code_review_bot.report.phabricator import PhabricatorReporter
    from code_review_bot.revisions import Revision, ImprovementPatch
    from code_review_bot.tasks.clang_format import ClangFormatIssue

    def _check_comment(request):
        # Check the Phabricator main comment is well formed
        payload = urllib.parse.parse_qs(request.body)
        assert payload["output"] == ["json"]
        assert len(payload["params"]) == 1
        details = json.loads(payload["params"][0])
        assert details["message"] == VALID_CLANG_FORMAT_MESSAGE.format(
            results=mock_config.taskcluster.results_dir)

        # Outputs dummy empty response
        resp = {"error_code": None, "result": None}
        return (
            201,
            {
                "Content-Type": "application/json",
                "unittest": "clang-format"
            },
            json.dumps(resp),
        )

    responses.add_callback(
        responses.POST,
        "http://phabricator.test/api/differential.createcomment",
        callback=_check_comment,
    )

    with mock_phabricator as api:
        revision = Revision(api, mock_try_task)
        revision.lines = {
            # Add dummy lines diff
            "test.cpp": [41, 42, 43],
            "dom/test.cpp": [42],
        }
        reporter = PhabricatorReporter({"analyzers": ["clang-format"]},
                                       api=api)

    issue = ClangFormatIssue("mock-clang-format", "dom/test.cpp", 42, 1,
                             revision)
    assert issue.is_publishable()

    revision.improvement_patches = [
        ImprovementPatch("clang-format", repr(revision), "Some lint fixes")
    ]
    list(map(lambda p: p.write(),
             revision.improvement_patches))  # trigger local write

    issues, patches = reporter.publish([issue], revision, [])
    assert len(issues) == 1
    assert len(patches) == 1

    # Check the callback has been used
    assert len(responses.calls) > 0
    call = responses.calls[-1]
    assert call.request.url == "http://phabricator.test/api/differential.createcomment"
    assert call.response.headers.get("unittest") == "clang-format"