##// END OF EJS Templates
Added basic models for saving open pull requests...
marcink -
r2434:f2946967 codereview
parent child Browse files
Show More
@@ -0,0 +1,79 b''
1 # -*- coding: utf-8 -*-
2 """
3 rhodecode.model.pull_reuquest
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 pull request model for RhodeCode
7
8 :created_on: Jun 6, 2012
9 :author: marcink
10 :copyright: (C) 2012-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
17 #
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
26 import logging
27 from pylons.i18n.translation import _
28
29 from rhodecode.lib import helpers as h
30 from rhodecode.model import BaseModel
31 from rhodecode.model.db import PullRequest, PullRequestReviewers, Notification
32 from rhodecode.model.notification import NotificationModel
33 from rhodecode.lib.utils2 import safe_unicode
34
35 log = logging.getLogger(__name__)
36
37
38 class PullRequestModel(BaseModel):
39
40 def create(self, created_by, org_repo, org_ref, other_repo,
41 other_ref, revisions, reviewers, title, description=None):
42
43 new = PullRequest()
44 new.org_repo = self._get_repo(org_repo)
45 new.org_ref = org_ref
46 new.other_repo = self._get_repo(other_repo)
47 new.other_ref = other_ref
48 new.revisions = revisions
49 new.title = title
50 new.description = description
51
52 self.sa.add(new)
53
54 #members
55 for member in reviewers:
56 _usr = self._get_user(member)
57 reviewer = PullRequestReviewers(_usr, new)
58 self.sa.add(reviewer)
59
60 #notification to reviewers
61 notif = NotificationModel()
62 created_by_user = self._get_user(created_by)
63 subject = safe_unicode(
64 h.link_to(
65 _('%(user)s wants you to review pull request #%(pr_id)s') % \
66 {'user': created_by_user.username,
67 'pr_id': new.pull_request_id},
68 h.url('pullrequest_show', repo_name=other_repo,
69 pull_request_id=new.pull_request_id,
70 qualified=True,
71 )
72 )
73 )
74 body = description
75 notif.create(created_by=created_by, subject=subject, body=body,
76 recipients=reviewers,
77 type_=Notification.TYPE_PULL_REQUEST,)
78
79 return new
@@ -0,0 +1,32 b''
1 <%inherit file="/base/base.html"/>
2
3 <%def name="title()">
4 ${c.repo_name} ${_('Pull request #%s') % c.pull_request.pull_request_id}
5 </%def>
6
7 <%def name="breadcrumbs_links()">
8 ${h.link_to(u'Home',h.url('/'))}
9 &raquo;
10 ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))}
11 &raquo;
12 ${_('Pull request #%s') % c.pull_request.pull_request_id}
13 </%def>
14
15 <%def name="main()">
16
17 <div class="box">
18 <!-- box / title -->
19 <div class="title">
20 ${self.breadcrumbs()}
21 </div>
22
23 pull request ${c.pull_request} overview...
24
25 </div>
26
27 <script type="text/javascript">
28
29
30 </script>
31
32 </%def>
@@ -436,9 +436,20 b' def make_map(config):'
436 other_ref_type='(branch|book|tag)'))
436 other_ref_type='(branch|book|tag)'))
437
437
438 rmap.connect('pullrequest_home',
438 rmap.connect('pullrequest_home',
439 '/{repo_name:.*}/pull-request/new',
439 '/{repo_name:.*}/pull-request/new', controller='pullrequests',
440 controller='pullrequests', action='index',
440 action='index', conditions=dict(function=check_repo,
441 conditions=dict(function=check_repo))
441 method=["GET"]))
442
443 rmap.connect('pullrequest',
444 '/{repo_name:.*}/pull-request/new', controller='pullrequests',
445 action='create', conditions=dict(function=check_repo,
446 method=["POST"]))
447
448 rmap.connect('pullrequest_show',
449 '/{repo_name:.*}/pull-request/{pull_request_id}',
450 controller='pullrequests',
451 action='show', conditions=dict(function=check_repo,
452 method=["GET"]))
442
453
443 rmap.connect('summary_home', '/{repo_name:.*}/summary',
454 rmap.connect('summary_home', '/{repo_name:.*}/summary',
444 controller='summary', conditions=dict(function=check_repo))
455 controller='summary', conditions=dict(function=check_repo))
@@ -120,6 +120,8 b' class CompareController(BaseRepoControll'
120
120
121 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
121 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
122 c.cs_ranges])
122 c.cs_ranges])
123 # defines that we need hidden inputs with changesets
124 c.as_form = request.GET.get('as_form', False)
123 if request.environ.get('HTTP_X_PARTIAL_XHR'):
125 if request.environ.get('HTTP_X_PARTIAL_XHR'):
124 return render('compare/compare_cs.html')
126 return render('compare/compare_cs.html')
125
127
@@ -31,7 +31,10 b' from pylons.i18n.translation import _'
31
31
32 from rhodecode.lib.base import BaseRepoController, render
32 from rhodecode.lib.base import BaseRepoController, render
33 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
33 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
34 from rhodecode.model.db import User
34 from rhodecode.lib import helpers as h
35 from rhodecode.model.db import User, PullRequest
36 from rhodecode.model.pull_request import PullRequestModel
37 from rhodecode.model.meta import Session
35
38
36 log = logging.getLogger(__name__)
39 log = logging.getLogger(__name__)
37
40
@@ -71,13 +74,15 b' class PullrequestsController(BaseRepoCon'
71
74
72 c.other_refs = c.org_refs
75 c.other_refs = c.org_refs
73 c.other_repos.extend(c.org_repos)
76 c.other_repos.extend(c.org_repos)
74
77 c.default_pull_request = org_repo.repo_name
75 #gather forks and add to this list
78 #gather forks and add to this list
76 for fork in org_repo.forks:
79 for fork in org_repo.forks:
77 c.other_repos.append((fork.repo_name, '%s/%s' % (
80 c.other_repos.append((fork.repo_name, '%s/%s' % (
78 fork.user.username, fork.repo_name))
81 fork.user.username, fork.repo_name))
79 )
82 )
80 #add parents of this fork also
83 #add parents of this fork also
84 if org_repo.parent:
85 c.default_pull_request = org_repo.parent.repo_name
81 c.other_repos.append((org_repo.parent.repo_name, '%s/%s' % (
86 c.other_repos.append((org_repo.parent.repo_name, '%s/%s' % (
82 org_repo.parent.user.username,
87 org_repo.parent.user.username,
83 org_repo.parent.repo_name))
88 org_repo.parent.repo_name))
@@ -85,6 +90,44 b' class PullrequestsController(BaseRepoCon'
85
90
86 #TODO: maybe the owner should be default ?
91 #TODO: maybe the owner should be default ?
87 c.review_members = []
92 c.review_members = []
88 c.available_members = [(x.user_id, x.username) for x in
93 c.available_members = []
89 User.query().filter(User.username != 'default').all()]
94 for u in User.query().filter(User.username != 'default').all():
95 uname = u.username
96 if org_repo.user == u:
97 uname = _('%s (owner)' % u.username)
98 # auto add owner to pull-request recipients
99 c.review_members.append([u.user_id, uname])
100 c.available_members.append([u.user_id, uname])
90 return render('/pullrequests/pullrequest.html')
101 return render('/pullrequests/pullrequest.html')
102
103 def create(self, repo_name):
104 req_p = request.POST
105 org_repo = req_p['org_repo']
106 org_ref = req_p['org_ref']
107 other_repo = req_p['other_repo']
108 other_ref = req_p['other_ref']
109 revisions = req_p.getall('revisions')
110 reviewers = req_p.getall('review_members')
111 #TODO: wrap this into a FORM !!!
112
113 title = req_p['pullrequest_title']
114 description = req_p['pullrequest_desc']
115
116 try:
117 model = PullRequestModel()
118 model.create(self.rhodecode_user.user_id, org_repo,
119 org_ref, other_repo, other_ref, revisions,
120 reviewers, title, description)
121 Session.commit()
122 h.flash(_('Pull request send'), category='success')
123 except Exception:
124 raise
125 h.flash(_('Error occured during sending pull request'),
126 category='error')
127 log.error(traceback.format_exc())
128
129 return redirect(url('changelog_home', repo_name=repo_name))
130
131 def show(self, repo_name, pull_request_id):
132 c.pull_request = PullRequest.get(pull_request_id)
133 return render('/pullrequests/pullrequest_show.html')
@@ -118,7 +118,8 b' class ChangesetCommentsModel(BaseModel):'
118 NotificationModel().create(
118 NotificationModel().create(
119 created_by=user_id, subject=subj, body=body,
119 created_by=user_id, subject=subj, body=body,
120 recipients=mention_recipients,
120 recipients=mention_recipients,
121 type_=Notification.TYPE_CHANGESET_COMMENT
121 type_=Notification.TYPE_CHANGESET_COMMENT,
122 email_kwargs={'status_change': status_change}
122 )
123 )
123
124
124 return comment
125 return comment
@@ -1371,9 +1371,12 b' class ChangesetStatus(Base, BaseModel):'
1371 changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'))
1371 changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'))
1372 modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now)
1372 modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now)
1373 version = Column('version', Integer(), nullable=False, default=0)
1373 version = Column('version', Integer(), nullable=False, default=0)
1374 pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
1375
1374 author = relationship('User', lazy='joined')
1376 author = relationship('User', lazy='joined')
1375 repo = relationship('Repository')
1377 repo = relationship('Repository')
1376 comment = relationship('ChangesetComment', lazy='joined')
1378 comment = relationship('ChangesetComment', lazy='joined')
1379 pull_request = relationship('PullRequest', lazy='joined')
1377
1380
1378 @classmethod
1381 @classmethod
1379 def get_status_lbl(cls, value):
1382 def get_status_lbl(cls, value):
@@ -1384,6 +1387,59 b' class ChangesetStatus(Base, BaseModel):'
1384 return ChangesetStatus.get_status_lbl(self.status)
1387 return ChangesetStatus.get_status_lbl(self.status)
1385
1388
1386
1389
1390 class PullRequest(Base, BaseModel):
1391 __tablename__ = 'pull_requests'
1392 __table_args__ = (
1393 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1394 'mysql_charset': 'utf8'},
1395 )
1396
1397 pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True)
1398 title = Column('title', Unicode(256), nullable=True)
1399 description = Column('description', Unicode(10240), nullable=True)
1400 _revisions = Column('revisions', UnicodeText(20500)) # 500 revisions max
1401 org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1402 org_ref = Column('org_ref', Unicode(256), nullable=False)
1403 other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1404 other_ref = Column('other_ref', Unicode(256), nullable=False)
1405
1406 @hybrid_property
1407 def revisions(self):
1408 return self._revisions.split(':')
1409
1410 @revisions.setter
1411 def revisions(self, val):
1412 self._revisions = ':'.join(val)
1413
1414 reviewers = relationship('PullRequestReviewers')
1415 org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id')
1416 other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id')
1417
1418 def __json__(self):
1419 return dict(
1420 revisions=self.revisions
1421 )
1422
1423
1424 class PullRequestReviewers(Base, BaseModel):
1425 __tablename__ = 'pull_request_reviewers'
1426 __table_args__ = (
1427 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1428 'mysql_charset': 'utf8'},
1429 )
1430
1431 def __init__(self, user=None, pull_request=None):
1432 self.user = user
1433 self.pull_request = pull_request
1434
1435 pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True)
1436 pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False)
1437 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True)
1438
1439 user = relationship('User')
1440 pull_request = relationship('PullRequest')
1441
1442
1387 class Notification(Base, BaseModel):
1443 class Notification(Base, BaseModel):
1388 __tablename__ = 'notifications'
1444 __tablename__ = 'notifications'
1389 __table_args__ = (
1445 __table_args__ = (
@@ -226,6 +226,7 b' class EmailNotificationModel(BaseModel):'
226 TYPE_CHANGESET_COMMENT = Notification.TYPE_CHANGESET_COMMENT
226 TYPE_CHANGESET_COMMENT = Notification.TYPE_CHANGESET_COMMENT
227 TYPE_PASSWORD_RESET = 'passoword_link'
227 TYPE_PASSWORD_RESET = 'passoword_link'
228 TYPE_REGISTRATION = Notification.TYPE_REGISTRATION
228 TYPE_REGISTRATION = Notification.TYPE_REGISTRATION
229 TYPE_PULL_REQUEST = Notification.TYPE_PULL_REQUEST
229 TYPE_DEFAULT = 'default'
230 TYPE_DEFAULT = 'default'
230
231
231 def __init__(self):
232 def __init__(self):
@@ -12,7 +12,11 b''
12 <div title="${c.statuses[cs.raw_id][1]}" class="changeset-status-ico"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses[cs.raw_id][0])}" /></div>
12 <div title="${c.statuses[cs.raw_id][1]}" class="changeset-status-ico"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses[cs.raw_id][0])}" /></div>
13 %endif
13 %endif
14 </td>
14 </td>
15 <td>${h.link_to('r%s:%s' % (cs.revision,h.short_id(cs.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</td>
15 <td>${h.link_to('r%s:%s' % (cs.revision,h.short_id(cs.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}
16 %if c.as_form:
17 ${h.hidden('revisions',cs.raw_id)}
18 %endif
19 </td>
16 <td><div class="author">${h.person(cs.author)}</div></td>
20 <td><div class="author">${h.person(cs.author)}</div></td>
17 <td><span class="tooltip" title="${h.age(cs.date)}">${cs.date}</span></td>
21 <td><span class="tooltip" title="${h.age(cs.date)}">${cs.date}</span></td>
18 <td><div class="message">${h.urlify_commit(h.wrap_paragraphs(cs.message),c.repo_name)}</div></td>
22 <td><div class="message">${h.urlify_commit(h.wrap_paragraphs(cs.message),c.repo_name)}</div></td>
@@ -20,4 +24,4 b''
20 %endfor
24 %endfor
21 %endif
25 %endif
22 </table>
26 </table>
23 </div> No newline at end of file
27 </div>
@@ -34,7 +34,7 b''
34 </div>
34 </div>
35 <div id="changeset_compare_view_content">
35 <div id="changeset_compare_view_content">
36 ##CS
36 ##CS
37 <div style="font-size:1.1em;font-weight: bold;clear:both;padding-top:10px">${_('Changesets')}</div>
37 <div style="font-size:1.1em;font-weight: bold;clear:both;padding-top:10px">${_('Outgoing changesets')}</div>
38 <%include file="compare_cs.html" />
38 <%include file="compare_cs.html" />
39
39
40 ## FILES
40 ## FILES
@@ -1,7 +1,7 b''
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${c.repo_name} ${_('Pull request')}
4 ${c.repo_name} ${_('New pull request')}
5 </%def>
5 </%def>
6
6
7 <%def name="breadcrumbs_links()">
7 <%def name="breadcrumbs_links()">
@@ -9,7 +9,7 b''
9 &raquo;
9 &raquo;
10 ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))}
10 ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))}
11 &raquo;
11 &raquo;
12 ${_('Pull request')}
12 ${_('New pull request')}
13 </%def>
13 </%def>
14
14
15 <%def name="main()">
15 <%def name="main()">
@@ -19,8 +19,16 b''
19 <div class="title">
19 <div class="title">
20 ${self.breadcrumbs()}
20 ${self.breadcrumbs()}
21 </div>
21 </div>
22 ${h.form(url('#'),method='put', id='pull_request_form')}
22 ${h.form(url('pullrequest', repo_name=c.repo_name), method='post', id='pull_request_form')}
23 <div style="float:left;padding:30px">
23 <div style="float:left;padding:0px 30px 30px 30px">
24 <div style="padding:0px 5px 5px 5px">
25 <span>
26 <a id="refresh" href="#">
27 <img class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/>
28 ${_('refresh overview')}
29 </a>
30 </span>
31 </div>
24 ##ORG
32 ##ORG
25 <div style="float:left">
33 <div style="float:left">
26 <div class="fork_user">
34 <div class="fork_user">
@@ -45,23 +53,15 b''
45 <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_db_repo.user.email,24)}"/>
53 <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_db_repo.user.email,24)}"/>
46 </div>
54 </div>
47 <span style="font-size: 20px">
55 <span style="font-size: 20px">
48 ${h.select('other_repo','',c.other_repos,class_='refs')}:${h.select('other_ref','',c.other_refs,class_='refs')}
56 ${h.select('other_repo',c.default_pull_request ,c.other_repos,class_='refs')}:${h.select('other_ref','',c.other_refs,class_='refs')}
49 </span>
57 </span>
50 <div style="padding:5px 3px 3px 42px;">${c.rhodecode_db_repo.description}</div>
58 <div style="padding:5px 3px 3px 42px;">${c.rhodecode_db_repo.description}</div>
51 </div>
59 </div>
52 <div style="clear:both;padding-top: 10px"></div>
60 <div style="clear:both;padding-top: 10px"></div>
53 </div>
61 </div>
54 <div style="float:left;padding:5px 5px 5px 15px">
55 <span>
56 <a id="refresh" href="#">
57 <img class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/>
58 ${_('refresh overview')}
59 </a>
60 </span>
61 </div>
62 <div style="clear:both;padding-top: 10px"></div>
62 <div style="clear:both;padding-top: 10px"></div>
63 <div style="float:left" id="pull_request_overview">
63 ## overview pulled by ajax
64 </div>
64 <div style="float:left" id="pull_request_overview"></div>
65 <div style="float:left;clear:both;padding:10px 10px 10px 0px;display:none">
65 <div style="float:left;clear:both;padding:10px 10px 10px 0px;display:none">
66 <a id="pull_request_overview_url" href="#">${_('Detailed compare view')}</a>
66 <a id="pull_request_overview_url" href="#">${_('Detailed compare view')}</a>
67 </div>
67 </div>
@@ -75,7 +75,7 b''
75 <td>
75 <td>
76 <div>
76 <div>
77 <div style="float:left">
77 <div style="float:left">
78 <div class="text" style="padding: 0px 0px 6px;">${_('Choosen reviewers')}</div>
78 <div class="text" style="padding: 0px 0px 6px;">${_('Chosen reviewers')}</div>
79 ${h.select('review_members',[x[0] for x in c.review_members],c.review_members,multiple=True,size=8,style="min-width:210px")}
79 ${h.select('review_members',[x[0] for x in c.review_members],c.review_members,multiple=True,size=8,style="min-width:210px")}
80 <div id="remove_all_elements" style="cursor:pointer;text-align:center">
80 <div id="remove_all_elements" style="cursor:pointer;text-align:center">
81 ${_('Remove all elements')}
81 ${_('Remove all elements')}
@@ -149,7 +149,8 b''
149 repo_name='org_repo',
149 repo_name='org_repo',
150 org_ref_type='branch', org_ref='org_ref',
150 org_ref_type='branch', org_ref='org_ref',
151 other_ref_type='branch', other_ref='other_ref',
151 other_ref_type='branch', other_ref='other_ref',
152 repo='other_repo')}";
152 repo='other_repo',
153 as_form=True)}";
153
154
154 var select_refs = YUQ('#pull_request_form select.refs')
155 var select_refs = YUQ('#pull_request_form select.refs')
155
156
@@ -183,8 +184,7 b''
183 loadPreview()
184 loadPreview()
184 })
185 })
185
186
186 //lazy load after 0.5
187 //lazy load overview after 0.5s
187
188 setTimeout(loadPreview,500)
188 setTimeout(loadPreview, 500)
189
189
190 </script>
190 </script>
@@ -1,7 +1,52 b''
1 from rhodecode.tests import *
1 from rhodecode.tests import *
2
2
3
3 class TestCompareController(TestController):
4 class TestCompareController(TestController):
4
5
5 def test_index(self):
6 def test_index_tag(self):
6 response = self.app.get(url(controller='compare', action='index'))
7 self.log_user()
7 # Test response...
8 tag1='0.1.3'
9 tag2='0.1.2'
10 response = self.app.get(url(controller='compare', action='index',
11 repo_name=HG_REPO,
12 org_ref_type="tag",
13 org_ref=tag1,
14 other_ref_type="tag",
15 other_ref=tag2,
16 ))
17 response.mustcontain('%s@%s -> %s@%s' % (HG_REPO, tag1, HG_REPO, tag2))
18 ## outgoing changesets between tags
19 response.mustcontain('''<a href="/%s/changeset/17544fbfcd33ffb439e2b728b5d526b1ef30bfcf">r120:17544fbfcd33</a>''' % HG_REPO)
20 response.mustcontain('''<a href="/%s/changeset/36e0fc9d2808c5022a24f49d6658330383ed8666">r119:36e0fc9d2808</a>''' % HG_REPO)
21 response.mustcontain('''<a href="/%s/changeset/bb1a3ab98cc45cb934a77dcabf87a5a598b59e97">r118:bb1a3ab98cc4</a>''' % HG_REPO)
22 response.mustcontain('''<a href="/%s/changeset/41fda979f02fda216374bf8edac4e83f69e7581c">r117:41fda979f02f</a>''' % HG_REPO)
23 response.mustcontain('''<a href="/%s/changeset/9749bfbfc0d2eba208d7947de266303b67c87cda">r116:9749bfbfc0d2</a>''' % HG_REPO)
24 response.mustcontain('''<a href="/%s/changeset/70d4cef8a37657ee4cf5aabb3bd9f68879769816">r115:70d4cef8a376</a>''' % HG_REPO)
25 response.mustcontain('''<a href="/%s/changeset/c5ddebc06eaaba3010c2d66ea6ec9d074eb0f678">r112:c5ddebc06eaa</a>''' % HG_REPO)
26
27 ## files diff
28 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--1c5cf9e91c12">docs/api/utils/index.rst</a></div>''' % (HG_REPO, tag1, tag2))
29 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--e3305437df55">test_and_report.sh</a></div>''' % (HG_REPO, tag1, tag2))
30 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--c8e92ef85cd1">.hgignore</a></div>''' % (HG_REPO, tag1, tag2))
31 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--6e08b694d687">.hgtags</a></div>''' % (HG_REPO, tag1, tag2))
32 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--2c14b00f3393">docs/api/index.rst</a></div>''' % (HG_REPO, tag1, tag2))
33 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--430ccbc82bdf">vcs/__init__.py</a></div>''' % (HG_REPO, tag1, tag2))
34 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--9c390eb52cd6">vcs/backends/hg.py</a></div>''' % (HG_REPO, tag1, tag2))
35 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--ebb592c595c0">vcs/utils/__init__.py</a></div>''' % (HG_REPO, tag1, tag2))
36 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--7abc741b5052">vcs/utils/annotate.py</a></div>''' % (HG_REPO, tag1, tag2))
37 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--2ef0ef106c56">vcs/utils/diffs.py</a></div>''' % (HG_REPO, tag1, tag2))
38 response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--3150cb87d4b7">vcs/utils/lazy.py</a></div>''' % (HG_REPO, tag1, tag2))
39
40 def test_index_branch(self):
41 self.log_user()
42 response = self.app.get(url(controller='compare', action='index',
43 repo_name=HG_REPO,
44 org_ref_type="branch",
45 org_ref='default',
46 other_ref_type="branch",
47 other_ref='default',
48 ))
49
50 response.mustcontain('%s@default -> %s@default' % (HG_REPO, HG_REPO))
51 # branch are equal
52 response.mustcontain('<tr><td>No changesets</td></tr>')
@@ -1,7 +1,9 b''
1 from rhodecode.tests import *
1 from rhodecode.tests import *
2
2
3
3 class TestPullrequestsController(TestController):
4 class TestPullrequestsController(TestController):
4
5
5 def test_index(self):
6 def test_index(self):
6 response = self.app.get(url(controller='pullrequests', action='index'))
7 self.log_user()
7 # Test response...
8 response = self.app.get(url(controller='pullrequests', action='index',
9 repo_name=HG_REPO))
General Comments 0
You need to be logged in to leave comments. Login now