From 10eda21e5cc7a0fbe8ba1870b44fd4648de983e7 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Nov 02 2016 16:51:38 +0000 Subject: [PATCH 1/5] Adjust the markdown processor to have 1 regex for all cross-project links Until now we had two regex/extensions for the cross-project links. One for forks one for regular project but this lead to the situation where if you have a pattern such as /# the first part () would be linked to the fork of the project of that user and the second part (#) would link to the ticket/PR with this id in the original project. That was because the regex for cross-link project was matching the content of the link generated by the cross-link fork. By moving to one regex for all, we fix this situation. --- diff --git a/pagure/pfmarkdown.py b/pagure/pfmarkdown.py index 063d9a6..4fd7f5e 100644 --- a/pagure/pfmarkdown.py +++ b/pagure/pfmarkdown.py @@ -31,8 +31,12 @@ import pagure.lib MENTION_RE = r'@(\w+)' -EXPLICIT_FORK_ISSUE_RE = r'(\w+)/([\w-]+)#([0-9]+)' -EXPLICIT_MAIN_ISSUE_RE = r'([\w-]+)#([0-9]+)' +EXPLICIT_LINK_RE = r'(?[0-9]+)' IMPLICIT_ISSUE_RE = r'[^|\w](? Date: Nov 02 2016 16:51:38 +0000 Subject: [PATCH 2/5] Add unit-tests for pagure.lib.text2markdown This should highly simplify the maintenance of this piece of code and help with stability. --- diff --git a/tests/test_pagure_lib.py b/tests/test_pagure_lib.py index 2b49320..8cf952b 100644 --- a/tests/test_pagure_lib.py +++ b/tests/test_pagure_lib.py @@ -2521,6 +2521,138 @@ class PagureLibtests(tests.Modeltests): watch_list = [obj.name for obj in watch_list_objs] self.assertEqual(watch_list, []) + def test_text2markdown(self): + ''' Test the test2markdown method in pagure.lib. ''' + pagure.APP.config['TESTING'] = True + pagure.APP.config['SERVER_NAME'] = 'https://pagure.org' + pagure.SESSION = self.session + pagure.lib.SESSION = self.session + self.app = pagure.APP.test_client() + + # This creates: + # project: test + # fork: pingou/test + # PR#1 to project test + self.test_new_pull_request() + + # create PR#2 to project pingou/test + repo = pagure.lib.get_project(self.session, 'test') + forked_repo = pagure.lib.get_project( + self.session, 'test', user='pingou') + req = pagure.lib.new_pull_request( + requestid=2, + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=forked_repo, + branch_to='master', + title='test pull-request in fork', + user='pingou', + requestfolder=None, + ) + self.session.commit() + self.assertEqual(req.id, 2) + self.assertEqual(req.title, 'test pull-request in fork') + + # Create the project ns/test + item = pagure.lib.model.Project( + user_id=1, # pingou + name='test3', + namespace='ns', + description='test project #1', + hook_token='aaabbbcccdd', + ) + item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate'] + self.session.add(item) + self.session.commit() + + iss = pagure.lib.new_issue( + issue_id=4, + session=self.session, + repo=item, + title='test issue', + content='content test issue', + user='pingou', + ticketfolder=None, + ) + self.session.commit() + self.assertEqual(iss.id, 4) + self.assertEqual(iss.title, 'test issue') + + # Fork ns/test to pingou + item = pagure.lib.model.Project( + user_id=1, # pingou + name='test', + namespace='ns', + description='Forked namespaced test project #1', + is_fork=True, + parent_id=item.id, + hook_token='aaabbbrrrbb', + ) + self.session.add(item) + self.session.commit() + + iss = pagure.lib.new_issue( + issue_id=7, + session=self.session, + repo=item, + title='test issue #7', + content='content test issue #7 in forked repo', + user='pingou', + ticketfolder=None, + ) + self.session.commit() + self.assertEqual(iss.id, 7) + self.assertEqual(iss.title, 'test issue #7') + + texts = [ + 'foo bar test#1 see?', + 'foo bar pingou/test#2 I mean, really', + 'foo bar fork/pingou/test#2 bouza!', + 'foo bar forks/pingou/test#2 bouza!', + 'foo bar ns/test3#4 bouza!', + 'foo bar fork/user/ns/test#5 bouza!', + 'foo bar fork/pingou/ns/test#7 bouza!', + 'test#1 bazinga!', + 'pingou opened the PR forks/pingou/test#2' + ] + expected = [ + # 'foo bar test#1 see?', + '

foo bar test#1 see?

', + # 'foo bar pingou/test#2 I mean, really', -- unknown namespace + '

foo bar pingou/test#2 I mean, really

', + # 'foo bar fork/pingou/test#2 bouza!', + '

foo bar ' + 'pingou/test#2 bouza!

', + # 'foo bar forks/pingou/test#2 bouza!', -- the 's' doesn't matter + '

foo bar ' + 'pingou/test#2 bouza!

', + # 'foo bar ns/test3#4 bouza!', + '

foo bar ns/test3#4 bouza!

', + # 'foo bar fork/user/ns/test#5 bouza!', -- unknown fork + '

foo bar user/ns/test#5 bouza!

', + # 'foo bar fork/pingou/ns/test#7 bouza!', + '

foo bar ' + 'pingou/ns/test#7 bouza!

', + # 'test#1 bazinga!', + '

test#1 bazinga!

', + # 'pingou opened the PR forks/pingou/test#2' + '

pingou opened the PR pingou/test#2

' + ] + + with pagure.APP.app_context(): + for idx, text in enumerate(texts): + html = pagure.lib.text2markdown(text) + self.assertEqual(html, expected[idx]) + if __name__ == '__main__': SUITE = unittest.TestLoader().loadTestsFromTestCase(PagureLibtests) From 55850f26f120e92442b4203c04b2f4f78ddfb185 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Nov 02 2016 16:51:38 +0000 Subject: [PATCH 3/5] Document the regex a little more to try to make it more comprehensible --- diff --git a/pagure/pfmarkdown.py b/pagure/pfmarkdown.py index 4fd7f5e..dc8323f 100644 --- a/pagure/pfmarkdown.py +++ b/pagure/pfmarkdown.py @@ -31,12 +31,12 @@ import pagure.lib MENTION_RE = r'@(\w+)' -EXPLICIT_LINK_RE = r'(?[0-9]+)' +EXPLICIT_LINK_RE = r'(?[0-9]+)' # Get the identifier `#` IMPLICIT_ISSUE_RE = r'[^|\w](? Date: Nov 02 2016 20:02:43 +0000 Subject: [PATCH 4/5] Document the regex in a way that make the code compile and work --- diff --git a/pagure/pfmarkdown.py b/pagure/pfmarkdown.py index dc8323f..2e28810 100644 --- a/pagure/pfmarkdown.py +++ b/pagure/pfmarkdown.py @@ -31,12 +31,19 @@ import pagure.lib MENTION_RE = r'@(\w+)' -EXPLICIT_LINK_RE = r'(?[0-9]+)' # Get the identifier `#` +# Each line below correspond to a line of the regex: +# 1) Ensure we catch the motif from the start +# 2) See if there is a `forks/` at the start +# 3) See if we have a `user/` +# 4) See if we have a `namespace/` +# 5) Get the last part `project` +# 6) Get the identifier `#` +EXPLICIT_LINK_RE = r'(?[0-9]+)' IMPLICIT_ISSUE_RE = r'[^|\w](? Date: Nov 02 2016 20:02:58 +0000 Subject: [PATCH 5/5] Drop the protocol in the SERVER_NAME to avoid http://https:// --- diff --git a/tests/test_pagure_lib.py b/tests/test_pagure_lib.py index 8cf952b..0ad9deb 100644 --- a/tests/test_pagure_lib.py +++ b/tests/test_pagure_lib.py @@ -2524,7 +2524,7 @@ class PagureLibtests(tests.Modeltests): def test_text2markdown(self): ''' Test the test2markdown method in pagure.lib. ''' pagure.APP.config['TESTING'] = True - pagure.APP.config['SERVER_NAME'] = 'https://pagure.org' + pagure.APP.config['SERVER_NAME'] = 'pagure.org' pagure.SESSION = self.session pagure.lib.SESSION = self.session self.app = pagure.APP.test_client() @@ -2618,32 +2618,32 @@ class PagureLibtests(tests.Modeltests): ] expected = [ # 'foo bar test#1 see?', - '

foo bar foo bar test#1 see?

', # 'foo bar pingou/test#2 I mean, really', -- unknown namespace '

foo bar pingou/test#2 I mean, really

', # 'foo bar fork/pingou/test#2 bouza!', - '

foo bar ' 'pingou/test#2 bouza!

', # 'foo bar forks/pingou/test#2 bouza!', -- the 's' doesn't matter - '

foo bar ' 'pingou/test#2 bouza!

', # 'foo bar ns/test3#4 bouza!', - '

foo bar foo bar ns/test3#4 bouza!

', # 'foo bar fork/user/ns/test#5 bouza!', -- unknown fork '

foo bar user/ns/test#5 bouza!

', # 'foo bar fork/pingou/ns/test#7 bouza!', - '

foo bar ' 'pingou/ns/test#7 bouza!

', # 'test#1 bazinga!', - '

test#1 bazinga!

', # 'pingou opened the PR forks/pingou/test#2' - '

pingou opened the PR pingou/test#2

' ]