#!/usr/bin/env python
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit Tests for bug hunter."""
import logging
from optparse import Values
import smtplib
import sys
import unittest
from bug_hunter import BugHunter
from bug_hunter import BugHunterUtils
try:
import atom.data
import gdata.data
import gdata.projecthosting.client
except ImportError:
logging.error('gdata-client needs to be installed. Please install\n'
'and try again (http://code.google.com/p/gdata-python-client/)')
sys.exit(1)
class MockClient(object):
"""A mock class for gdata.projecthosting.client.ProjectHostingClient.
Mocking the very simple method invocations for get_issues() and
get_comments().
"""
def _CreateIssues(self, n_issues):
feed = gdata.projecthosting.data.IssuesFeed()
for i in xrange(n_issues):
feed.entry.append(gdata.projecthosting.data.IssueEntry(
title=atom.data.Title(text='title'),
content=atom.data.Content(text='http://www.content.com'),
id=atom.data.Id(text='/' + str(i)),
status=gdata.projecthosting.data.Status(text='Unconfirmed'),
state=gdata.projecthosting.data.State(text='open'),
label=[gdata.projecthosting.data.Label('label1')],
author=[atom.data.Author(name=atom.data.Name(text='author'))]))
return feed
def get_issues(self, project_name, query):
"""Get issues using mock object without calling the issue tracker API.
Based on query argument, this returns the dummy issues. The number of
dummy issues are specified in query.text_query.
Args:
project_name: A string for project name in the issue tracker.
query: A query object for querying the issue tracker.
Returns:
A IssuesFeed object that contains a simple test issue.
"""
n_issues = 1
if query.text_query.isdigit():
n_issues = int(query.text_query)
return self._CreateIssues(n_issues)
def get_comments(self, project_name, issue_id):
"""Get comments using mock object without calling the issue tracker API.
Args:
project_name: A string for project name in the issue tracker.
issue_id: Issue_id string.
Returns:
A CommentsFeed object that contains a simple test comment.
"""
feed = gdata.projecthosting.data.CommentsFeed()
feed.entry = [gdata.projecthosting.data.CommentEntry(
id=atom.data.Id(text='/0'),
content=atom.data.Content(text='http://www.comments.com'),
updated=atom.data.Updated(text='Updated'),
author=[atom.data.Author(name=atom.data.Name(text='cauthor'))])]
return feed
class BugHunterUnitTest(unittest.TestCase):
"""Unit tests for the Bug Hunter class."""
def setUp(self):
self._old_client = gdata.projecthosting.client.ProjectHostingClient
gdata.projecthosting.client.ProjectHostingClient = MockClient
def tearDown(self):
gdata.projecthosting.client.ProjectHostingClient = self._old_client
def _GetDefaultOption(self, set_10_days_ago, query='steps'):
ops = Values()
ops.query = query
if set_10_days_ago:
ops.interval_value = 10
ops.interval_unit = 'days'
else:
ops.interval_value = None
ops.email_entries = ['comments']
ops.project_name = 'chromium'
ops.query_title = 'query title'
ops.max_comments = None
return ops
def _GetIssue(self, n_issues):
issues = []
for i in xrange(n_issues):
issues.append({'issue_id': str(i), 'title': 'title', 'author': 'author',
'status': 'status', 'state': 'state',
'content': 'content', 'comments': [],
'labels': [], 'urls': []})
return issues
def testSetUpEmailSubjectMsg(self):
bh = BugHunter(self._GetDefaultOption(False))
subject, content = bh._SetUpEmailSubjectMsg(self._GetIssue(1))
self.assertEquals(subject,
'BugHunter found 1 query title bug!')
self.assertEquals(content,
('Used Query: steps
The number of '
'issues : 1
X
'), 'X') def testStripHTMLEmpty(self): self.assertEquals(BugHunterUtils.StripHTML(''), '') def testSendEmail(self): smtplib.SMTP = MockSmtp self.assertEqual(BugHunterUtils.SendEmail('message', 'sender_email_address', 'receivers_email_addresses', 'subject'), True)