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