1# Copyright (C) 2005-2008, 2010 by Canonical Ltd 2# Authors: Robert Collins <robert.collins@canonical.com> 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 2 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program; if not, write to the Free Software 16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 18from unittest import TestLoader 19 20from .... import ( 21 config, 22 tests, 23 ) 24from ....bzr.bzrdir import BzrDir 25from ....tests import TestCaseInTempDir 26from ..emailer import EmailSender 27 28 29def test_suite(): 30 return TestLoader().loadTestsFromName(__name__) 31 32 33sample_config = (b"[DEFAULT]\n" 34 b"post_commit_to=demo@example.com\n" 35 b"post_commit_sender=Sample <foo@example.com>\n" 36 b"revision_mail_headers=X-Cheese: to the rescue!\n") 37 38unconfigured_config = (b"[DEFAULT]\n" 39 b"email=Robert <foo@example.com>\n") 40 41sender_configured_config = (b"[DEFAULT]\n" 42 b"post_commit_sender=Sample <foo@example.com>\n") 43 44to_configured_config = (b"[DEFAULT]\n" 45 b"post_commit_to=Sample <foo@example.com>\n") 46 47multiple_to_configured_config = (b"[DEFAULT]\n" 48 b"post_commit_sender=Sender <from@example.com>\n" 49 b"post_commit_to=Sample <foo@example.com>, Other <baz@bar.com>\n") 50 51customized_mail_config = (b"[DEFAULT]\n" 52 b"post_commit_to=demo@example.com\n" 53 b"post_commit_sender=Sample <foo@example.com>\n" 54 b"post_commit_subject=[commit] $message\n" 55 b"post_commit_body='''$committer has committed " 56 b"revision 1 at $url.\n\n'''\n") 57 58push_config = (b"[DEFAULT]\n" 59 b"post_commit_to=demo@example.com\n" 60 b"post_commit_push_pull=True\n") 61 62with_url_config = (b"[DEFAULT]\n" 63 b"post_commit_url=http://some.fake/url/\n" 64 b"post_commit_to=demo@example.com\n" 65 b"post_commit_sender=Sample <foo@example.com>\n") 66 67# FIXME: this should not use a literal log, rather grab one from breezy.log 68sample_log = ('------------------------------------------------------------\n' 69 'revno: 1\n' 70 'revision-id: A\n' 71 'committer: Sample <john@example.com>\n' 72 'branch nick: work\n' 73 'timestamp: Thu 1970-01-01 00:00:01 +0000\n' 74 'message:\n' 75 ' foo bar baz\n' 76 ' fuzzy\n' 77 ' wuzzy\n') 78 79 80class TestGetTo(TestCaseInTempDir): 81 82 def test_body(self): 83 sender = self.get_sender() 84 self.assertEqual('At %s\n\n%s' % (sender.url(), sample_log), 85 sender.body()) 86 87 def test_custom_body(self): 88 sender = self.get_sender(customized_mail_config) 89 self.assertEqual('%s has committed revision 1 at %s.\n\n%s' % 90 (sender.revision.committer, sender.url(), sample_log), 91 sender.body()) 92 93 def test_command_line(self): 94 sender = self.get_sender() 95 self.assertEqual(['mail', '-s', sender.subject(), '-a', 96 'From: ' + sender.from_address()] + sender.to(), 97 sender._command_line()) 98 99 def test_to(self): 100 sender = self.get_sender() 101 self.assertEqual(['demo@example.com'], sender.to()) 102 103 def test_from(self): 104 sender = self.get_sender() 105 self.assertEqual('Sample <foo@example.com>', sender.from_address()) 106 107 def test_from_default(self): 108 sender = self.get_sender(unconfigured_config) 109 self.assertEqual('Robert <foo@example.com>', sender.from_address()) 110 111 def test_should_send(self): 112 sender = self.get_sender() 113 self.assertEqual(True, sender.should_send()) 114 115 def test_should_not_send(self): 116 sender = self.get_sender(unconfigured_config) 117 self.assertEqual(False, sender.should_send()) 118 119 def test_should_not_send_sender_configured(self): 120 sender = self.get_sender(sender_configured_config) 121 self.assertEqual(False, sender.should_send()) 122 123 def test_should_not_send_to_configured(self): 124 sender = self.get_sender(to_configured_config) 125 self.assertEqual(True, sender.should_send()) 126 127 def test_send_to_multiple(self): 128 sender = self.get_sender(multiple_to_configured_config) 129 self.assertEqual([u'Sample <foo@example.com>', u'Other <baz@bar.com>'], 130 sender.to()) 131 self.assertEqual([u'Sample <foo@example.com>', u'Other <baz@bar.com>'], 132 sender._command_line()[-2:]) 133 134 def test_url_set(self): 135 sender = self.get_sender(with_url_config) 136 self.assertEqual(sender.url(), 'http://some.fake/url/') 137 138 def test_public_url_set(self): 139 config = (b"[DEFAULT]\n" 140 b"public_branch=http://the.publication/location/\n") 141 sender = self.get_sender(config) 142 self.assertEqual(sender.url(), 'http://the.publication/location/') 143 144 def test_url_precedence(self): 145 config = (b"[DEFAULT]\n" 146 b"post_commit_url=http://some.fake/url/\n" 147 b"public_branch=http://the.publication/location/\n") 148 sender = self.get_sender(config) 149 self.assertEqual(sender.url(), 'http://some.fake/url/') 150 151 def test_url_unset(self): 152 sender = self.get_sender() 153 self.assertEqual(sender.url(), sender.branch.base) 154 155 def test_subject(self): 156 sender = self.get_sender() 157 self.assertEqual("Rev 1: foo bar baz in %s" % 158 sender.branch.base, 159 sender.subject()) 160 161 def test_custom_subject(self): 162 sender = self.get_sender(customized_mail_config) 163 self.assertEqual("[commit] %s" % 164 sender.revision.get_summary(), 165 sender.subject()) 166 167 def test_diff_filename(self): 168 sender = self.get_sender() 169 self.assertEqual('patch-1.diff', sender.diff_filename()) 170 171 def test_headers(self): 172 sender = self.get_sender() 173 self.assertEqual({'X-Cheese': 'to the rescue!'}, 174 sender.extra_headers()) 175 176 def get_sender(self, text=sample_config): 177 my_config = config.MemoryStack(text) 178 self.branch = BzrDir.create_branch_convenience('.') 179 tree = self.branch.controldir.open_workingtree() 180 tree.commit('foo bar baz\nfuzzy\nwuzzy', rev_id=b'A', 181 allow_pointless=True, 182 timestamp=1, 183 timezone=0, 184 committer="Sample <john@example.com>", 185 ) 186 sender = EmailSender(self.branch, b'A', my_config) 187 # This is usually only done after the EmailSender has locked the branch 188 # and repository during send(), however, for testing, we need to do it 189 # earlier, since send() is not called. 190 sender._setup_revision_and_revno() 191 return sender 192 193 194class TestEmailerWithLocal(tests.TestCaseWithTransport): 195 """Test that Emailer will use a local branch if supplied.""" 196 197 def test_local_has_revision(self): 198 master_tree = self.make_branch_and_tree('master') 199 self.build_tree(['master/a']) 200 master_tree.add('a') 201 master_tree.commit('a') 202 203 child_tree = master_tree.controldir.sprout('child').open_workingtree() 204 child_tree.branch.bind(master_tree.branch) 205 206 self.build_tree(['child/b']) 207 child_tree.add(['b']) 208 revision_id = child_tree.commit('b') 209 210 sender = EmailSender(master_tree.branch, revision_id, 211 master_tree.branch.get_config(), 212 local_branch=child_tree.branch) 213 214 # Make sure we are using the 'local_branch' repository, and not the 215 # remote one. 216 self.assertIs(child_tree.branch.repository, sender.repository) 217 218 def test_local_missing_revision(self): 219 master_tree = self.make_branch_and_tree('master') 220 self.build_tree(['master/a']) 221 master_tree.add('a') 222 master_tree.commit('a') 223 224 child_tree = master_tree.controldir.sprout('child').open_workingtree() 225 child_tree.branch.bind(master_tree.branch) 226 227 self.build_tree(['master/c']) 228 master_tree.add(['c']) 229 revision_id = master_tree.commit('c') 230 231 self.assertFalse( 232 child_tree.branch.repository.has_revision(revision_id)) 233 sender = EmailSender(master_tree.branch, revision_id, 234 master_tree.branch.get_config(), 235 local_branch=child_tree.branch) 236 # We should be using the master repository here, because the child 237 # repository doesn't contain the revision. 238 self.assertIs(master_tree.branch.repository, sender.repository) 239