Exemple #1
0
class TestGithubIssuesParser(unittest.TestCase, GithubApiTestMixin):
    def setUp(self):
        self.init_github()
        self.gh = get_github_api("TestUser", "TestPass")
        self.title = "Issues"
        # Set up the mock release_tag lookup response
        self.issue_number_valid = 123
        self.issue_number_invalid = 456
        self.pr_number = 789
        self.pr_url = "https://github.com/{}/{}/pulls/{}".format(
            "TestOwner", "TestRepo", self.pr_number)
        self.mock_util = MockUtil("TestOwner", "TestRepo")

    @responses.activate
    def test_issue_numbers(self):
        self.mock_util.mock_get_repo()
        change_note = "# {}\r\nFixes #2, Closed #3 and Resolve #5".format(
            self.title)
        self.mock_util.mock_pull_request(self.pr_number, body=change_note)
        generator = self._create_generator()
        repo = generator.get_repo()
        pull_request = repo.pull_request(self.pr_number)
        parser = GithubIssuesParser(generator, self.title)
        parser.parse(pull_request)
        pr_url = "https://github.com/TestOwner/TestRepo/pulls/{}".format(
            self.pr_number)
        expected_content = self._create_expected_content([2, 3, 5], pr_url)
        self.assertEqual(parser.content, expected_content)

    @responses.activate
    def test_issue_numbers_and_other_numbers(self):
        self.mock_util.mock_get_repo()
        change_note = "# {}\r\nFixes #2 but not #5".format(self.title)
        self.mock_util.mock_pull_request(self.pr_number, body=change_note)
        generator = self._create_generator()
        repo = generator.get_repo()
        pull_request = repo.pull_request(self.pr_number)
        parser = GithubIssuesParser(generator, self.title)
        parser.parse(pull_request)
        pr_url = "https://github.com/TestOwner/TestRepo/pulls/{}".format(
            self.pr_number)
        expected_content = self._create_expected_content([2], pr_url)
        self.assertEqual(parser.content, expected_content)

    @responses.activate
    def test_no_issue_numbers(self):
        pr_number = 1
        self.mock_util.mock_get_repo()
        change_note = "# {}\r\n#2 and #3 are fixed by this change".format(
            self.title)
        self.mock_util.mock_pull_request(pr_number, body=change_note)
        generator = self._create_generator()
        repo = generator.get_repo()
        pull_request = repo.pull_request(pr_number)
        parser = GithubIssuesParser(generator, self.title)
        parser.parse(pull_request)
        self.assertEqual(parser.content, [])

    @responses.activate
    def test_render_issue_number_valid(self):
        api_url = "{}/issues/{}".format(self.repo_api_url,
                                        self.issue_number_valid)
        expected_response = self._get_expected_issue(self.issue_number_valid)
        self.mock_util.mock_get_repo()
        responses.add(method=responses.GET,
                      url=api_url,
                      json=expected_response)
        generator = self._create_generator()
        generator.link_pr = True
        parser = GithubIssuesParser(generator, self.title)
        parser.content = [{
            "issue_number": self.issue_number_valid,
            "pr_number": self.pr_number,
            "pr_url": self.pr_url,
        }]
        expected_render = self._create_expected_render(
            self.issue_number_valid, expected_response["title"], True)
        self.assertEqual(parser.render(), expected_render)

    @responses.activate
    def test_render_issue_number_invalid(self):
        api_url = "{}/issues/{}".format(self.repo_api_url,
                                        self.issue_number_invalid)
        expected_response = self._get_expected_not_found()
        self.mock_util.mock_get_repo()
        responses.add(
            method=responses.GET,
            url=api_url,
            json=expected_response,
            status=http.client.NOT_FOUND,
        )
        generator = self._create_generator()
        parser = GithubIssuesParser(generator, self.title)
        parser.content = [{
            "issue_number": self.issue_number_invalid,
            "pr_number": self.pr_number,
            "pr_url": self.pr_url,
        }]
        with self.assertRaises(GithubApiNotFoundError):
            parser.render()

    def test_init__issues_disabled(self):
        generator = mock.Mock(has_issues=False)
        with self.assertRaises(GithubIssuesError):
            parser = GithubIssuesParser(generator, self.title)

    def _create_expected_content(self, issue_numbers, pr_url):
        y = []
        for n in issue_numbers:
            y.append({
                "issue_number": n,
                "pr_number": self.pr_number,
                "pr_url": pr_url
            })
        return y

    def _create_expected_render(self, issue_number, issue_title, link_pr):
        render = "# {}\r\n\r\n#{}: {}".format(self.title, issue_number,
                                              issue_title)
        if link_pr:
            render += " [[PR{}]({})]".format(self.pr_number, self.pr_url)
        return render

    def _create_generator(self):
        generator = GithubReleaseNotesGenerator(self.gh,
                                                self.github_info.copy(),
                                                PARSER_CONFIG, "release/1.1")
        return generator
class TestGithubIssuesParser(unittest.TestCase, GithubApiTestMixin):

    def setUp(self):
        self.init_github()
        self.gh = get_github_api('TestUser', 'TestPass')
        self.title = 'Issues'
        # Set up the mock release_tag lookup response
        self.issue_number_valid = 123
        self.issue_number_invalid = 456
        self.pr_number = 789
        self.pr_url = 'https://github.com/{}/{}/pulls/{}'.format(
            'TestOwner',
            'TestRepo',
            self.pr_number,
        )
        self.mock_util = MockUtil('TestOwner', 'TestRepo')

    @responses.activate
    def test_issue_numbers(self):
        self.mock_util.mock_get_repo()
        change_note = '# {}\r\nFixes #2, Closed #3 and Resolve #5'.format(
            self.title)
        self.mock_util.mock_pull_request(self.pr_number, body=change_note)
        generator = self._create_generator()
        repo = generator.get_repo()
        pull_request = repo.pull_request(self.pr_number)
        parser = GithubIssuesParser(generator, self.title)
        parser.parse(pull_request)
        pr_url = 'https://github.com/TestOwner/TestRepo/pulls/{}'.format(self.pr_number)
        expected_content = self._create_expected_content([2, 3, 5], pr_url)
        self.assertEqual(parser.content, expected_content)

    @responses.activate
    def test_issue_numbers_and_other_numbers(self):
        self.mock_util.mock_get_repo()
        change_note = '# {}\r\nFixes #2 but not #5'.format(
            self.title)
        self.mock_util.mock_pull_request(self.pr_number, body=change_note)
        generator = self._create_generator()
        repo = generator.get_repo()
        pull_request = repo.pull_request(self.pr_number)
        parser = GithubIssuesParser(generator, self.title)
        parser.parse(pull_request)
        pr_url = 'https://github.com/TestOwner/TestRepo/pulls/{}'.format(self.pr_number)
        expected_content = self._create_expected_content([2], pr_url)
        self.assertEqual(parser.content, expected_content)

    @responses.activate
    def test_no_issue_numbers(self):
        pr_number = 1
        self.mock_util.mock_get_repo()
        change_note = '# {}\r\n#2 and #3 are fixed by this change'.format(
            self.title)
        self.mock_util.mock_pull_request(pr_number, body=change_note)
        generator = self._create_generator()
        repo = generator.get_repo()
        pull_request = repo.pull_request(pr_number)
        parser = GithubIssuesParser(generator, self.title)
        parser.parse(pull_request)
        self.assertEqual(parser.content, [])

    @responses.activate
    def test_render_issue_number_valid(self):
        api_url = '{}/issues/{}'.format(
            self.repo_api_url, self.issue_number_valid)
        expected_response = self._get_expected_issue(self.issue_number_valid)
        self.mock_util.mock_get_repo()
        responses.add(
            method=responses.GET,
            url=api_url,
            json=expected_response,
        )
        generator = self._create_generator()
        parser = GithubIssuesParser(generator, self.title)
        parser.content = [{
            'issue_number': self.issue_number_valid,
            'pr_number': self.pr_number,
            'pr_url': self.pr_url,
        }]
        expected_render = self._create_expected_render(
            self.issue_number_valid,
            expected_response['title'],
            False,
        )
        self.assertEqual(parser.render(), expected_render)

    @responses.activate
    def test_render_issue_number_invalid(self):
        api_url = '{}/issues/{}'.format(
            self.repo_api_url, self.issue_number_invalid)
        expected_response = self._get_expected_not_found()
        self.mock_util.mock_get_repo()
        responses.add(
            method=responses.GET,
            url=api_url,
            json=expected_response,
            status=httplib.NOT_FOUND,
        )
        generator = self._create_generator()
        parser = GithubIssuesParser(generator, self.title)
        parser.content = [{
            'issue_number': self.issue_number_invalid,
            'pr_number': self.pr_number,
            'pr_url': self.pr_url,
        }]
        with self.assertRaises(GithubApiNotFoundError):
            parser.render()

    def _create_expected_content(self, issue_numbers, pr_url):
        y = []
        for n in issue_numbers:
            y.append({
                'issue_number': n,
                'pr_number': self.pr_number,
                'pr_url': pr_url,
            })
        return y

    def _create_expected_render(self, issue_number, issue_title, link_pr):
        render = '# {}\r\n\r\n#{}: {}'.format(
            self.title,
            issue_number,
            issue_title,
        )
        if link_pr:
            render += ' [[PR{}]({})]'.format(self.pr_number, self.pr_url)
        return render

    def _create_generator(self):
        generator = GithubReleaseNotesGenerator(
            self.gh,
            self.github_info.copy(),
            PARSER_CONFIG,
            'prod/1.1',
        )
        return generator
class TestGithubReleaseNotesGenerator(unittest.TestCase, GithubApiTestMixin):
    def setUp(self):
        self.current_tag = "prod/1.4"
        self.last_tag = "prod/1.3"
        self.github_info = {
            "github_owner": "TestOwner",
            "github_repo": "TestRepo",
            "github_username": "******",
            "github_password": "******",
        }
        self.gh = get_github_api("TestUser", "TestPass")
        self.mock_util = MockUtil("TestOwner", "TestRepo")

    @responses.activate
    def test_init_without_last_tag(self):
        github_info = self.github_info.copy()
        self.mock_util.mock_get_repo()
        generator = GithubReleaseNotesGenerator(self.gh, github_info,
                                                PARSER_CONFIG,
                                                self.current_tag)
        self.assertEqual(generator.github_info, github_info)
        self.assertEqual(generator.current_tag, self.current_tag)
        self.assertEqual(generator.last_tag, None)
        self.assertEqual(generator.change_notes.current_tag, self.current_tag)
        self.assertEqual(generator.change_notes._last_tag, None)

    @responses.activate
    def test_init_with_last_tag(self):
        github_info = self.github_info.copy()
        self.mock_util.mock_get_repo()
        generator = GithubReleaseNotesGenerator(self.gh, github_info,
                                                PARSER_CONFIG,
                                                self.current_tag,
                                                self.last_tag)
        self.assertEqual(generator.github_info, github_info)
        self.assertEqual(generator.current_tag, self.current_tag)
        self.assertEqual(generator.last_tag, self.last_tag)
        self.assertEqual(generator.change_notes.current_tag, self.current_tag)
        self.assertEqual(generator.change_notes._last_tag, self.last_tag)

    @responses.activate
    def test_mark_down_link_to_pr(self):
        self.mock_util.mock_get_repo()
        self.mock_util.mock_pull_request(1,
                                         body="# Changes\r\n\r\nfoo",
                                         title="Title 1")
        generator = self._create_generator()
        pr = generator.get_repo().pull_request(1)
        actual_link = markdown_link_to_pr(pr)
        expected_link = "{} [[PR{}]({})]".format(pr.title, pr.number,
                                                 pr.html_url)
        self.assertEquals(expected_link, actual_link)

    @responses.activate
    def test_render_empty_pr_section(self):
        self.mock_util.mock_get_repo()
        self.mock_util.mock_pull_request(1, body="# Changes\r\n\r\nfoo")
        self.mock_util.mock_pull_request(2, body="# Changes\r\n\r\nbar")
        generator = self._create_generator()
        repo = generator.get_repo()
        pr1 = repo.pull_request(1)
        pr2 = repo.pull_request(2)
        generator.empty_change_notes.extend([pr1, pr2])
        content = render_empty_pr_section(generator.empty_change_notes)
        self.assertEquals(3, len(content))
        self.assertEquals("\n# Pull requests with no release notes",
                          content[0])
        self.assertEquals(
            "\n* {} [[PR{}]({})]".format(pr1.title, pr1.number, pr1.html_url),
            content[1],
        )
        self.assertEquals(
            "\n* {} [[PR{}]({})]".format(pr2.title, pr2.number, pr2.html_url),
            content[2],
        )

    @responses.activate
    def test_update_content_with_empty_release_body(self):
        self.mock_util.mock_get_repo()
        self.mock_util.mock_pull_request(88, body="Just a small note.")
        self.mock_util.mock_pull_request(89, body="")
        generator = self._create_generator()
        repo = generator.get_repo()
        pr1 = repo.pull_request(88)
        pr2 = repo.pull_request(89)
        generator.include_empty_pull_requests = True
        generator.empty_change_notes = [pr1, pr2]
        release = mock.Mock(body=None)
        content = generator._update_release_content(release, "new content")

        split_content = content.split("\r\n")
        self.assertEquals(4, len(split_content))
        self.assertEquals("new content", split_content[0])
        self.assertEquals("\n# Pull requests with no release notes",
                          split_content[1])
        self.assertEquals(
            "\n* Pull Request #{0} [[PR{0}]({1})]".format(
                pr1.number, pr1.html_url),
            split_content[2],
        )
        self.assertEquals(
            "\n* Pull Request #{0} [[PR{0}]({1})]".format(
                pr2.number, pr2.html_url),
            split_content[3],
        )

    @responses.activate
    def test_detect_empty_change_note(self):
        self.mock_util.mock_get_repo()
        self.mock_util.mock_pull_request(1, body="# Changes\r\n\r\nfoo")
        self.mock_util.mock_pull_request(2,
                                         body="Nothing under headers we track")
        self.mock_util.mock_pull_request(3, body="")
        generator = self._create_generator()
        repo = generator.get_repo()
        pr1 = repo.pull_request(1)
        pr2 = repo.pull_request(2)
        pr3 = repo.pull_request(3)

        generator._parse_change_note(pr1)
        generator._parse_change_note(pr2)
        generator._parse_change_note(pr3)

        # PR1 is "non-empty" second two are "empty"
        self.assertEquals(2, len(generator.empty_change_notes))
        self.assertEquals(2, generator.empty_change_notes[0].number)
        self.assertEquals(3, generator.empty_change_notes[1].number)

    def _create_generator(self):
        generator = GithubReleaseNotesGenerator(self.gh,
                                                self.github_info.copy(),
                                                PARSER_CONFIG,
                                                self.current_tag)
        return generator
class TestGithubIssuesParser(unittest.TestCase, GithubApiTestMixin):
    def setUp(self):
        self.init_github()
        self.gh = get_github_api("TestUser", "TestPass")
        self.title = "Issues"
        # Set up the mock release_tag lookup response
        self.issue_number_valid = 123
        self.issue_number_invalid = 456
        self.pr_number = 789
        self.pr_url = "https://github.com/{}/{}/pulls/{}".format(
            "TestOwner", "TestRepo", self.pr_number
        )
        self.mock_util = MockUtil("TestOwner", "TestRepo")

    @responses.activate
    def test_issue_numbers(self):
        self.mock_util.mock_get_repo()
        change_note = "# {}\r\nFixes #2, Closed #3 and Resolve #5".format(self.title)
        self.mock_util.mock_pull_request(self.pr_number, body=change_note)
        generator = self._create_generator()
        repo = generator.get_repo()
        pull_request = repo.pull_request(self.pr_number)
        parser = GithubIssuesParser(generator, self.title)
        parser.parse(pull_request)
        pr_url = "https://github.com/TestOwner/TestRepo/pulls/{}".format(self.pr_number)
        expected_content = self._create_expected_content([2, 3, 5], pr_url)
        self.assertEqual(parser.content, expected_content)

    @responses.activate
    def test_issue_numbers_and_other_numbers(self):
        self.mock_util.mock_get_repo()
        change_note = "# {}\r\nFixes #2 but not #5".format(self.title)
        self.mock_util.mock_pull_request(self.pr_number, body=change_note)
        generator = self._create_generator()
        repo = generator.get_repo()
        pull_request = repo.pull_request(self.pr_number)
        parser = GithubIssuesParser(generator, self.title)
        parser.parse(pull_request)
        pr_url = "https://github.com/TestOwner/TestRepo/pulls/{}".format(self.pr_number)
        expected_content = self._create_expected_content([2], pr_url)
        self.assertEqual(parser.content, expected_content)

    @responses.activate
    def test_no_issue_numbers(self):
        pr_number = 1
        self.mock_util.mock_get_repo()
        change_note = "# {}\r\n#2 and #3 are fixed by this change".format(self.title)
        self.mock_util.mock_pull_request(pr_number, body=change_note)
        generator = self._create_generator()
        repo = generator.get_repo()
        pull_request = repo.pull_request(pr_number)
        parser = GithubIssuesParser(generator, self.title)
        parser.parse(pull_request)
        self.assertEqual(parser.content, [])

    @responses.activate
    def test_render_issue_number_valid(self):
        api_url = "{}/issues/{}".format(self.repo_api_url, self.issue_number_valid)
        expected_response = self._get_expected_issue(self.issue_number_valid)
        self.mock_util.mock_get_repo()
        responses.add(method=responses.GET, url=api_url, json=expected_response)
        generator = self._create_generator()
        generator.link_pr = True
        parser = GithubIssuesParser(generator, self.title)
        parser.content = [
            {
                "issue_number": self.issue_number_valid,
                "pr_number": self.pr_number,
                "pr_url": self.pr_url,
            }
        ]
        expected_render = self._create_expected_render(
            self.issue_number_valid, expected_response["title"], True
        )
        self.assertEqual(parser.render(), expected_render)

    @responses.activate
    def test_render_issue_number_invalid(self):
        api_url = "{}/issues/{}".format(self.repo_api_url, self.issue_number_invalid)
        expected_response = self._get_expected_not_found()
        self.mock_util.mock_get_repo()
        responses.add(
            method=responses.GET,
            url=api_url,
            json=expected_response,
            status=http.client.NOT_FOUND,
        )
        generator = self._create_generator()
        parser = GithubIssuesParser(generator, self.title)
        parser.content = [
            {
                "issue_number": self.issue_number_invalid,
                "pr_number": self.pr_number,
                "pr_url": self.pr_url,
            }
        ]
        with self.assertRaises(GithubApiNotFoundError):
            parser.render()

    def test_init__issues_disabled(self):
        generator = mock.Mock(has_issues=False)
        with self.assertRaises(GithubIssuesError):
            GithubIssuesParser(generator, self.title)

    def _create_expected_content(self, issue_numbers, pr_url):
        y = []
        for n in issue_numbers:
            y.append({"issue_number": n, "pr_number": self.pr_number, "pr_url": pr_url})
        return y

    def _create_expected_render(self, issue_number, issue_title, link_pr):
        render = "# {}\r\n\r\n#{}: {}".format(self.title, issue_number, issue_title)
        if link_pr:
            render += " [[PR{}]({})]".format(self.pr_number, self.pr_url)
        return render

    def _create_generator(self):
        generator = GithubReleaseNotesGenerator(
            self.gh, self.github_info.copy(), PARSER_CONFIG, "release/1.1"
        )
        return generator