def test_gets_by_project_ids(self): p1 = ProjectIssue.add('test1', 'desp', 'test', project=1) p2 = ProjectIssue.add('test2', 'desp', 'test2', project=2) p3 = ProjectIssue.add('test3', 'desp', 'test3', project=2) issues = ProjectIssue.gets_by_project_ids([1, 2]) assert len(issues), 3 for p in [p1, p2, p3]: p.delete()
def main(): rs = store.execute("select id, project_id, issue_id, number from project_issues") if rs: for r in rs: pi = ProjectIssue(*r) pi.update_rank_score() rs = store.execute("select id, team_id, issue_id, number from team_issues") if rs: for r in rs: ti = TeamIssue(*r) ti.update_rank_score()
def test_zero_vote_and_zero_comment_display(self): app = TestApp(M.app) project_name = "project" delete_project(project_name) project = CodeDoubanProject.add( project_name, owner_id="test1", summary="test", product="fire") ProjectIssue.add('test', 'test description', 'test', project=project.id) resp = app.get(project.url + "/issues/") assert resp.status_int == 200 assert 'Issues' in resp.body assert '0 vote' not in resp.body assert '0 comment' not in resp.body
def create(self, request): if request.method == 'POST': user = request.user if not user: raise AccessError project = request.get_form_var('project') title = request.get_form_var('title', '').decode('utf-8') description = request.get_form_var('body', '').decode('utf-8') tags = request.get_form_var('issue_tags', []) if isinstance(tags, list): tags = [tag.decode('utf-8') for tag in tags if tag] elif isinstance(tags, basestring): tags = [tags.decode('utf-8')] if not project: raise TraversalError if not title.strip(): return request.redirect('/%s/issues/new?error=empty' % project) project = CodeDoubanProject.get_by_name(project) pissue = ProjectIssue.add(title, description, user.name, project=project.id) pissue.add_tags(tags, pissue.project_id) # TODO: 重构feed后取消信号发送 issue_signal.send(author=user.name, content=description, issue_id=pissue.issue_id) dispatch('issue', data={ 'sender': user.name, 'content': description, 'issue': pissue }) return request.redirect(pissue.url) project_name = self.proj_name return request.redirect('/%s/issues' % project_name)
def _get_issue_comment_by_uid(uid): issue = {} # uid: issue-type-id-number if uid and uid.startswith('issue-'): fields = uid.split('-') if len(fields) != 6: return issue _, _, type, id, number, comment_number = fields if type == 'project': _issue = ProjectIssue.get(id, number=number) _issue = Issue.get_cached_issue(_issue.issue_id) _target = _get_project_by_name(_issue.target.name) elif type == 'team': _issue = TeamIssue.get(id, number=number) _issue = Issue.get_cached_issue(_issue.issue_id) _target = _get_team_by_uid(_issue.target.uid) else: return issue _author = _get_user_by_name(_issue.creator_id) _closer = _get_user_by_name(_issue.closer_id) if _issue.closer_id else {} issue = dict( id=_issue.issue_id, name=_issue.title, author=_author, closer=_closer, ) issue[_issue.target_type] = _target return issue
def index_a_project_issue(cls, project): issues = ProjectIssue._get_issues_by_project_id(project.id) for issue in issues: data = issue.as_dict() if data: serial = "%s_%s" % (project.index_name, issue.number) cls.index_an_object(serial, data)
def _q_index(request): user = request.user my_issues = [] if user: username = user.username your_projects = CodeDoubanProject.get_projects(owner=username, sortby='lru') watched_projects = CodeDoubanProject.get_watched_others_projects_by_user( # noqa user=username, sortby='lru') teams = Team.get_by_user_id(user.name) actions = get_user_inbox(username).get_actions( stop=PAGE_ACTIONS_COUNT - 1) badge_items = user.get_badge_items() # pull request # your_tickets = user.get_user_pull_requests_rank(limit=5) your_tickets = user.get_user_submit_pull_requests(limit=5) # issue project_ids = CodeDoubanProject.get_ids(user.name) dt = { 'state': "open", 'limit': 5, 'start': 0, } my_issues = ProjectIssue.gets_by_project_ids(project_ids, **dt) return st('newsfeed.html', **locals()) return request.redirect("/teams/")
def test_single_project(self): skip_test() u_to = User("admin") u_from = User("testuser") to_proj = self._prj("test", "admin") self._add(to_proj, u_to, "README.md", "hi") from_proj = self._prj("testuser/test", "testuser", to_proj.id) self._add(from_proj, u_from, "README.md", "hello") pullreq = PullRequest.open(from_proj, "master", to_proj, "master") ticket = Ticket(None, None, to_proj.id, "title", "desc", "testuser", None, None) pullreq = add_pull(ticket, pullreq, u_from) iss = ProjectIssue.add(title='title1', description='desc1', creator='owner', project=to_proj.id) IssuePRSearch.index_a_project(to_proj) res = IssueSearch.search_a_phrase('title1', to_proj.id) res = SearchEngine.decode(res, ('issue_id', )) res = [id for id, in res] assert len(res) == 1 assert res[0] == iss.id res = PullRequestSearch.search_a_phrase('title', to_proj.id) res = SearchEngine.decode(res, ('issue_id', )) res = [id for id, in res] assert len(res) == 1
def __init__(self, issue_id, description, hl_description): self.issue = ProjectIssue.get_by_issue_id(issue_id) \ if issue_id else None if self.issue and self.issue.description: description = self.issue.description self.description = description self.hl_description = hl_description or description
def setUp(self): super(ProjectIssueCommentsTest, self).setUp() project_name = "code" product_name = "fire" summary = "test" owner_id = "lisong_intern" delete_project(project_name) project = CodeDoubanProject.add( project_name, owner_id=owner_id, summary=summary, product=product_name ) self.project = project title = "test title" description = "test desc" creator = "test" issue = ProjectIssue.add( title, description, creator, project=self.project.id ) self.issue = issue self.project = project self.comment1 = IssueComment.add( self.issue.issue_id, 'content1', 'test1') self.comment2 = IssueComment.add( self.issue.issue_id, 'content2', 'test2') self.api_token = self.create_api_token('test1') self.api_token2 = self.create_api_token('test2')
def test_single_project(self): skip_test() u_to = User("admin") u_from = User("testuser") to_proj = self._prj("test", "admin") self._add(to_proj, u_to, "README.md", "hi") from_proj = self._prj("testuser/test", "testuser", to_proj.id) self._add(from_proj, u_from, "README.md", "hello") pullreq = PullRequest.open(from_proj, "master", to_proj, "master") ticket = Ticket(None, None, to_proj.id, "title", "desc", "testuser", None, None) pullreq = add_pull(ticket, pullreq, u_from) iss = ProjectIssue.add(title='title1', description='desc1', creator='owner', project=to_proj.id) IssuePRSearch.index_a_project(to_proj) res = IssueSearch.search_a_phrase('title1', to_proj.id) res = SearchEngine.decode(res, ('issue_id',)) res = [id for id, in res] assert len(res) == 1 assert res[0] == iss.id res = PullRequestSearch.search_a_phrase('title', to_proj.id) res = SearchEngine.decode(res, ('issue_id',)) res = [id for id, in res] assert len(res) == 1
def test_add_issue(self): p = ProjectIssue.add('test', 'test description', 'test', project=1) assert isinstance(p, ProjectIssue) assert p.title == 'test' assert p.description == 'test description' assert p.project_id == 1 p.delete()
def _q_lookup(self, request, issue_number): repo = self.repo issue = ProjectIssue.get(project_id=repo.id, number=issue_number) if not issue: raise api_errors.NotFoundError('project issue') return IssueUI(request, repo, issue)
def __init__(self, proj_name, issue_number): self.target = CodeDoubanProject.get_by_name(proj_name) self.issue_number = issue_number project_issue = ProjectIssue.get(self.target.id, number=self.issue_number) self.issue_id = project_issue.issue_id self.issue = Issue.get_cached_issue(self.issue_id) self.issue_template = 'issue/issue.html'
def get(self, request): page = int(request.get_form_var('page', 1)) count = int(request.get_form_var('count', 25)) start = (page - 1) * count state = request.get_form_var('state', None) project = self.project project_issues = ProjectIssue.gets_by_target(project.id, state=state, start=start, limit=count) return [issue.as_dict() for issue in project_issues]
def setUp(self): TestCase.setUp(self) self.testuser1 = 'testuser1' self.testuser2 = 'testuser2' self.testuser3 = 'testuser3' self.test_team_issue = TeamIssue.add('test', 'test description', self.testuser1, team=1) self.test_project_issue = ProjectIssue.add( 'test', 'test description', self.testuser1, project=1)
def test_zero_vote_and_zero_comment_display(self): app = TestApp(M.app) project_name = "project" delete_project(project_name) project = CodeDoubanProject.add(project_name, owner_id="test1", summary="test", product="fire") ProjectIssue.add('test', 'test description', 'test', project=project.id) resp = app.get(project.url + "/issues/") assert resp.status_int == 200 assert 'Issues' in resp.body assert '0 vote' not in resp.body assert '0 comment' not in resp.body
def test_gets_by_project_ids(self): ProjectIssue.add('test1', 'desp', 'test', project=1) ProjectIssue.add('test2', 'desp', 'test2', project=2) ProjectIssue.add('test3', 'desp', 'test3', project=2) issues = ProjectIssue.gets_by_project_ids([1, 2]) assert len(issues), 3
def __init__(self, request, proj_name, issue_number): self.proj_name = proj_name self.issue_number = issue_number self.project = CodeDoubanProject.get_by_name(self.proj_name) self.project_issue = ProjectIssue.get(project_id=self.project.id, number=self.issue_number) if not self.project_issue: raise api_errors.NotFoundError('project issue') self.comments = IssueCommentsUI(request, self.project_issue) self.user = request.user
def test_upate_issue_not_author_fail(self): issue = ProjectIssue.add("old title", "old desc", self.username, project=self.project.id) title = "new title" description = "new desc" ret = self.app.patch_json( "/api/%s/issues/%s/" % (self.project.name, issue.number), dict(title=title, description=description), headers=dict(Authorization="Bearer %s" % self.api_token2.token), status=403, ).json self.assertProblemType(ret["type"], "not_the_author")
def _get_closed_multi(self): milestone = self.milestone tasks = [] rs = IssueMilestone.gets_by(milestone_id=milestone.id) for r in rs: issue = ProjectIssue.get_by_issue_id(r.issue_id) if not issue: continue if issue.closer_id: tasks.append(r) return tasks
def test_multiple_project(self): skip_test() p1 = self._prj("test_1") p2 = self._prj("test_2") iss1 = ProjectIssue.add(title='title1', description='desc1', creator='owner', project=p1.id) iss2 = ProjectIssue.add(title='title1', description='desc1', creator='owner', project=p2.id) IssueSearch.index_a_project_issue(p1) IssueSearch.index_a_project_issue(p2) res = IssueSearch.search_a_phrase('title1', p1.id) res = SearchEngine.decode(res, ('issue_id',)) res = [id for id, in res] assert len(res) == 1 assert res[0] == iss1.id res = IssueSearch.search_a_phrase('title1', p2.id) res = SearchEngine.decode(res, ('issue_id',)) res = [id for id, in res] assert len(res) == 1 assert res[0] == iss2.id
def test_single_project(self): skip_test() p = self._prj("test") iss1 = ProjectIssue.add(title='title1', description='desc1', creator='owner', project=p.id) IssueSearch.index_a_project_issue(p) res = IssueSearch.search_a_phrase('owner', p.id) res = SearchEngine.decode(res, ('issue_id',)) res = [id for id, in res] assert len(res) == 1 assert res[0] == iss1.id iss2 = ProjectIssue.add(title='title2', description='desc2', creator='owner', project=p.id) IssueSearch.index_a_project_issue(p) res = IssueSearch.search_a_phrase('owner', p.id) res = SearchEngine.decode(res, ('issue_id',)) res = [id for id, in res] assert len(res) == 2 assert iss1.id in res assert iss2.id in res
def test_get_single_issue(self): title = "test title" description = "test desc" creator = "test" issue = ProjectIssue.add(title, description, creator, project=self.project.id) IssueComment.add(issue.issue_id, "content", "test") ret = self.app.get("/api/%s/issues/%s/" % (self.project.name, issue.number), status=200).json self.assertEquals(ret["title"], title) self.assertEquals(ret["description"], description) self.assertEquals(ret["creator"], creator) self.assertEquals(ret["project"], self.project.name) self.assertEquals(ret["comments"], 1)
def setUp(self): super(TestCase, self).setUp() self.project = get_temp_project() self.issue = ProjectIssue.add('test', 'test description', 'test', project=self.project.id) user = User('testuser') project = self.project name = "Test Milestone 1" ms = Milestone.create_by_project(project, name, user) self.milestone = ms
def test_get_issue(self): p1 = ProjectIssue.add('test1', 'test1 description', 'test', project=1, assignee='assignee') p1.close('test') p2 = ProjectIssue.add('test2', 'test2 description', 'test', project=1, assignee='assignee') p2.close('test') p3 = ProjectIssue.add('test3', 'test3 description', 'test', project=1, assignee='assignee') p4 = ProjectIssue.add('test4', 'test4 description', 'test', project=1, assignee='test') p5 = ProjectIssue.add('test5', 'test5 description', 'test1', project=2, assignee='test') rs = UserIssue.gets_by_creator_id('test', state='open') assert all([isinstance(i, ProjectIssue) for i in rs]) assert len(rs) == 2 rs = UserIssue.gets_by_assignee_id('test', state='open') assert all([isinstance(i, ProjectIssue) for i in rs]) assert len(rs) == 2
def setUp(self): TestCase.setUp(self) self.testuser1 = 'testuser1' self.testuser2 = 'testuser2' self.testuser3 = 'testuser3' self.test_team_issue = TeamIssue.add('test', 'test description', self.testuser1, team=1) self.test_project_issue = ProjectIssue.add('test', 'test description', self.testuser1, project=1)
def test_upate_issue_not_author_fail(self): issue = ProjectIssue.add('old title', 'old desc', self.username, project=self.project.id) title = "new title" description = 'new desc' ret = self.app.patch_json( "/api/%s/issues/%s/" % (self.project.name, issue.number), dict(title=title, description=description), headers=dict(Authorization="Bearer %s" % self.api_token2.token), status=403).json self.assertProblemType(ret['type'], "not_the_author")
def _get_issue_by_project_and_number(id, number): issue = {} project_issue = ProjectIssue.get(id, number=number) _issue = Issue.get_cached_issue(project_issue.issue_id) _author = _get_user_by_name(_issue.creator_id) _closer = _get_user_by_name(_issue.closer_id) if _issue.closer_id else {} issue = dict( id=_issue.issue_id, name=_issue.title, author=_author, closer=_closer, ) return issue
def test_new_project_issue_participant_count(self): app = TestApp(M.app) project_name = "project" project = CodeDoubanProject.add( project_name, owner_id="test1", summary="test", product="fire") issue = ProjectIssue.add( 'test', 'test description', 'test', project=project.id) resp = app.get(issue.url) assert resp.status_int == 200 assert 'Issues' in resp.body assert '<strong>1</strong> participant' in resp.text assert '<strong>1</strong> participants' not in resp.text
def test_two_comments_display(self): app = TestApp(M.app) project_name = "project4" project = CodeDoubanProject.add( project_name, owner_id="test1", summary="test", product="fire") issue = ProjectIssue.add('test', 'test description', 'test', project=project.id) issue.add_comment('this is a comment', 'test') issue.add_comment('this is also a comment', 'test') resp = app.get(project.url + "/issues/") assert resp.status_int == 200 assert "Issues" in resp.body assert "2 comments" in resp.body
def test_two_votes_display(self): app = TestApp(M.app) project_name = "project3" project = CodeDoubanProject.add( project_name, owner_id="test1", summary="test", product="fire") issue = ProjectIssue.add('test', 'test description', 'test', project=project.id) issue.upvote_by_user('test1') issue.upvote_by_user('test2') resp = app.get(project.url + "/issues/") assert resp.status_int == 200 assert "Issues" in resp.body assert "2 votes" in resp.body
def index(request): user = request.user my_issues = [] if user: page = request.get_form_var('page', 1) state = request.get_form_var("state", "open") is_closed_tab = None if state == "open" else True project_ids = CodeDoubanProject.get_ids(user.name) # TODO: 下面的这些N,可以考虑先从 get 参数里拿一下,没有的话再重新读 n_repos_issue = ProjectIssue.get_count_by_project_ids(project_ids, state) n_assigned_issue = user.get_count_assigned_issues(state) n_created_issue = user.get_count_created_issues(state) n_participated_issue = user.get_n_participated_issues(state) total_issues = { 'repos': n_repos_issue, 'assigned': n_assigned_issue, 'created_by': n_created_issue, 'participated': n_participated_issue, }[list_type] n_pages = (total_issues - 1) / ISSUES_COUNT_PER_PAGE + 1 dt = { 'state': state, 'limit': ISSUES_COUNT_PER_PAGE, 'start': ISSUES_COUNT_PER_PAGE * (int(page) - 1), } if list_type == 'repos': my_issues = ProjectIssue.gets_by_project_ids(project_ids, **dt) else: get_my_issues = { 'assigned': user.get_assigned_issues, 'created_by': user.get_created_issues, 'participated': user.get_participated_issues, }[list_type] my_issues = get_my_issues(**dt) return st('issue/my_issues.html', **locals())
def test_upate_issue(self): title = "test title" description = "test desc" creator = self.username issue = ProjectIssue.add(title, description, creator, project=self.project.id) new_title = "new title" new_description = "new desc" ret = self.app.patch_json( "/api/%s/issues/%s/" % (self.project.name, issue.number), dict(title=new_title, description=new_description, state="closed"), headers=dict(Authorization="Bearer %s" % self.api_token.token), ).json self.assertEquals(ret["title"], new_title) self.assertEquals(ret["description"], new_description) self.assertEquals(ret["state"], "closed")
def test_multiple_project(self): skip_test() p1 = self._prj("test_1") p2 = self._prj("test_2") iss1 = ProjectIssue.add(title='title1', description='desc1', creator='owner', project=p1.id) iss2 = ProjectIssue.add(title='title1', description='desc1', creator='owner', project=p2.id) IssueSearch.index_a_project_issue(p1) IssueSearch.index_a_project_issue(p2) res = IssueSearch.search_a_phrase('title1', p1.id) res = SearchEngine.decode(res, ('issue_id', )) res = [id for id, in res] assert len(res) == 1 assert res[0] == iss1.id res = IssueSearch.search_a_phrase('title1', p2.id) res = SearchEngine.decode(res, ('issue_id', )) res = [id for id, in res] assert len(res) == 1 assert res[0] == iss2.id
def test_single_project(self): skip_test() p = self._prj("test") iss1 = ProjectIssue.add(title='title1', description='desc1', creator='owner', project=p.id) IssueSearch.index_a_project_issue(p) res = IssueSearch.search_a_phrase('owner', p.id) res = SearchEngine.decode(res, ('issue_id', )) res = [id for id, in res] assert len(res) == 1 assert res[0] == iss1.id iss2 = ProjectIssue.add(title='title2', description='desc2', creator='owner', project=p.id) IssueSearch.index_a_project_issue(p) res = IssueSearch.search_a_phrase('owner', p.id) res = SearchEngine.decode(res, ('issue_id', )) res = [id for id, in res] assert len(res) == 2 assert iss1.id in res assert iss2.id in res
def test_add_tags(self): target_id = project_id = 1 p = ProjectIssue.add( 'test', 'test description', 'test', project=project_id) assert isinstance(p, ProjectIssue) assert p.title == 'test' assert p.description == 'test description' assert p.project_id == 1 tags = ['tag1', 'tag2', 'tag3'] p.add_tags(tags, target_id) assert len(p.tags) == len(tags) tag_names = [t.name for t in p.tags] assert set(tags) & set(tag_names) == set(tags)
def test_get_single_issue(self): title = "test title" description = "test desc" creator = "test" issue = ProjectIssue.add(title, description, creator, project=self.project.id) IssueComment.add(issue.issue_id, 'content', 'test') ret = self.app.get("/api/%s/issues/%s/" % (self.project.name, issue.number), status=200).json self.assertEquals(ret['title'], title) self.assertEquals(ret['description'], description) self.assertEquals(ret['creator'], creator) self.assertEquals(ret['project'], self.project.name) self.assertEquals(ret['comments'], 1)
def test_add_tags(self): target_id = project_id = 1 p = ProjectIssue.add( 'test', 'test description', 'test', project=project_id) assert isinstance(p, ProjectIssue) assert p.title == 'test' assert p.description == 'test description' assert p.project_id == 1 tags = ['tag1', 'tag2', 'tag3'] p.add_tags(tags, target_id) assert len(p.tags) == len(tags) tag_names = [t.name for t in p.tags] assert set(tags) & set(tag_names) == set(tags) p.delete()
def mute(request): ''' mute ticket(pr) or issue, just 'project' scope yet. ''' user = request.user if user: entry_type = request.get_form_var('type', '') target = request.get_form_var('target', '') entry_id = request.get_form_var('id', '') if entry_type == 'pull': Mute.mute('ticket', target, entry_id, user) elif entry_type == 'issue': # TODO: models.issue.leave or mute issue = ProjectIssue.get_by_proj_name_and_number(target, entry_id) if user.name != issue.creator_id: issue.delete_participant(user.name) return dict(r=0) else: return dict(r=1)
def test_upate_issue(self): title = "test title" description = "test desc" creator = self.username issue = ProjectIssue.add(title, description, creator, project=self.project.id) new_title = "new title" new_description = 'new desc' ret = self.app.patch_json( "/api/%s/issues/%s/" % (self.project.name, issue.number), dict(title=new_title, description=new_description, state="closed"), headers=dict(Authorization="Bearer %s" % self.api_token.token), ).json self.assertEquals(ret["title"], new_title) self.assertEquals(ret["description"], new_description) self.assertEquals(ret["state"], "closed")
def test_two_comments_display(self): app = TestApp(M.app) project_name = "project4" delete_project(project_name) project = CodeDoubanProject.add(project_name, owner_id="test1", summary="test", product="fire") issue = ProjectIssue.add('test', 'test description', 'test', project=project.id) issue.add_comment('this is a comment', 'test') issue.add_comment('this is also a comment', 'test') resp = app.get(project.url + "/issues/") assert resp.status_int == 200 assert "Issues" in resp.body assert "2 comments" in resp.body
def test_two_votes_display(self): app = TestApp(M.app) project_name = "project3" delete_project(project_name) project = CodeDoubanProject.add(project_name, owner_id="test1", summary="test", product="fire") issue = ProjectIssue.add('test', 'test description', 'test', project=project.id) issue.upvote_by_user('test1') issue.upvote_by_user('test2') resp = app.get(project.url + "/issues/") assert resp.status_int == 200 assert "Issues" in resp.body assert "2 votes" in resp.body
def patch(self, request): issue = Issue.get_cached_issue(self.project_issue.issue_id) if self.user.username != issue.creator_id: raise api_errors.NotTheAuthorError('project issue', 'edit') data = request.data state = data.get("state") if state in ("open", "closed") and state != issue.state: if state == "open": issue.open(self.user.username) else: issue.close(self.user.username) title = data.get("title") title = title if title else issue.title description = data.get("description") description = description if description else issue.description issue.update(title, description) new_issue = ProjectIssue.get(project_id=self.project.id, number=self.issue_number) return new_issue.as_dict()
def test_open_and_close_issue(self): p1 = ProjectIssue.add('test1', 'test1 description', 'test', project=1) p2 = ProjectIssue.add('test2', 'test2 description', 'test', project=1) p3 = ProjectIssue.add('test3', 'test3 description', 'test', project=1) count = ProjectIssue.get_count_by_project_id(1) assert count == 3 p1.close('test') count = ProjectIssue.get_count_by_project_id(1, 'open') assert count == 2 p1.open() count = ProjectIssue.get_count_by_project_id(1, 'open') assert count == 3 for p in [p1, p2, p3]: p.delete()
def post(self, request): title = request.data.get("title") if not title: raise api_errors.MissingFieldError('title') # optional parameters description = request.data.get("description", "") assignee = request.data.get("assignee", "") tags = request.data.get("tags", []) participants = request.data.get("participants", []) if not isinstance(tags, list): raise api_errors.InvalidFieldError('tags', "an array of strings") issue = ProjectIssue.add(title=title, description=description, creator=request.user.username, project=self.project.id, assignee=assignee) issue.add_tags(tags, issue.project_id) issue.add_participants(participants) return issue.as_dict()