def testPaginateComments_Visible(self): mr = testing_helpers.MakeMonorailRequest() config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) issue = fake.MakeTestIssue(789, 1, 'summary', 'New', 111L) issuecomment_list = [tracker_pb2.IssueComment()] # 500 comments, none deleted. for _ in range(500): issuecomment_list.append(tracker_pb2.IssueComment()) description, visible_comments, pagination = issuepeek.PaginateComments( mr, issue, issuecomment_list, config) self.assertEqual([issuecomment_list[0]], description) self.assertEqual(issuecomment_list[1:], visible_comments) self.assertFalse(pagination.visible) # 501 comments, none deleted. issuecomment_list.append(tracker_pb2.IssueComment()) description, visible_comments, pagination = issuepeek.PaginateComments( mr, issue, issuecomment_list, config) self.assertEqual([issuecomment_list[0]], description) self.assertEqual(issuecomment_list[2:], visible_comments) self.assertTrue(pagination.visible) self.assertEqual(2, pagination.last) self.assertEqual(501, pagination.start) # 501 comments, 1 of them deleted. issuecomment_list[1].deleted_by = 123 description, visible_comments, pagination = issuepeek.PaginateComments( mr, issue, issuecomment_list, config) self.assertEqual([issuecomment_list[0]], description) self.assertEqual(issuecomment_list[2:], visible_comments) self.assertFalse(pagination.visible)
def testPaginateComments_Visible(self): mr = testing_helpers.MakeMonorailRequest() config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) issue = fake.MakeTestIssue(789, 1, 'summary', 'New', 111) issuecomment_list = [tracker_pb2.IssueComment()] # full page of comments, none deleted. for _ in range(framework_constants.DEFAULT_COMMENTS_PER_PAGE): issuecomment_list.append(tracker_pb2.IssueComment()) description, visible_comments, pagination = issuepeek.PaginateComments( mr, issue, issuecomment_list, config, self.services) self.assertEqual([issuecomment_list[0]], description) self.assertEqual(issuecomment_list[1:], visible_comments) self.assertFalse(pagination.visible) # One comment on second page, none deleted. issuecomment_list.append(tracker_pb2.IssueComment()) description, visible_comments, pagination = issuepeek.PaginateComments( mr, issue, issuecomment_list, config, self.services) self.assertEqual([issuecomment_list[0]], description) self.assertEqual(issuecomment_list[2:], visible_comments) self.assertTrue(pagination.visible) self.assertEqual(2, pagination.last) self.assertEqual(framework_constants.DEFAULT_COMMENTS_PER_PAGE + 1, pagination.start) # One comment on second page, 1 of them deleted. issuecomment_list[1].deleted_by = 123 description, visible_comments, pagination = issuepeek.PaginateComments( mr, issue, issuecomment_list, config, self.services) self.assertEqual([issuecomment_list[0]], description) self.assertEqual(issuecomment_list[2:], visible_comments) self.assertFalse(pagination.visible)
def setUp(self): self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_app_identity_stub() services = service_manager.Services(project=fake.ProjectService(), config=fake.ConfigService(), issue=fake.IssueService(), user=fake.UserService()) self.project = services.project.TestAddProject('proj') self.servlet = issueattachmenttext.AttachmentText('req', 'res', services=services) self.issue = tracker_pb2.Issue() self.issue.local_id = 1 self.issue.issue_id = 1 self.issue.summary = 'sum' self.issue.project_name = 'proj' self.issue.project_id = self.project.project_id services.issue.TestAddIssue(self.issue) self.comment0 = tracker_pb2.IssueComment() self.comment0.content = 'this is the description' self.comment1 = tracker_pb2.IssueComment() self.comment1.content = 'this is a comment' self.attach0 = tracker_pb2.Attachment( attachment_id=4567, filename='b.txt', mimetype='text/plain', gcs_object_id='/pid/attachments/abcd') self.comment0.attachments.append(self.attach0) self.attach1 = tracker_pb2.Attachment( attachment_id=1234, filename='a.txt', mimetype='text/plain', gcs_object_id='/pid/attachments/abcdefg') self.comment0.attachments.append(self.attach1) self.bin_attach = tracker_pb2.Attachment( attachment_id=2468, mimetype='application/octets', gcs_object_id='/pid/attachments/\0\0\0\0\0\1\2\3') self.comment1.attachments.append(self.bin_attach) self.comment0.project_id = self.project.project_id services.issue.TestAddComment(self.comment0, self.issue.local_id) self.comment1.project_id = self.project.project_id services.issue.TestAddComment(self.comment1, self.issue.local_id) services.issue.TestAddAttachment(self.attach0, self.comment0.id, self.issue.issue_id) services.issue.TestAddAttachment(self.attach1, self.comment1.id, self.issue.issue_id) # TODO(jrobbins): add tests for binary content self._old_gcs_open = cloudstorage.open cloudstorage.open = fake.gcs_open
def testClassifyIssue_Whitelisted(self): issue = fake.MakeTestIssue(project_id=789, local_id=1, reporter_id=111L, owner_id=456, summary='sum', status='Live', issue_id=78901, is_spam=True) self.spam_service._predict = lambda *args: { 'outputLabel': 'this should not be called' } # Prevent missing service inits to fail the test. self.spam_service.prediction_service = True comment_pb = tracker_pb2.IssueComment() comment_pb.content = "this is spam" reporter = user_pb2.MakeUser(111L, email='*****@*****.**') res = self.spam_service.ClassifyIssue(issue, comment_pb, reporter, False) self.assertEqual('ham', res['outputLabel']) reporter.email = '*****@*****.**' res = self.spam_service.ClassifyIssue(issue, comment_pb, reporter, False) self.assertEqual('ham', res['outputLabel'])
def testConvertComment(self): """Test convert_comment.""" svcs = service_manager.Services() svcs.user = fake.UserService() svcs.user.TestAddUser('*****@*****.**', 1) mar = mock.Mock() mar.cnxn = None issue = fake.MakeTestIssue(project_id=12345, local_id=1, summary='sum', status='New', owner_id=1001) comment = tracker_pb2.IssueComment( user_id=1, content='test content', sequence=1, deleted_by=1, timestamp=1437700000, ) result = api_pb2_v1_helpers.convert_comment(issue, comment, mar, svcs, None) self.assertEquals('*****@*****.**', result.author.name) self.assertEquals(comment.content, result.content) self.assertEquals('*****@*****.**', result.deletedBy.name) self.assertEquals(1, result.id) # Ensure that the published timestamp falls in a timestamp range to account # for the test being run in different timezones. # Using "Fri, 23 Jul 2015 00:00:00" and "Fri, 25 Jul 2015 00:00:00". self.assertTrue( datetime.datetime(2015, 7, 23, 0, 0, 0) <= result.published <= datetime.datetime(2015, 7, 25, 0, 0, 0))
def testConvertApprovalComment(self): """Test convert_approval_comment.""" mar = mock.Mock() mar.cnxn = None mar.perms = permissions.PermissionSet([]) issue = fake.MakeTestIssue(project_id=12345, local_id=1, summary='sum', status='New', owner_id=1001) comment = tracker_pb2.IssueComment( user_id=111, content='test content', sequence=1, deleted_by=111, timestamp=1437700000, ) result = api_pb2_v1_helpers.convert_approval_comment( issue, comment, mar, self.services, None) self.assertEquals('*****@*****.**', result.author.name) self.assertEquals(comment.content, result.content) self.assertEquals('*****@*****.**', result.deletedBy.name) self.assertEquals(1, result.id) # Ensure that the published timestamp falls in a timestamp range to account # for the test being run in different timezones. # Using "Fri, 23 Jul 2015 00:00:00" and "Fri, 25 Jul 2015 00:00:00". self.assertTrue( datetime.datetime(2015, 7, 23, 0, 0, 0) <= result.published <= datetime.datetime(2015, 7, 25, 0, 0, 0)) self.assertEqual(result.kind, 'monorail#approvalComment')
def testIssuesCommentsList_GetComments(self): """Get comments of requested issue.""" self.services.project.TestAddProject( 'test-project', owner_ids=[2], project_id=12345) issue1 = fake.MakeTestIssue( project_id=12345, local_id=1, summary='test summary', status='New', issue_id=10001, owner_id=2, reporter_id=1) self.services.issue.TestAddIssue(issue1) comment = tracker_pb2.IssueComment( id=123, issue_id=10001, project_id=12345, user_id=2, content='this is a comment', timestamp=1437700000) self.services.issue.TestAddComment(comment, 1) resp = self.call_api('issues_comments_list', self.request).json_body self.assertEqual(2, resp['totalResults']) comment1 = resp['items'][0] comment2 = resp['items'][1] self.assertEqual('*****@*****.**', comment1['author']['name']) self.assertEqual('test summary', comment1['content']) self.assertEqual('*****@*****.**', comment2['author']['name']) self.assertEqual('this is a comment', comment2['content'])
def testClassifyIssue_spam(self): issue = fake.MakeTestIssue(project_id=789, local_id=1, reporter_id=111, owner_id=456, summary='sum', status='Live', issue_id=78901, is_spam=True) self.spam_service._predict = lambda body: 1.0 # Prevent missing service inits to fail the test. self.spam_service.ml_engine = True comment_pb = tracker_pb2.IssueComment() comment_pb.content = "this is spam" reporter = user_pb2.MakeUser(111, email='*****@*****.**') res = self.spam_service.ClassifyIssue(issue, comment_pb, reporter, False) self.assertEqual(1.0, res['confidence_is_spam']) reporter.email = '*****@*****.**' res = self.spam_service.ClassifyIssue(issue, comment_pb, reporter, False) self.assertEqual(1.0, res['confidence_is_spam']) reporter.email = '*****@*****.**' res = self.spam_service.ClassifyIssue(issue, comment_pb, reporter, False) self.assertEqual(1.0, res['confidence_is_spam'])
def setUp(self): self.mox = mox.Mox() self.mock_index = self.mox.CreateMockAnything() self.mox.StubOutWithMock(search, 'Index') self.docs = None self.cnxn = 'fake connection' self.user_service = fake.UserService() self.user_service.TestAddUser('*****@*****.**', 111) self.issue_service = fake.IssueService() self.config_service = fake.ConfigService() self.issue = fake.MakeTestIssue(123, 1, 'test summary', 'New', 111) self.issue_service.TestAddIssue(self.issue) self.comment = tracker_pb2.IssueComment( project_id=789, issue_id=self.issue.issue_id, user_id=111, content='comment content', attachments=[ tracker_pb2.Attachment(filename='hello.c'), tracker_pb2.Attachment(filename='hello.h') ]) self.issue_service.TestAddComment(self.comment, 1) self.users_by_id = framework_views.MakeAllUserViews( self.cnxn, self.user_service, [111])
def setUp(self): self.mox = mox.Mox() self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_memcache_stub() self.testbed.init_app_identity_stub() self.testbed.init_urlfetch_stub() self.attachment_data = "" self._old_gcs_open = cloudstorage.open cloudstorage.open = fake.gcs_open services = service_manager.Services( project=fake.ProjectService(), config=fake.ConfigService(), issue=fake.IssueService(), user=fake.UserService()) self.project = services.project.TestAddProject('proj') self.servlet = issueattachment.AttachmentPage( 'req', webapp2.Response(), services=services) self.issue = fake.MakeTestIssue( self.project.project_id, 1, 'summary', 'New', 111L) services.issue.TestAddIssue(self.issue) self.comment = tracker_pb2.IssueComment( id=123, issue_id=self.issue.issue_id, project_id=self.project.project_id, user_id=111L, content='this is a comment') services.issue.TestAddComment(self.comment, self.issue.local_id) self.attachment = tracker_pb2.Attachment( attachment_id=54321, filename='hello.txt', filesize=23432, mimetype='text/plain', gcs_object_id='/pid/attachments/hello.txt') services.issue.TestAddAttachment( self.attachment, self.comment.id, self.issue.issue_id)
def setUp(self): self.services = service_manager.Services(project=fake.ProjectService(), config=fake.ConfigService(), issue=fake.IssueService(), user=fake.UserService()) self.servlet = issueoriginal.IssueOriginal('req', 'res', services=self.services) self.proj = self.services.project.TestAddProject('proj', project_id=789) summary = 'System wont boot' status = 'New' cnxn = 'fake connection' self.services.user.TestAddUser('*****@*****.**', 222) self.local_id_1, desc = self.services.issue.CreateIssue( cnxn, self.services, 789, summary, status, 111, [], [], [], [], 111, 'The screen is just dark when I press power on') comment_0 = tracker_pb2.IssueComment(issue_id=desc.issue_id, user_id=222, project_id=789, content=STRIPPED_MSG, inbound_message=ORIG_MSG) self.services.issue.InsertComment(cnxn, comment_0) comment_1 = tracker_pb2.IssueComment(issue_id=desc.issue_id, user_id=222, project_id=789, content=STRIPPED_MSG, inbound_message=BAD_UNICODE_MSG) self.services.issue.InsertComment(cnxn, comment_1) comment_2 = tracker_pb2.IssueComment(issue_id=desc.issue_id, user_id=222, project_id=789, content=STRIPPED_MSG, inbound_message=GMAIL_CRUFT_MSG) self.services.issue.InsertComment(cnxn, comment_2) comment_3 = tracker_pb2.IssueComment(issue_id=desc.issue_id, user_id=222, project_id=789, content=STRIPPED_MSG, inbound_message=GOOD_UNICODE_MSG) self.services.issue.InsertComment(cnxn, comment_3) self.issue_1 = self.services.issue.GetIssueByLocalID( cnxn, 789, self.local_id_1) self.comments = [comment_0, comment_1, comment_2, comment_3]
def testUsersInvolvedInCommentList(self): self.assertEqual(set(), tracker_bizobj.UsersInvolvedInCommentList([])) c1 = tracker_pb2.IssueComment() c1.user_id = 111L c1.amendments.append(tracker_pb2.Amendment(newvalue='foo')) c2 = tracker_pb2.IssueComment() c2.user_id = 111L c2.amendments.append(tracker_pb2.Amendment( added_user_ids=[222L], removed_user_ids=[333L])) self.assertEqual({111L}, tracker_bizobj.UsersInvolvedInCommentList([c1])) self.assertEqual({111L, 222L, 333L}, tracker_bizobj.UsersInvolvedInCommentList([c2])) self.assertEqual({111L, 222L, 333L}, tracker_bizobj.UsersInvolvedInCommentList([c1, c2]))
def ExecuteIssueChanges(self, config, issue, new_approvals, phases, new_fvs): # Apply Approval and phase changes approval_defs_by_id = { ad.approval_id: ad for ad in config.approval_defs } for av in new_approvals: ad = approval_defs_by_id.get(av.approval_id) if ad: av.approver_ids = ad.approver_ids survey = '' if ad.survey: questions = ad.survey.split('\n') survey = '\n'.join(['<b>' + q + '</b>' for q in questions]) self.services.issue.InsertComment( self.mr.cnxn, tracker_pb2.IssueComment(issue_id=issue.issue_id, project_id=issue.project_id, user_id=self.mr.auth.user_id, content=survey, is_description=True, approval_id=av.approval_id, timestamp=int(time.time()))) else: logging.info( 'ERROR: ApprovalDef %r for ApprovalValue %r not valid', ad, av) issue.approval_values = new_approvals self.services.issue._UpdateIssuesApprovals(self.mr.cnxn, issue) # Apply field value changes issue.phases = phases delta = tracker_bizobj.MakeIssueDelta( None, None, [], [], [], [], ['Type-FLT-Launch', 'FLT-Conversion'], ['Type-Launch'], new_fvs, [], [], [], [], [], [], None, None) amendments, _ = self.services.issue.DeltaUpdateIssue( self.mr.cnxn, self.services, self.mr.auth.user_id, issue.project_id, config, issue, delta, comment=CONVERSION_COMMENT) return amendments
def testUsersInvolvedInComment(self): comment = tracker_pb2.IssueComment() self.assertEqual({0}, tracker_bizobj.UsersInvolvedInComment(comment)) comment.user_id = 111L self.assertEqual( {111L}, tracker_bizobj.UsersInvolvedInComment(comment)) amendment = tracker_pb2.Amendment(newvalue='foo') comment.amendments.append(amendment) self.assertEqual( {111L}, tracker_bizobj.UsersInvolvedInComment(comment)) amendment.added_user_ids.append(222L) amendment.removed_user_ids.append(333L) self.assertEqual({111L, 222L, 333L}, tracker_bizobj.UsersInvolvedInComment(comment))
def _ParseComment(self, project_id, user_id_dict, comment_json, event_log): comment = tracker_pb2.IssueComment( # Note: issue_id is filled in after the issue is saved. project_id=project_id, timestamp=comment_json['timestamp'], user_id=user_id_dict[comment_json['commenter']], content=comment_json.get('content')) for amendment in comment_json['amendments']: comment.amendments.append( self._ParseAmendment(amendment, user_id_dict, event_log)) for attachment in comment_json['attachments']: comment.attachments.append( self._ParseAttachment(attachment, event_log)) return comment
def testNotifyApprovalChangeTask_GetApprovalEmailRecipients(self): task = notify.NotifyApprovalChangeTask(request=None, response=None, services=self.services) issue = fake.MakeTestIssue(789, 1, 'summary', 'New', 111) approval_value = tracker_pb2.ApprovalValue( approver_ids=[222, 333], status=tracker_pb2.ApprovalStatus.APPROVED) comment = tracker_pb2.IssueComment(project_id=789, user_id=1, issue_id=78901) # Comment with not amendments notifies everyone. rids = task._GetApprovalEmailRecipients(approval_value, comment, issue, [777, 888]) self.assertItemsEqual(rids, [111, 222, 333, 777, 888]) # New APPROVED status notifies owners and any_comment users. amendment = tracker_bizobj.MakeApprovalStatusAmendment( tracker_pb2.ApprovalStatus.APPROVED) comment.amendments = [amendment] rids = task._GetApprovalEmailRecipients(approval_value, comment, issue, [777, 888]) self.assertItemsEqual(rids, [111, 777, 888]) # New REVIEW_REQUESTED status notifies approvers. approval_value.status = tracker_pb2.ApprovalStatus.REVIEW_REQUESTED amendment = tracker_bizobj.MakeApprovalStatusAmendment( tracker_pb2.ApprovalStatus.REVIEW_REQUESTED) comment.amendments = [amendment] rids = task._GetApprovalEmailRecipients(approval_value, comment, issue, [777, 888]) self.assertItemsEqual(rids, [222, 333]) # Approvers change notifies everyone. amendment = tracker_bizobj.MakeApprovalApproversAmendment([222], [555]) comment.amendments = [amendment] approval_value.approver_ids = [222] rids = task._GetApprovalEmailRecipients(approval_value, comment, issue, [777], omit_ids=[444, 333]) self.assertItemsEqual(rids, [111, 222, 555, 777])
def testProcessAlert_ExistingIssueTimeDelay(self): """Don't add a comment if it's been less than 24 hours.""" self.issue.labels = ['Incident-Id-incident-1'] self.mox.StubOutWithMock(self.services.config, 'LookupLabelID') self.services.config.LookupLabelID( self.cnxn, self.project.project_id, 'Incident-Id-incident-1').AndReturn(1234) self.mox.StubOutWithMock(self.services.issue, 'GetIIDsByLabelIDs') self.services.issue.GetIIDsByLabelIDs(self.cnxn, [1234], self.project.project_id, None).AndReturn([1]) self.mox.StubOutWithMock(self.services.issue, 'GetOpenAndClosedIssues') self.services.issue.GetOpenAndClosedIssues(self.cnxn, [1]).AndReturn( ([self.issue], [])) comment = tracker_pb2.IssueComment() comment.timestamp = int(time.time()) self.mox.StubOutWithMock(self.services.issue, 'GetComments') self.services.issue.GetComments(self.cnxn, issue_id=[self.issue.issue_id], commenter_id=[111 ]).AndReturn([comment]) # CreateIssueComment should not be called. self.mox.StubOutWithMock(self.services.issue, 'CreateIssueComment') self.mox.ReplayAll() auth = authdata.AuthData(user_id=111, email='*****@*****.**') ret = self.inbound.ProcessAlert(self.cnxn, self.project, self.project_addr, '*****@*****.**', auth, 'issue title', 'issue body', 'incident-1') self.mox.VerifyAll() self.assertIsNone(ret)
def testProcessFormData_okSomeCommentsAndIssues(self): mr = testing_helpers.MakeMonorailRequest( path=urls.BAN_SPAMMER_TASK + '.do', method='POST', params={'spammer_id': 111L, 'reporter_id': 222L}) for i in range(0, 12): issue = fake.MakeTestIssue( 001, i, 'issue_summary', 'New', 111L, project_name='project-name') self.servlet.services.issue.TestAddIssue(issue) for i in range(10, 20): issue = fake.MakeTestIssue( 001, i, 'issue_summary', 'New', 222L, project_name='project-name') self.servlet.services.issue.TestAddIssue(issue) for _ in range(0, 5): comment = tracker_pb2.IssueComment() comment.project_id = 001 comment.user_id = 111L comment.issue_id = issue.issue_id self.servlet.services.issue.TestAddComment(comment, issue.local_id) self.servlet.HandleRequest(mr) self.assertEqual(self.res.body, json.dumps({'comments': 50, 'issues': 10}))
def testIssuesCommentsDelete_DeleteUndelete(self): self.services.project.TestAddProject( 'test-project', owner_ids=[2], project_id=12345) issue1 = fake.MakeTestIssue( project_id=12345, local_id=1, summary='test summary', issue_id=10001, status='New', owner_id=2, reporter_id=1) self.services.issue.TestAddIssue(issue1) comment = tracker_pb2.IssueComment( id=123, issue_id=10001, project_id=12345, user_id=1, content='this is a comment', timestamp=1437700000) self.services.issue.TestAddComment(comment, 1) self.request['commentId'] = 1 comments = self.services.issue.GetCommentsForIssue(None, 10001) self.call_api('issues_comments_delete', self.request) self.assertEqual(1, comments[1].deleted_by) self.call_api('issues_comments_undelete', self.request) self.assertIsNone(comments[1].deleted_by)
def testMakeEmailTasks(self): issue = fake.MakeTestIssue(789, 1, 'summary', 'New', self.owner.user_id, issue_id=78901) self.services.issue.TestAddIssue(issue) now = int(time.time()) issue.field_values = [ tracker_bizobj.MakeFieldValue(123, None, None, None, now, False), tracker_bizobj.MakeFieldValue(124, None, None, None, now, False), tracker_bizobj.MakeFieldValue(125, None, None, None, now, False), ] issue.project_name = 'proj' comment = tracker_pb2.IssueComment() comment.project_id = self.project.project_id comment.user_id = self.date_action_user.user_id comment.content = 'Some date(s) arrived...' next_action_field_def = self.config.field_defs[0] pings = [(next_action_field_def, now)] users_by_id = framework_views.MakeAllUserViews( 'fake cnxn', self.services.user, [self.owner.user_id, self.date_action_user.user_id]) tasks = self.servlet._MakeEmailTasks('fake cnxn', issue, self.project, self.config, comment, 'example-app.appspot.com', users_by_id, pings) self.assertEqual(1, len(tasks)) notify_owner_task = tasks[0] self.assertEqual('*****@*****.**', notify_owner_task['to']) self.assertEqual('Follow up on issue 1 in proj: summary', notify_owner_task['subject']) body = notify_owner_task['body'] self.assertIn(comment.content, body) self.assertIn(next_action_field_def.docstring, body)
def createAndAssertUpdates(self, project_ids=None, user_ids=None, ascending=True): user = user_pb2.MakeUser(self.user_id) comment_1 = tracker_pb2.IssueComment(id=self.comment_id, issue_id=self.issue_id, project_id=self.project_id, user_id=self.user_id, content='this is the 1st comment', timestamp=self.comment_timestamp) self.mox.StubOutWithMock(self.services.issue, 'GetIssueActivity') after = 0 if ascending: after = self.mr_after self.services.issue.GetIssueActivity(mox.IgnoreArg(), num=50, before=0, after=after, project_ids=project_ids, user_ids=user_ids, ascending=ascending).AndReturn( [comment_1]) self.mox.StubOutWithMock(framework_views, 'MakeAllUserViews') framework_views.MakeAllUserViews(mox.IgnoreArg(), self.services.user, [self.user_id], []).AndReturn({self.user_id: user}) self.mox.ReplayAll() mr = testing_helpers.MakeMonorailRequest() if ascending: mr.after = self.mr_after updates_page_url = 'testing/testing' updates_data = activities.GatherUpdatesData( self.services, mr, project_ids=project_ids, user_ids=user_ids, ending=None, autolink=None, highlight='highlightme', updates_page_url=updates_page_url) self.mox.VerifyAll() if mr.after: pagination = updates_data['pagination'] self.assertIsNone(pagination.last) self.assertEquals( '%s?before=%d' % (updates_page_url.split('/')[-1], self.comment_timestamp), pagination.next_url) self.assertEquals( '%s?after=%d' % (updates_page_url.split('/')[-1], self.comment_timestamp), pagination.prev_url) activity_view = updates_data['updates_data'].older[0] self.assertEqual( '<a class="ot-issue-link"\n \n ' 'href="/p//issues/detail?id=%s#c_ts%s"\n >' 'issue %s</a>\n\n()\n\n\n\n\n \n commented on' % (self.issue_local_id, self.comment_timestamp, self.issue_local_id), activity_view.escaped_title) self.assertEqual( '<span class="ot-issue-comment">\n this is the 1st comment\n</span>', activity_view.escaped_body) self.assertEqual('highlightme', activity_view.highlight) self.assertEqual(self.project_name, activity_view.project_name)
def createAndAssertUpdates(self, project_ids=None, user_ids=None, ascending=True): user = user_pb2.MakeUser(self.user_id) comment_1 = tracker_pb2.IssueComment(id=self.comment_id, issue_id=self.issue_id, project_id=self.project_id, user_id=self.user_id, content='this is the 1st comment', timestamp=self.comment_timestamp) self.mox.StubOutWithMock(self.services.issue, 'GetComments') created_order = 'created' field = 'project_id' if project_ids else 'commenter_id' where_clauses = [('Issue.id = Comment.issue_id', [])] if project_ids: where_clauses.append(('Comment.project_id IN (%s)', project_ids)) if user_ids: where_clauses.append(('Comment.commenter_id IN (%s)', user_ids)) if ascending: where_clauses.append(('created > %s', [self.mr_after])) else: created_order += ' DESC' self.services.issue.GetComments( mox.IgnoreArg(), deleted_by=None, joins=[('Issue', [])], limit=activities.UPDATES_PER_PAGE + 1, order_by=[(created_order, [])], use_clause='USE INDEX (%s) USE INDEX FOR ORDER BY (%s)' % (field, field), where=where_clauses).AndReturn([comment_1]) self.mox.StubOutWithMock(framework_views, 'MakeAllUserViews') framework_views.MakeAllUserViews(mox.IgnoreArg(), self.services.user, [self.user_id], []).AndReturn({self.user_id: user}) self.mox.ReplayAll() mr = testing_helpers.MakeMonorailRequest() if ascending: mr.after = self.mr_after updates_page_url = 'testing/testing' updates_data = activities.GatherUpdatesData( self.services, mr, profiler.Profiler(), project_ids=project_ids, user_ids=user_ids, ending=None, autolink=None, highlight='highlightme', updates_page_url=updates_page_url) self.mox.VerifyAll() if mr.after: pagination = updates_data['pagination'] self.assertIsNone(pagination.last) self.assertEquals( '%s?before=%d' % (updates_page_url.split('/')[-1], self.comment_timestamp), pagination.next_url) self.assertEquals( '%s?after=%d' % (updates_page_url.split('/')[-1], self.comment_timestamp), pagination.prev_url) activity_view = updates_data['updates_data'].older[0] self.assertEqual( '<a class="ot-issue-link"\n \n ' 'href="/p//issues/detail?id=%s#c_ts%s"\n >' 'issue %s</a>\n\n()\n\n\n\n\n \n commented on' % (self.issue_local_id, self.comment_timestamp, self.issue_local_id), activity_view.escaped_title) self.assertEqual( '<span class="ot-issue-comment">\n this is the 1st comment\n</span>', activity_view.escaped_body) self.assertEqual('highlightme', activity_view.highlight) self.assertEqual(self.project_name, activity_view.project_name)
def MakePingComment(self): comment = tracker_pb2.IssueComment() comment.project_id = self.project.project_id comment.user_id = self.date_action_user.user_id comment.content = 'Some date(s) arrived...' return comment
def testMakeIssueJSON(self): config = self.services.config.GetProjectConfig(self.cnxn, 789) config.field_defs.extend([ tracker_pb2.FieldDef( field_id=1, field_name='UXReview', field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE), tracker_pb2.FieldDef(field_id=2, field_name='approvalsubfield', field_type=tracker_pb2.FieldTypes.STR_TYPE, approval_id=1), tracker_pb2.FieldDef(field_id=3, field_name='phasefield', field_type=tracker_pb2.FieldTypes.INT_TYPE, is_phase_field=True), tracker_pb2.FieldDef(field_id=4, field_name='normalfield', field_type=tracker_pb2.FieldTypes.STR_TYPE) ]) self.services.config.StoreConfig(self.cnxn, config) phases = [ tracker_pb2.Phase(phase_id=1, name='Phase1', rank=1), tracker_pb2.Phase(phase_id=2, name='Phase2', rank=2) ] avs = [ tracker_pb2.ApprovalValue( approval_id=1, status=tracker_pb2.ApprovalStatus.APPROVED, setter_id=111, set_on=7, approver_ids=[333, 444], phase_id=1) ] fvs = [ tracker_pb2.FieldValue(field_id=2, str_value='two'), tracker_pb2.FieldValue(field_id=3, int_value=3, phase_id=2), tracker_pb2.FieldValue(field_id=4, str_value='four') ] labels = ['test', 'Type-FLT-Launch'] issue = fake.MakeTestIssue(self.project.project_id, 1, 'summary', 'Open', 111, labels=labels, issue_id=78901, reporter_id=222, opened_timestamp=1, closed_timestamp=2, modified_timestamp=3, project_name='project', field_values=fvs, phases=phases, approval_values=avs) email_dict = { 111: '*****@*****.**', 222: '*****@*****.**', 333: '*****@*****.**', 444: '*****@*****.**' } comment_list = [ tracker_pb2.IssueComment(content='simple'), tracker_pb2.IssueComment(content='issue desc', is_description=True) ] starrer_id_list = [222, 333] issue_JSON = self.jsonfeed._MakeIssueJSON(self.mr, issue, email_dict, comment_list, starrer_id_list) expected_JSON = { 'local_id': 1, 'reporter': '*****@*****.**', 'summary': 'summary', 'owner': '*****@*****.**', 'status': 'Open', 'cc': [], 'labels': labels, 'phases': [{ 'id': 1, 'name': 'Phase1', 'rank': 1 }, { 'id': 2, 'name': 'Phase2', 'rank': 2 }], 'fields': [{ 'field': 'approvalsubfield', 'phase': None, 'approval': 'UXReview', 'str_value': 'two' }, { 'field': 'phasefield', 'phase': 'Phase2', 'int_value': 3 }, { 'field': 'normalfield', 'phase': None, 'str_value': 'four' }], 'approvals': [{ 'approval': 'UXReview', 'status': 'APPROVED', 'setter': '*****@*****.**', 'set_on': 7, 'approvers': ['*****@*****.**', '*****@*****.**'], 'phase': 'Phase1' }], 'starrers': ['*****@*****.**', '*****@*****.**'], 'comments': [ { 'content': 'simple', 'timestamp': None, 'amendments': [], 'commenter': None, 'attachments': [], 'description_num': None }, { 'content': 'issue desc', 'timestamp': None, 'amendments': [], 'commenter': None, 'attachments': [], 'description_num': '1' }, ], 'opened': 1, 'modified': 3, 'closed': 2, } self.assertEqual(expected_JSON, issue_JSON)
def testNotifyApprovalChangeTask_Normal(self): config = self.services.config.GetProjectConfig('cnxn', 12345) config.field_defs = [ # issue's User field with any_comment is notified. tracker_bizobj.MakeFieldDef( 121, 12345, 'TL', tracker_pb2.FieldTypes.USER_TYPE, '', '', False, False, False, None, None, None, False, '', None, tracker_pb2.NotifyTriggers.ANY_COMMENT, 'no_action', 'TL, notified on everything', False), # issue's User field with never is not notified. tracker_bizobj.MakeFieldDef( 122, 12345, 'silentTL', tracker_pb2.FieldTypes.USER_TYPE, '', '', False, False, False, None, None, None, False, '', None, tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'TL, notified on nothing', False), # approval's User field with any_comment is notified. tracker_bizobj.MakeFieldDef(123, 12345, 'otherapprovalTL', tracker_pb2.FieldTypes.USER_TYPE, '', '', False, False, False, None, None, None, False, '', None, tracker_pb2.NotifyTriggers.ANY_COMMENT, 'no_action', 'TL on the approvers team', False, approval_id=3), # another approval's User field with any_comment is not notified. tracker_bizobj.MakeFieldDef(124, 12345, 'otherapprovalTL', tracker_pb2.FieldTypes.USER_TYPE, '', '', False, False, False, None, None, None, False, '', None, tracker_pb2.NotifyTriggers.ANY_COMMENT, 'no_action', 'TL on another approvers team', False, approval_id=4), tracker_bizobj.MakeFieldDef(3, 12345, 'Goat-Approval', tracker_pb2.FieldTypes.APPROVAL_TYPE, '', '', False, False, False, None, None, None, False, '', None, tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'Get Approval from Goats', False) ] self.services.config.StoreConfig('cnxn', config) # Custom user_type field TLs self.services.user.TestAddUser('*****@*****.**', 111) self.services.user.TestAddUser('*****@*****.**', 222) self.services.user.TestAddUser('*****@*****.**', 333) self.services.user.TestAddUser('*****@*****.**', 444) # Approvers self.services.user.TestAddUser('*****@*****.**', 777) self.services.user.TestAddUser('*****@*****.**', 888) self.services.user.TestAddUser('*****@*****.**', 999) self.services.user.TestAddUser('*****@*****.**', 666) self.services.user.TestAddUser('*****@*****.**', 661) self.services.user.TestAddUser('*****@*****.**', 662) self.services.user.TestAddUser('*****@*****.**', 663) self.services.usergroup.TestAddGroupSettings( 666, '*****@*****.**') self.services.usergroup.TestAddMembers(666, [661, 662, 663]) canary_phase = tracker_pb2.Phase(name='Canary', phase_id=1, rank=1) approval_values = [ tracker_pb2.ApprovalValue(approval_id=3, approver_ids=[888, 999, 666, 661]) ] approval_issue = MakeTestIssue(project_id=12345, local_id=2, owner_id=2, reporter_id=1, is_spam=True) approval_issue.phases = [canary_phase] approval_issue.approval_values = approval_values approval_issue.field_values = [ tracker_bizobj.MakeFieldValue(121, None, None, 111, None, None, False), tracker_bizobj.MakeFieldValue(122, None, None, 222, None, None, False), tracker_bizobj.MakeFieldValue(123, None, None, 333, None, None, False), tracker_bizobj.MakeFieldValue(124, None, None, 444, None, None, False), ] self.services.issue.TestAddIssue(approval_issue) amend = tracker_bizobj.MakeApprovalApproversAmendment([888], [777]) comment = tracker_pb2.IssueComment(project_id=12345, user_id=999, issue_id=approval_issue.issue_id, amendments=[amend], timestamp=1234567890, content='just a comment.') attach = tracker_pb2.Attachment(attachment_id=4567, filename='sploot.jpg', mimetype='image/png', gcs_object_id='/pid/attachments/abcd', filesize=(1024 * 1023)) comment.attachments.append(attach) self.services.issue.TestAddComment(comment, approval_issue.local_id) self.services.issue.TestAddAttachment(attach, comment.id, approval_issue.issue_id) task = notify.NotifyApprovalChangeTask(request=None, response=None, services=self.services) params = { 'send_email': 1, 'issue_id': approval_issue.issue_id, 'approval_id': 3, 'comment_id': comment.id, } mr = testing_helpers.MakeMonorailRequest(user_info={'user_id': 1}, params=params, method='POST', services=self.services) result = task.HandleRequest(mr) self.assertTrue('just a comment' in result['tasks'][0]['body']) self.assertTrue('Approvers: -approver' in result['tasks'][0]['body']) self.assertTrue('sploot.jpg' in result['tasks'][0]['body']) self.assertTrue( '/issues/attachment?aid=4567' in result['tasks'][0]['body']) self.assertItemsEqual([ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**' ], result['notified']) # Test no approvers/groups notified # Status change to NEED_INFO does not email approvers. amend2 = tracker_bizobj.MakeApprovalStatusAmendment( tracker_pb2.ApprovalStatus.NEED_INFO) comment2 = tracker_pb2.IssueComment(project_id=12345, user_id=999, issue_id=approval_issue.issue_id, amendments=[amend2], timestamp=1234567891, content='') self.services.issue.TestAddComment(comment2, approval_issue.local_id) task = notify.NotifyApprovalChangeTask(request=None, response=None, services=self.services) params = { 'send_email': 1, 'issue_id': approval_issue.issue_id, 'approval_id': 3, 'comment_id': comment2.id, } mr = testing_helpers.MakeMonorailRequest(user_info={'user_id': 1}, params=params, method='POST', services=self.services) result = task.HandleRequest(mr) self.assertTrue('Status: need_info' in result['tasks'][0]['body']) self.assertItemsEqual( ['*****@*****.**', '*****@*****.**', '*****@*****.**'], result['notified'])