Show More
@@ -1602,16 +1602,24 b' def urlify_commits(text_, repository):' | |||||
1602 |
|
1602 | |||
1603 |
|
1603 | |||
1604 | def _process_url_func(match_obj, repo_name, uid, entry, |
|
1604 | def _process_url_func(match_obj, repo_name, uid, entry, | |
1605 | return_raw_data=False): |
|
1605 | return_raw_data=False, link_format='html'): | |
1606 | pref = '' |
|
1606 | pref = '' | |
1607 | if match_obj.group().startswith(' '): |
|
1607 | if match_obj.group().startswith(' '): | |
1608 | pref = ' ' |
|
1608 | pref = ' ' | |
1609 |
|
1609 | |||
1610 | issue_id = ''.join(match_obj.groups()) |
|
1610 | issue_id = ''.join(match_obj.groups()) | |
1611 | tmpl = ( |
|
1611 | ||
1612 | '%(pref)s<a class="%(cls)s" href="%(url)s">' |
|
1612 | if link_format == 'html': | |
1613 | '%(issue-prefix)s%(id-repr)s' |
|
1613 | tmpl = ( | |
1614 | '</a>') |
|
1614 | '%(pref)s<a class="%(cls)s" href="%(url)s">' | |
|
1615 | '%(issue-prefix)s%(id-repr)s' | |||
|
1616 | '</a>') | |||
|
1617 | elif link_format == 'rst': | |||
|
1618 | tmpl = '`%(issue-prefix)s%(id-repr)s <%(url)s>`_' | |||
|
1619 | elif link_format == 'markdown': | |||
|
1620 | tmpl = '[%(issue-prefix)s%(id-repr)s](%(url)s)' | |||
|
1621 | else: | |||
|
1622 | raise ValueError('Bad link_format:{}'.format(link_format)) | |||
1615 |
|
1623 | |||
1616 | (repo_name_cleaned, |
|
1624 | (repo_name_cleaned, | |
1617 | parent_group_name) = RepoGroupModel().\ |
|
1625 | parent_group_name) = RepoGroupModel().\ | |
@@ -1644,7 +1652,12 b' def _process_url_func(match_obj, repo_na' | |||||
1644 | return tmpl % data |
|
1652 | return tmpl % data | |
1645 |
|
1653 | |||
1646 |
|
1654 | |||
1647 |
def process_patterns(text_string, repo_name, |
|
1655 | def process_patterns(text_string, repo_name, link_format='html'): | |
|
1656 | allowed_formats = ['html', 'rst', 'markdown'] | |||
|
1657 | if link_format not in allowed_formats: | |||
|
1658 | raise ValueError('Link format can be only one of:{} got {}'.format( | |||
|
1659 | allowed_formats, link_format)) | |||
|
1660 | ||||
1648 | repo = None |
|
1661 | repo = None | |
1649 | if repo_name: |
|
1662 | if repo_name: | |
1650 | # Retrieving repo_name to avoid invalid repo_name to explode on |
|
1663 | # Retrieving repo_name to avoid invalid repo_name to explode on | |
@@ -1656,6 +1669,7 b' def process_patterns(text_string, repo_n' | |||||
1656 |
|
1669 | |||
1657 | issues_data = [] |
|
1670 | issues_data = [] | |
1658 | newtext = text_string |
|
1671 | newtext = text_string | |
|
1672 | ||||
1659 | for uid, entry in active_entries.items(): |
|
1673 | for uid, entry in active_entries.items(): | |
1660 | log.debug('found issue tracker entry with uid %s' % (uid,)) |
|
1674 | log.debug('found issue tracker entry with uid %s' % (uid,)) | |
1661 |
|
1675 | |||
@@ -1682,7 +1696,8 b' def process_patterns(text_string, repo_n' | |||||
1682 | issues_data.append(data_func(match_obj)) |
|
1696 | issues_data.append(data_func(match_obj)) | |
1683 |
|
1697 | |||
1684 | url_func = partial( |
|
1698 | url_func = partial( | |
1685 |
_process_url_func, repo_name=repo_name, entry=entry, uid=uid |
|
1699 | _process_url_func, repo_name=repo_name, entry=entry, uid=uid, | |
|
1700 | link_format=link_format) | |||
1686 |
|
1701 | |||
1687 | newtext = pattern.sub(url_func, newtext) |
|
1702 | newtext = pattern.sub(url_func, newtext) | |
1688 | log.debug('processed prefix:uid `%s`' % (uid,)) |
|
1703 | log.debug('processed prefix:uid `%s`' % (uid,)) | |
@@ -1750,7 +1765,8 b' def renderer_from_filename(filename, exc' | |||||
1750 | return None |
|
1765 | return None | |
1751 |
|
1766 | |||
1752 |
|
1767 | |||
1753 |
def render(source, renderer='rst', mentions=False, relative_url=None |
|
1768 | def render(source, renderer='rst', mentions=False, relative_url=None, | |
|
1769 | repo_name=None): | |||
1754 |
|
1770 | |||
1755 | def maybe_convert_relative_links(html_source): |
|
1771 | def maybe_convert_relative_links(html_source): | |
1756 | if relative_url: |
|
1772 | if relative_url: | |
@@ -1758,11 +1774,21 b" def render(source, renderer='rst', menti" | |||||
1758 | return html_source |
|
1774 | return html_source | |
1759 |
|
1775 | |||
1760 | if renderer == 'rst': |
|
1776 | if renderer == 'rst': | |
|
1777 | if repo_name: | |||
|
1778 | # process patterns on comments if we pass in repo name | |||
|
1779 | source, issues = process_patterns( | |||
|
1780 | source, repo_name, link_format='rst') | |||
|
1781 | ||||
1761 | return literal( |
|
1782 | return literal( | |
1762 | '<div class="rst-block">%s</div>' % |
|
1783 | '<div class="rst-block">%s</div>' % | |
1763 | maybe_convert_relative_links( |
|
1784 | maybe_convert_relative_links( | |
1764 | MarkupRenderer.rst(source, mentions=mentions))) |
|
1785 | MarkupRenderer.rst(source, mentions=mentions))) | |
1765 | elif renderer == 'markdown': |
|
1786 | elif renderer == 'markdown': | |
|
1787 | if repo_name: | |||
|
1788 | # process patterns on comments if we pass in repo name | |||
|
1789 | source, issues = process_patterns( | |||
|
1790 | source, repo_name, link_format='markdown') | |||
|
1791 | ||||
1766 | return literal( |
|
1792 | return literal( | |
1767 | '<div class="markdown-block">%s</div>' % |
|
1793 | '<div class="markdown-block">%s</div>' % | |
1768 | maybe_convert_relative_links( |
|
1794 | maybe_convert_relative_links( |
@@ -103,55 +103,62 b' def test_extract_issues(backend, text_st' | |||||
103 | assert issues == expected |
|
103 | assert issues == expected | |
104 |
|
104 | |||
105 |
|
105 | |||
106 | @pytest.mark.parametrize('text_string, pattern, expected_text', [ |
|
106 | @pytest.mark.parametrize('text_string, pattern, link_format, expected_text', [ | |
107 | ('Fix #42', '(?:#)(?P<issue_id>\d+)', |
|
107 | ('Fix #42', '(?:#)(?P<issue_id>\d+)', 'html', | |
108 | 'Fix <a class="issue-tracker-link" href="http://r.io/{repo}/i/42">#42</a>' |
|
108 | 'Fix <a class="issue-tracker-link" href="http://r.io/{repo}/i/42">#42</a>'), | |
109 | ), |
|
109 | ||
110 |
('Fix #42', '(?:#)?<issue_id>\d+)', ' |
|
110 | ('Fix #42', '(?:#)(?P<issue_id>\d+)', 'markdown', | |
|
111 | 'Fix [#42](http://r.io/{repo}/i/42)'), | |||
|
112 | ||||
|
113 | ('Fix #42', '(?:#)(?P<issue_id>\d+)', 'rst', | |||
|
114 | 'Fix `#42 <http://r.io/{repo}/i/42>`_'), | |||
|
115 | ||||
|
116 | ('Fix #42', '(?:#)?<issue_id>\d+)', 'html', | |||
|
117 | 'Fix #42'), # Broken regex | |||
111 | ]) |
|
118 | ]) | |
112 | def test_process_patterns_repo(backend, text_string, pattern, expected_text): |
|
119 | def test_process_patterns_repo(backend, text_string, pattern, expected_text, link_format): | |
113 | repo = backend.create_repo() |
|
120 | repo = backend.create_repo() | |
114 | config = {'123': { |
|
|||
115 | 'uid': '123', |
|
|||
116 | 'pat': pattern, |
|
|||
117 | 'url': 'http://r.io/${repo}/i/${issue_id}', |
|
|||
118 | 'pref': '#', |
|
|||
119 | } |
|
|||
120 | } |
|
|||
121 |
|
121 | |||
122 | def get_settings_mock(self, cache=True): |
|
122 | def get_settings_mock(self, cache=True): | |
123 |
return |
|
123 | return { | |
|
124 | '123': { | |||
|
125 | 'uid': '123', | |||
|
126 | 'pat': pattern, | |||
|
127 | 'url': 'http://r.io/${repo}/i/${issue_id}', | |||
|
128 | 'pref': '#', | |||
|
129 | } | |||
|
130 | } | |||
124 |
|
131 | |||
125 | with mock.patch.object(IssueTrackerSettingsModel, |
|
132 | with mock.patch.object(IssueTrackerSettingsModel, | |
126 | 'get_settings', get_settings_mock): |
|
133 | 'get_settings', get_settings_mock): | |
127 | processed_text, issues = helpers.process_patterns( |
|
134 | processed_text, issues = helpers.process_patterns( | |
128 |
text_string, repo.repo_name, |
|
135 | text_string, repo.repo_name, link_format) | |
129 |
|
136 | |||
130 | assert processed_text == expected_text.format(repo=repo.repo_name) |
|
137 | assert processed_text == expected_text.format(repo=repo.repo_name) | |
131 |
|
138 | |||
132 |
|
139 | |||
133 | @pytest.mark.parametrize('text_string, pattern, expected_text', [ |
|
140 | @pytest.mark.parametrize('text_string, pattern, expected_text', [ | |
134 | ('Fix #42', '(?:#)(?P<issue_id>\d+)', |
|
141 | ('Fix #42', '(?:#)(?P<issue_id>\d+)', | |
135 | 'Fix <a class="issue-tracker-link" href="http://r.io/i/42">#42</a>' |
|
142 | 'Fix <a class="issue-tracker-link" href="http://r.io/i/42">#42</a>'), | |
136 | ), |
|
143 | ('Fix #42', '(?:#)?<issue_id>\d+)', | |
137 |
|
|
144 | 'Fix #42'), # Broken regex | |
138 | ]) |
|
145 | ]) | |
139 | def test_process_patterns_no_repo(text_string, pattern, expected_text): |
|
146 | def test_process_patterns_no_repo(text_string, pattern, expected_text): | |
140 | config = {'123': { |
|
|||
141 | 'uid': '123', |
|
|||
142 | 'pat': pattern, |
|
|||
143 | 'url': 'http://r.io/i/${issue_id}', |
|
|||
144 | 'pref': '#', |
|
|||
145 | } |
|
|||
146 | } |
|
|||
147 |
|
147 | |||
148 | def get_settings_mock(self, cache=True): |
|
148 | def get_settings_mock(self, cache=True): | |
149 |
return |
|
149 | return { | |
|
150 | '123': { | |||
|
151 | 'uid': '123', | |||
|
152 | 'pat': pattern, | |||
|
153 | 'url': 'http://r.io/i/${issue_id}', | |||
|
154 | 'pref': '#', | |||
|
155 | } | |||
|
156 | } | |||
150 |
|
157 | |||
151 | with mock.patch.object(IssueTrackerSettingsModel, |
|
158 | with mock.patch.object(IssueTrackerSettingsModel, | |
152 | 'get_global_settings', get_settings_mock): |
|
159 | 'get_global_settings', get_settings_mock): | |
153 | processed_text, issues = helpers.process_patterns( |
|
160 | processed_text, issues = helpers.process_patterns( | |
154 |
text_string, '' |
|
161 | text_string, '') | |
155 |
|
162 | |||
156 | assert processed_text == expected_text |
|
163 | assert processed_text == expected_text | |
157 |
|
164 | |||
@@ -161,21 +168,21 b' def test_process_patterns_non_existent_r' | |||||
161 | pattern = '(?:#)(?P<issue_id>\d+)' |
|
168 | pattern = '(?:#)(?P<issue_id>\d+)' | |
162 | expected_text = ('Fix <a class="issue-tracker-link" ' |
|
169 | expected_text = ('Fix <a class="issue-tracker-link" ' | |
163 | 'href="http://r.io/do-not-exist/i/42">#42</a>') |
|
170 | 'href="http://r.io/do-not-exist/i/42">#42</a>') | |
164 | config = {'123': { |
|
|||
165 | 'uid': '123', |
|
|||
166 | 'pat': pattern, |
|
|||
167 | 'url': 'http://r.io/${repo}/i/${issue_id}', |
|
|||
168 | 'pref': '#', |
|
|||
169 | } |
|
|||
170 | } |
|
|||
171 |
|
171 | |||
172 | def get_settings_mock(self, cache=True): |
|
172 | def get_settings_mock(self, cache=True): | |
173 |
return |
|
173 | return { | |
|
174 | '123': { | |||
|
175 | 'uid': '123', | |||
|
176 | 'pat': pattern, | |||
|
177 | 'url': 'http://r.io/${repo}/i/${issue_id}', | |||
|
178 | 'pref': '#', | |||
|
179 | } | |||
|
180 | } | |||
174 |
|
181 | |||
175 | with mock.patch.object(IssueTrackerSettingsModel, |
|
182 | with mock.patch.object(IssueTrackerSettingsModel, | |
176 | 'get_global_settings', get_settings_mock): |
|
183 | 'get_global_settings', get_settings_mock): | |
177 | processed_text, issues = helpers.process_patterns( |
|
184 | processed_text, issues = helpers.process_patterns( | |
178 |
text_string, 'do-not-exist' |
|
185 | text_string, 'do-not-exist') | |
179 |
|
186 | |||
180 | assert processed_text == expected_text |
|
187 | assert processed_text == expected_text | |
181 |
|
188 |
General Comments 0
You need to be logged in to leave comments.
Login now