diff --git a/announcer/tests/__init__.py b/announcer/tests/__init__.py
index a6daa6f..7b0010a 100644
--- a/announcer/tests/__init__.py
+++ b/announcer/tests/__init__.py
@@ -8,9 +8,22 @@
# you should have received as part of this distribution.
#
+import sys
import unittest
-from announcer.tests import api, filters, formatters, model, pref, subscribers
+try:
+ import twill
+ INCLUDE_FUNCTIONAL_TESTS = True
+ from trac.tests.functional import FunctionalTestEnvironment
+ has_min_trac_version = hasattr(FunctionalTestEnvironment, 'post_create')
+except ImportError:
+ twill = False
+ has_min_trac_version = True # unknown, but avoids diagnostic message
+ INCLUDE_FUNCTIONAL_TESTS = False
+
+from announcer.tests import (
+ api, filters, formatters, model, pref, subscribers
+)
from announcer.opt.tests import test_suite as opt_test_suite
@@ -19,6 +32,9 @@ def test_suite():
suite.addTest(api.suite())
suite.addTest(filters.suite())
suite.addTest(formatters.suite())
+ if INCLUDE_FUNCTIONAL_TESTS:
+ from announcer.tests import functional
+ suite.addTest(functional.suite())
suite.addTest(model.suite())
suite.addTest(pref.suite())
suite.addTest(subscribers.suite())
@@ -29,6 +45,16 @@ def test_suite():
# Start test suite directly from command line like so:
-# $> PYTHONPATH=$PWD python announcer/tests/__init__.py
+# $> PYTHONPATH=. python announcer/tests/__init__.py [--skip-functional-tests]
if __name__ == '__main__':
+ if '--skip-functional-tests' in sys.argv:
+ sys.argv.remove('--skip-functional-tests')
+ INCLUDE_FUNCTIONAL_TESTS = False
+ if not INCLUDE_FUNCTIONAL_TESTS:
+ diagnostic = "SKIP: functional tests"
+ if not twill:
+ diagnostic += " (no twill installed)"
+ if not has_min_trac_version:
+ diagnostic += " (requires Trac 0.11.5dev-r8131 or later)"
+ print diagnostic
unittest.main(defaultTest="test_suite")
diff --git a/announcer/tests/functional.py b/announcer/tests/functional.py
new file mode 100644
index 0000000..2635560
--- /dev/null
+++ b/announcer/tests/functional.py
@@ -0,0 +1,80 @@
+# -*- encoding: utf-8 -*-
+
+from trac.tests.functional import *
+
+class TestPreferencePanelsExist(FunctionalTwillTestCaseSetup):
+ def runTest(self):
+ self._tester.go_to_prefs('announcer')
+ tc.find('
\s*'
+ 'Announcements\s*')
+ self._tester.go_to_prefs('subscriptions')
+ tc.find('\s*'
+ 'Subscriptions\s*')
+
+class RegressionTestTicket10675(FunctionalTwillTestCaseSetup):
+ def runTest(self):
+ """Preferences boxes should not be shown for an anonymous user unless
+ an email address has been entered by an anonymous user."""
+ # Boxes should be present when logged in as admin
+ self._tester.go_to_prefs('announcer')
+ tc.find('General Wiki Announcements')
+ tc.find('Ticket Component Subscriptions')
+ tc.find('Watch Users')
+ # Boxes should not be present for anonymous with no email
+ self._tester.logout()
+ self._tester.go_to_prefs('announcer')
+ tc.notfind('General Wiki Announcements')
+ tc.notfind('Ticket Component Subscriptions')
+ tc.notfind('Watch Users')
+ tc.find('Set your email address to '
+ 'enable announcement preferences.')
+ # Boxes should be present for anonymous with an email
+ self._tester.set_email('someone@example.net')
+ self._tester.go_to_prefs('announcer')
+ tc.find('General Wiki Announcements')
+ tc.find('Ticket Component Subscriptions')
+ tc.find('Watch Users')
+ # Revert state of environment
+ self._tester.set_email('')
+ self._tester.login('admin')
+
+
+def set_email(self, email):
+ self.go_to_prefs()
+ tc.formvalue('userprefs', 'email', email)
+ tc.submit()
+ tc.find('Your preferences have been saved.')
+
+def go_to_prefs(self, panel=None):
+ url = self.url + '/prefs' + ('/' + panel if panel else '')
+ tc.go(url)
+ tc.url(url)
+
+class AnnouncerFunctionalTestEnvironment(FunctionalTestEnvironment):
+
+ def get_enabled_components(self):
+ return ['announcer.*']
+
+ def post_create(self, env):
+ self._tracadmin('upgrade')
+ self.restart()
+
+class AnnouncerFunctionalTestSuite(FunctionalTestSuite):
+ env_class = AnnouncerFunctionalTestEnvironment
+
+def functionalSuite():
+ suite = AnnouncerFunctionalTestSuite()
+ # TODO: Add methods by inheriting from FunctionalTester
+ FunctionalTester.go_to_prefs = go_to_prefs
+ FunctionalTester.set_email = set_email
+ return suite
+
+def suite():
+ suite = functionalSuite()
+ suite.addTest(TestPreferencePanelsExist())
+ suite.addTest(RegressionTestTicket10675())
+ return suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')