diff --git a/modules/bibclassify/lib/bibclassify_unit_tests.py b/modules/bibclassify/lib/bibclassify_unit_tests.py
index 65d3a77c6..48167e24f 100644
--- a/modules/bibclassify/lib/bibclassify_unit_tests.py
+++ b/modules/bibclassify/lib/bibclassify_unit_tests.py
@@ -1,306 +1,307 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
-## Copyright (C) 2010, 2011 CERN.
+## Copyright (C) 2010, 2011, 2013 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 """
 Test suite for BibClassify module - this unit-test is actually abusing
 an idea of unit-testing. Some of the test require a lot of time (several
 seconds) to run: they download files, process fulltexts, rebuild cache etc
 [rca]
 
 This module is STANDALONE SAFE
 """
 
 import sys
 
 import unittest
 import tempfile
 import cStringIO
 import random
 import copy
 import os
 import glob
 import time
 import stat
 import shutil
 
 import bibclassify_config as bconfig
-from testutils import make_test_suite, run_test_suite
+from testutils import make_test_suite, run_test_suite, nottest
 import config
 import bibclassify_engine
 import bibclassify_cli
 import bibclassify_ontology_reader
 
 log = bconfig.get_logger("bibclassify.tests")
 
 # do this only if not in STANDALONE mode
 bibclassify_daemon = dbquery = None
 if not bconfig.STANDALONE:
     import dbquery
     import bibclassify_daemon
     import bibdocfile
 
 
 class BibClassifyTestCase(unittest.TestCase):
     """ Abusive test suite - the one that takes sooooo long """
 
     def setUp(self):
         """Initialize stuff"""
         #self.tmpdir = invenio.config.CFG_TMPDIR
         config.CFG_TMPDIR = tempfile.gettempdir()
 
         self.oldstdout = sys.stdout
         self.oldstderr = sys.stderr
         self.stdout = None
         self.stderr = None
 
         self.taxonomy_name = "test"
 
         self.log_level = bconfig.logging_level
         bconfig.set_global_level(bconfig.logging.CRITICAL)
 
     def tearDown(self):
         if self.stdout:
             self.unredirect()
         bconfig.set_global_level(self.log_level)
 
 
     def redirect(self):
         # just for debugging in Eclipse (to see messages printed)
         if 'stdout' in sys.argv:
             self.stdout = sys.stdout
             self.stderr = sys.stderr
         else:
             self.stdout = cStringIO.StringIO()
             self.stderr = cStringIO.StringIO()
 
         sys.stdout = self.stdout
         sys.stderr = self.stderr
 
     def unredirect(self):
         sin, serr = '', ''
         if self.stdout:
             self.stdout.flush()
             self.stdout.seek(0)
             sin = self.stdout.read()
             self.stderr.flush()
             self.stderr.seek(0)
             serr = self.stderr.read()
 
             self.stdout.close()
             self.stderr.close()
         self.stdout = None
         self.stderr = None
         sys.stdout = self.oldstdout
         sys.stderr = self.oldstderr
 
         return sin, serr
 
 
+    @nottest
     def get_test_file(self, recid, type='Main', format='pdf'):
 
         br = bibdocfile.BibRecDocs(recid)
         bibdocs = br.list_bibdocs(type)
         # we grab the first
         for b in bibdocs:
             x = b.get_file(format)
             if x:
                 return x.get_full_path(), x.get_url()
 
 
 
 class BibClassifyTest(BibClassifyTestCase):
 
 
     def test_rebuild_cache(self):
         """bibclassify - test rebuilding cache (takes long time)"""
 
         info = bibclassify_ontology_reader._get_ontology(self.taxonomy_name)
 
         if info[0]:
             cache = bibclassify_ontology_reader._get_cache_path(info[0])
 
             if os.path.exists(cache):
                 ctime = os.stat(cache)[stat.ST_CTIME]
             else:
                 ctime = -1
 
             rex = bibclassify_ontology_reader.get_regular_expressions(self.taxonomy_name, rebuild=True)
 
             self.assertTrue(os.path.exists(cache))
             ntime = os.stat(cache)[stat.ST_CTIME]
 
             self.assertTrue((ntime > ctime))
         else:
             raise Exception("Taxonomy wasn't found")
 
 
     def test_cache_accessibility(self):
         """bibclassify - test cache accessibility/writability"""
 
         # we will do tests with a copy of test taxonomy, in case anything goes wrong...
         orig_name, orig_taxonomy_path, orig_taxonomy_url = bibclassify_ontology_reader._get_ontology(self.taxonomy_name)
 
         taxonomy_path = orig_taxonomy_path.replace('.rdf', '.copy.rdf')
         taxonomy_name = self.taxonomy_name + '.copy'
 
         shutil.copy(orig_taxonomy_path, taxonomy_path)
         assert(os.path.exists(taxonomy_path))
 
         name, taxonomy_path, taxonomy_url = bibclassify_ontology_reader._get_ontology(taxonomy_name)
 
         cache = bibclassify_ontology_reader._get_cache_path(os.path.basename(taxonomy_path))
 
 
         if not name:
             raise Exception("Taxonomy wasn't found")
 
         if os.path.exists(cache):
             os.remove(cache)
 
         bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=True, no_cache=False)
         assert(os.path.exists(cache))
 
         log.error('Testing corrupted states, please ignore errors...')
 
         # set cache unreadable
         os.chmod(cache, 000)
         try: bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=False, no_cache=False)
         except: pass
         else: raise Exception('cache chmod to 000 but no exception raised')
 
         # set cache unreadable and test writing
         os.chmod(cache, 000)
         try: bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=True, no_cache=False)
         except: pass
         else: raise Exception('cache chmod to 000 but no exception raised')
 
         # set cache unreadable but don't care for it
         os.chmod(cache, 000)
         bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=False, no_cache=True)
         bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=True, no_cache=True)
 
         # set cache readable and test writing
         os.chmod(cache, 600)
         try: bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=True, no_cache=False)
         except: pass
         else: raise Exception('cache chmod to 600 but no exception raised')
 
         # set cache writable only
         os.chmod(cache, 200)
         bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=True, no_cache=False)
         bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=False, no_cache=False)
 
 
         # set cache readable/writable but corrupted (must rebuild itself)
         os.chmod(cache, 600)
         os.remove(cache)
         open(cache, 'w').close()
         bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=False, no_cache=False)
 
 
         # set cache readable/writable but corrupted (must rebuild itself)
         open(cache, 'w').close()
         try:
             try:
                 os.rename(taxonomy_path, taxonomy_path + 'x')
                 open(taxonomy_path, 'w').close()
                 bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=False, no_cache=False)
             except:
                 pass
         finally:
             os.rename(taxonomy_path+'x', taxonomy_path)
 
         # make cache ok, but corrupt source
         bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=True, no_cache=False)
 
         try:
             try:
                 os.rename(taxonomy_path, taxonomy_path + 'x')
                 open(taxonomy_path, 'w').close()
                 time.sleep(.1)
                 os.utime(cache, (time.time() + 100, time.time() + 100))  #touch the taxonomy to be older
                 bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=False, no_cache=False)
             except:
                 os.rename(taxonomy_path+'x', taxonomy_path)
                 raise Exception('Cache exists and is ok, but was ignored')
         finally:
             os.rename(taxonomy_path+'x', taxonomy_path)
 
         # make cache ok (but old), and corrupt source
         bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=True, no_cache=False)
         try:
             try:
                 os.rename(taxonomy_path, taxonomy_path + 'x')
                 open(taxonomy_path, 'w').close()
                 bibclassify_ontology_reader.get_regular_expressions(taxonomy_name, rebuild=False, no_cache=False)
             except:
                 pass
         finally:
             os.rename(taxonomy_path+'x', taxonomy_path)
 
         log.error('...testing of corrupted states finished.')
 
         name, taxonomy_path, taxonomy_url = bibclassify_ontology_reader._get_ontology(taxonomy_name)
         cache = bibclassify_ontology_reader._get_cache_path(name)
         os.remove(taxonomy_path)
         os.remove(cache)
 
     def xtest_ingest_taxonomy_by_url(self):
         pass
 
     def xtest_ingest_taxonomy_by_name(self):
         pass
 
     def xtest_ingest_taxonomy_by_path(self):
         pass
 
     def xtest_ingest_taxonomy_db_name(self):
         pass
 
     def xtest_ouput_modes(self):
         pass
 
     def xtest_get_single_keywords(self):
         """test the function returns {<keyword>: [ [spans...] ] }"""
 
     def xtest_get_composite_keywords(self):
         """test the function returns {<keyword>: [ [spans...], [correct component counts] ] }"""
 
 
 
 
 
 def suite(cls=BibClassifyTest):
     tests = []
     for x in sys.argv[1:]:
         if x[0:4] == 'test':
             tests.append(x)
     if len(tests) < 1:
         raise Exception('You must specify tests to run')
 
     return unittest.TestSuite(map(cls, tests))
 
 if 'custom' in sys.argv:
     TEST_SUITE = suite(BibClassifyTest)
 else:
     TEST_SUITE = make_test_suite(BibClassifyTest)
 
 
 if __name__ == '__main__':
     run_test_suite(TEST_SUITE)
diff --git a/modules/miscutil/lib/testutils.py b/modules/miscutil/lib/testutils.py
index 6198519f1..b14d75410 100644
--- a/modules/miscutil/lib/testutils.py
+++ b/modules/miscutil/lib/testutils.py
@@ -1,812 +1,830 @@
 ## This file is part of Invenio.
-## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 CERN.
+## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 # pylint: disable=E1102
 
 """
 Helper functions for building and running test suites.
 """
 
 __revision__ = "$Id$"
 
 CFG_TESTUTILS_VERBOSE = 1
 
 import os
 import sys
 import time
 import unittest
 import cgi
 
 from warnings import warn
 from urlparse import urlsplit, urlunsplit
 from urllib import urlencode
 from itertools import chain, repeat
 
 try:
     from selenium import webdriver
     from selenium.webdriver.support.ui import WebDriverWait
 except ImportError:
     # web tests will not be available, but unit and regression tests will:
     pass
 
 from invenio.config import CFG_SITE_URL, \
      CFG_SITE_SECURE_URL, CFG_LOGDIR, CFG_SITE_NAME_INTL, CFG_PYLIBDIR
 from invenio.w3c_validator import w3c_validate, w3c_errors_to_str, \
      CFG_TESTS_REQUIRE_HTML_VALIDATION
 from invenio.pluginutils import PluginContainer
 
+try:
+    from nose.tools import nottest
+except ImportError:
+    def nottest(f):
+        """Helper decorator to mark a function as not to be tested by nose."""
+        f.__test__ = False
+        return f
+
+@nottest
 def warn_user_about_tests(test_suite_type='regression'):
     """
     Display a standard warning about running tests that might modify
     user data, and wait for user confirmation, unless --yes-i-know
     was specified in the comman line.
     """
 
     # Provide a command line option to avoid having to type the
     # confirmation every time during development.
     if '--yes-i-know' in sys.argv:
         return
 
     if test_suite_type == 'web':
         sys.stderr.write("""\
 **********************************************************************
 **                                                                  **
 **     A B O U T   T H E   W E B   T E S T   S U I T E              **
 **                                                                  **
 ** The web test suite will be launched in Firefox.  You must have   **
 ** the Selenium IDE extension installed to be able to run the web   **
 ** test suite.  If you do, please check out the results of the web  **
 ** test suite in the Selenium IDE window.                           **
 **                                                                  **
 **********************************************************************
 
 """)
 
     sys.stderr.write("""\
 **********************************************************************
 **                                                                  **
 **     I M P O R T A N T   W A R N I N G                            **
 **                                                                  **
 ** The %s test suite needs to be run on a clean demo site   **
 ** that you can obtain by doing:                                    **
 **                                                                  **
 **    $ inveniocfg --drop-demo-site \                               **
 **                 --create-demo-site \                             **
 **                 --load-demo-records                              **
 **                                                                  **
 ** Note that DOING THE ABOVE WILL ERASE YOUR ENTIRE DATABASE.       **
 **                                                                  **
 ** In addition, due to the write nature of some of the tests,       **
 ** the demo DATABASE will be ALTERED WITH JUNK DATA, so that        **
 ** it is recommended to rebuild the demo site anew afterwards.      **
 **                                                                  **
 **********************************************************************
 
 Please confirm by typing 'Yes, I know!': """ % test_suite_type)
 
     answer = raw_input('')
     if answer != 'Yes, I know!':
         sys.stderr.write("Aborted.\n")
         raise SystemExit(0)
 
     return
 
+@nottest
 def make_test_suite(*test_cases):
     """ Build up a test suite given separate test cases"""
     return unittest.TestSuite([unittest.makeSuite(case, 'test')
                                for case in test_cases])
 
+@nottest
 def run_test_suite(testsuite, warn_user=False):
     """
     Convenience function to embed in test suites.  Run given testsuite
     and eventually ask for confirmation of warn_user is True.
     """
     if warn_user:
         warn_user_about_tests()
     res = unittest.TextTestRunner(verbosity=2).run(testsuite)
     return res.wasSuccessful()
 
 def make_url(path, **kargs):
     """ Helper to generate an absolute invenio URL with query
     arguments"""
 
     url = CFG_SITE_URL + path
 
     if kargs:
         url += '?' + urlencode(kargs, doseq=True)
 
     return url
 
 def make_surl(path, **kargs):
     """ Helper to generate an absolute invenio Secure URL with query
     arguments"""
 
     url = CFG_SITE_SECURE_URL + path
 
     if kargs:
         url += '?' + urlencode(kargs, doseq=True)
 
     return url
 
 class InvenioTestUtilsBrowserException(Exception):
     """Helper exception for the regression test suite browser."""
     pass
 
+@nottest
 def test_web_page_existence(url):
     """
     Test whether URL exists and is well accessible.
     Return True or raise exception in case of problems.
     """
     import mechanize
     browser = mechanize.Browser()
     try:
         browser.open(url)
     except:
         raise
     return True
 
 def get_authenticated_mechanize_browser(username="guest", password=""):
     """
     Return an instance of a mechanize browser already authenticated
     to Invenio
     """
     try:
         import mechanize
     except ImportError:
         raise InvenioTestUtilsBrowserException('ERROR: Cannot import mechanize.')
     browser = mechanize.Browser()
     browser.set_handle_robots(False) # ignore robots.txt, since we test gently
     if username == "guest":
         return browser
     browser.open(CFG_SITE_SECURE_URL + "/youraccount/login")
     browser.select_form(nr=0)
     browser['p_un'] = username
     browser['p_pw'] = password
     browser.submit()
     username_account_page_body = browser.response().read()
     try:
         username_account_page_body.index("You are logged in as %s." % username)
     except ValueError:
         raise InvenioTestUtilsBrowserException('ERROR: Cannot login as %s.' % username)
     return browser
 
+@nottest
 def test_web_page_content(url,
                           username="guest",
                           password="",
                           expected_text="</html>",
                           unexpected_text="",
                           expected_link_target=None,
                           expected_link_label=None,
                           require_validate_p=CFG_TESTS_REQUIRE_HTML_VALIDATION):
     """Test whether web page URL as seen by user USERNAME contains
        text EXPECTED_TEXT and, eventually, contains a link to
        EXPECTED_LINK_TARGET (if set) labelled EXPECTED_LINK_LABEL (if
        set).  The EXPECTED_TEXT is checked via substring matching, the
        EXPECTED_LINK_TARGET and EXPECTED_LINK_LABEL via exact string
        matching.
 
        EXPECTED_TEXT, EXPECTED_LINK_LABEL and EXPECTED_LINK_TARGET can
        either be strings or list of strings (in order to check multiple
        values inside same page).
 
        Before doing the tests, login as USERNAME with password
        PASSWORD.  E.g. interesting values for USERNAME are "guest" or
        "admin".
 
        Return empty list in case of no problems, otherwise list of error
        messages that may have been encountered during processing of
        page.
     """
     try:
         import mechanize
     except ImportError:
         raise InvenioTestUtilsBrowserException('ERROR: Cannot import mechanize.')
     if '--w3c-validate' in sys.argv:
         require_validate_p = True
         sys.stderr.write('Required validation\n')
 
     error_messages = []
     try:
         browser = get_authenticated_mechanize_browser(username, password)
         browser.open(url)
         url_body = browser.response().read()
 
         # now test for EXPECTED_TEXT:
         # first normalize expected_text
         if isinstance(expected_text, str):
             expected_texts = [expected_text]
         else:
             expected_texts = expected_text
         # then test
         for cur_expected_text in expected_texts:
             try:
                 url_body.index(cur_expected_text)
             except ValueError:
                 raise InvenioTestUtilsBrowserException, \
                       'ERROR: Page %s (login %s) does not contain %s, but contains %s' % \
                       (url, username, cur_expected_text, url_body)
 
         # now test for UNEXPECTED_TEXT:
         # first normalize unexpected_text
         if isinstance(unexpected_text, str):
             if unexpected_text:
                 unexpected_texts = [unexpected_text]
             else:
                 unexpected_texts = []
         else:
             unexpected_texts = unexpected_text
         # then test
         for cur_unexpected_text in unexpected_texts:
             try:
                 url_body.index(cur_unexpected_text)
                 raise InvenioTestUtilsBrowserException, \
                       'ERROR: Page %s (login %s) contains %s.' % \
                       (url, username, cur_unexpected_text)
             except ValueError:
                 pass
 
         # now test for EXPECTED_LINK_TARGET and EXPECTED_LINK_LABEL:
         if expected_link_target or expected_link_label:
             # first normalize expected_link_target and expected_link_label
             if isinstance(expected_link_target, str) or \
                    expected_link_target is None:
                 expected_link_targets = [expected_link_target]
             else:
                 expected_link_targets = expected_link_target
             if isinstance(expected_link_label, str) or \
                    expected_link_label is None:
                 expected_link_labels = [expected_link_label]
             else:
                 expected_link_labels = expected_link_label
             max_links = max(len(expected_link_targets), len(expected_link_labels))
             expected_link_labels = chain(expected_link_labels, repeat(None))
             expected_link_targets = chain(expected_link_targets, repeat(None))
             # then test
             for dummy in range(0, max_links):
                 cur_expected_link_target = expected_link_targets.next()
                 cur_expected_link_label = expected_link_labels.next()
                 try:
                     browser.find_link(url=cur_expected_link_target,
                                       text=cur_expected_link_label)
                 except mechanize.LinkNotFoundError:
                     raise InvenioTestUtilsBrowserException, \
                           'ERROR: Page %s (login %s) does not contain link to %s entitled %s.' % \
                           (url, username, cur_expected_link_target, cur_expected_link_label)
 
         # now test for validation if required
         if require_validate_p:
             valid_p, errors, warnings = w3c_validate(url_body)
             if not valid_p:
                 error_text = 'ERROR: Page %s (login %s) does not validate:\n %s' % \
                                   (url, username, w3c_errors_to_str(errors, warnings))
                 open('%s/w3c-markup-validator.log' % CFG_LOGDIR, 'a').write(error_text)
                 raise InvenioTestUtilsBrowserException, error_text
 
 
     except mechanize.HTTPError, msg:
         error_messages.append('ERROR: Page %s (login %s) not accessible. %s' % \
                               (url, username, msg))
     except InvenioTestUtilsBrowserException, msg:
         error_messages.append('ERROR: Page %s (login %s) led to an error: %s.' % \
                               (url, username, msg))
 
     try:
         # logout after tests:
         browser.open(CFG_SITE_SECURE_URL + "/youraccount/logout")
         browser.response().read()
         browser.close()
     except UnboundLocalError:
         pass
 
     if CFG_TESTUTILS_VERBOSE >= 9:
         print "%s test_web_page_content(), tested page `%s', login `%s', expected text `%s', errors `%s'." % \
               (time.strftime("%Y-%m-%d %H:%M:%S -->", time.localtime()),
                url, username, expected_text,
                ",".join(error_messages))
 
     return error_messages
 
 def merge_error_messages(error_messages):
     """If the ERROR_MESSAGES list is non-empty, merge them and return nicely
        formatted string suitable for printing.  Otherwise return empty
        string.
     """
     out = ""
     if error_messages:
         out = "\n*** " + "\n*** ".join(error_messages)
     return out
 
+@nottest
 def build_and_run_unit_test_suite():
     """
     Detect all Invenio modules with names ending by '*_unit_tests.py', build
     a complete test suite of them, and run it.
     Called by 'inveniocfg --run-unit-tests'.
     """
 
     test_modules_map = PluginContainer(
         os.path.join(CFG_PYLIBDIR, 'invenio', '*_unit_tests.py'),
         lambda plugin_name, plugin_code: getattr(plugin_code, "TEST_SUITE"))
     test_modules = [test_modules_map[name] for name in test_modules_map]
 
     broken_tests = test_modules_map.get_broken_plugins()
 
     broken_unit_tests = ['%s (reason: %s)' % (name, broken_tests[name][1]) for name in broken_tests]
     if broken_unit_tests:
         warn("Broken unit tests suites found: %s" % ', '.join(broken_unit_tests))
 
     complete_suite = unittest.TestSuite(test_modules)
     res = unittest.TextTestRunner(verbosity=2).run(complete_suite)
     return res.wasSuccessful()
 
+@nottest
 def build_and_run_regression_test_suite():
     """
     Detect all Invenio modules with names ending by
     '*_regression_tests.py', build a complete test suite of them, and
     run it.  Called by 'inveniocfg --run-regression-tests'.
     """
 
     test_modules_map = PluginContainer(
         os.path.join(CFG_PYLIBDIR, 'invenio', '*_regression_tests.py'),
         lambda plugin_name, plugin_code: getattr(plugin_code, "TEST_SUITE"))
     test_modules = test_modules_map.values()
 
     broken_tests = test_modules_map.get_broken_plugins()
 
     broken_regression_tests = ['%s (reason: %s)' % (name, broken_tests[name][1]) for name in broken_tests]
     if broken_regression_tests:
         warn("Broken regression tests suites found: %s" % ', '.join(broken_regression_tests))
 
     warn_user_about_tests()
 
     complete_suite = unittest.TestSuite(test_modules)
     res = unittest.TextTestRunner(verbosity=2).run(complete_suite)
     return res.wasSuccessful()
 
+@nottest
 def build_and_run_web_test_suite():
     """
     Detect all Invenio modules with names ending by
     '*_web_tests.py', build a complete test suite of them, and
     run it.  Called by 'inveniocfg --run-web-tests'.
     """
 
     test_modules_map = PluginContainer(
         os.path.join(CFG_PYLIBDIR, 'invenio', '*_web_tests.py'),
         lambda plugin_name, plugin_code: getattr(plugin_code, "TEST_SUITE"))
     test_modules = test_modules_map.values()
 
     broken_tests = test_modules_map.get_broken_plugins()
 
     broken_web_tests = ['%s (reason: %s)' % (name, broken_tests[name][1]) for name in broken_tests]
     if broken_web_tests:
         warn("Broken web tests suites found: %s" % ', '.join(broken_web_tests))
 
     warn_user_about_tests()
 
     complete_suite = unittest.TestSuite(test_modules)
     res = unittest.TextTestRunner(verbosity=2).run(complete_suite)
     return res.wasSuccessful()
 
 
 class InvenioWebTestCase(unittest.TestCase):
     """ Helper library of useful web test functions
     for web tests creation.
     """
 
     def setUp(self):
         """Initialization before tests."""
 
         ## Let's default to English locale
         profile = webdriver.FirefoxProfile()
         profile.set_preference('intl.accept_languages', 'en-us, en')
         profile.update_preferences()
 
         # the instance of Firefox WebDriver is created
         self.browser = webdriver.Firefox(profile)
 
         # list of errors
         self.errors = []
 
     def tearDown(self):
         """Cleanup actions after tests."""
 
         self.browser.quit()
         self.assertEqual([], self.errors)
 
     def find_element_by_name_with_timeout(self, element_name, timeout=30):
         """ Find an element by name. This waits up to 'timeout' seconds
         before throwing an InvenioWebTestCaseException or if it finds the
         element will return it in 0 - timeout seconds.
         @param element_name: name of the element to find
         @type element_name: string
         @param timeout: time in seconds before throwing an exception
         if the element is not found
         @type timeout: int
         """
 
         try:
             WebDriverWait(self.browser, timeout).until(lambda driver: driver.find_element_by_name(element_name))
         except:
             raise InvenioWebTestCaseException(element=element_name)
 
     def find_element_by_link_text_with_timeout(self, element_link_text, timeout=30):
         """ Find an element by link text. This waits up to 'timeout' seconds
         before throwing an InvenioWebTestCaseException or if it finds the element
         will return it in 0 - timeout seconds.
         @param element_link_text: link text of the element to find
         @type element_link_text: string
         @param timeout: time in seconds before throwing an exception
         if the element is not found
         @type timeout: int
         """
 
         try:
             WebDriverWait(self.browser, timeout).until(lambda driver: driver.find_element_by_link_text(element_link_text))
         except:
             raise InvenioWebTestCaseException(element=element_link_text)
 
     def find_element_by_partial_link_text_with_timeout(self, element_partial_link_text, timeout=30):
         """ Find an element by partial link text. This waits up to 'timeout' seconds
         before throwing an InvenioWebTestCaseException or if it finds the element
         will return it in 0 - timeout seconds.
         @param element_partial_link_text: partial link text of the element to find
         @type element_partial_link_text: string
         @param timeout: time in seconds before throwing an exception
         if the element is not found
         @type timeout: int
         """
 
         try:
             WebDriverWait(self.browser, timeout).until(lambda driver: driver.find_element_by_partial_link_text(element_partial_link_text))
         except:
             raise InvenioWebTestCaseException(element=element_partial_link_text)
 
     def find_element_by_id_with_timeout(self, element_id, timeout=30, text=""):
         """ Find an element by id. This waits up to 'timeout' seconds
         before throwing an InvenioWebTestCaseException or if it finds the element
         will return it in 0 - timeout seconds.
         If the parameter text is provided, the function waits
         until the element is found and its content is equal to the given text.
         If the element's text is not equal to the given text an exception will be raised
         and the result of this comparison will be stored in the errors list
         #NOTE: Currently this is used to wait for an element's text to be
         refreshed using JavaScript
         @param element_id: id of the element to find
         @type element_id: string
         @param timeout: time in seconds before throwing an exception
         if the element is not found
         @type timeout: int
         @param text: expected text inside the given element.
         @type text: string
         """
 
         try:
             WebDriverWait(self.browser, timeout).until(lambda driver: driver.find_element_by_id(element_id))
         except:
             raise InvenioWebTestCaseException(element=element_id)
 
         if text:
             q = self.browser.find_element_by_id(element_id)
             try:
                 # if the element's text is not equal to the given text, an exception will be raised
                 WebDriverWait(self.browser, timeout).until(lambda driver: driver.find_element_by_id(element_id) and q.text==text)
             except:
                 # let's store the result of the comparison in the errors list
                 try:
                     self.assertEqual(q.text, text)
                 except AssertionError, e:
                     self.errors.append(str(e))
 
     def find_element_by_xpath_with_timeout(self, element_xpath, timeout=30):
         """ Find an element by xpath. This waits up to 'timeout' seconds
         before throwing an InvenioWebTestCaseException or if it finds the element
         will return it in 0 - timeout seconds.
         @param element_xpath: xpath of the element to find
         @type element_xpath: string
         @param timeout: time in seconds before throwing an exception
         if the element is not found
         @type timeout: int
         """
 
         try:
             WebDriverWait(self.browser, timeout).until(lambda driver: driver.find_element_by_xpath(element_xpath))
         except:
             raise InvenioWebTestCaseException(element=element_xpath)
 
     def find_elements_by_class_name_with_timeout(self, element_class_name, timeout=30):
         """ Find an element by class name. This waits up to 'timeout' seconds
         before throwing an InvenioWebTestCaseException or if it finds the element
         will return it in 0 - timeout seconds.
         @param element_class_name: class name of the element to find
         @type element_class_name: string
         @param timeout: time in seconds before throwing an exception
         if the element is not found
         @type timeout: int
         """
 
         try:
             WebDriverWait(self.browser, timeout).until(lambda driver: driver.find_element_by_class_name(element_class_name))
         except:
             raise InvenioWebTestCaseException(element=element_class_name)
 
     def find_page_source_with_timeout(self, timeout=30):
         """ Find the page source. This waits up to 'timeout' seconds
         before throwing an InvenioWebTestCaseException
         or if the page source is loaded will return it
         in 0 - timeout seconds.
         @param timeout: time in seconds before throwing an exception
         if the page source is not found
         @type timeout: int
         """
 
         try:
             WebDriverWait(self.browser, timeout).until(lambda driver: driver.page_source)
         except:
             raise InvenioWebTestCaseException(element="page source")
 
     def login(self, username="guest", password="", force_ln='en'):
         """ Login function
         @param username: the username (nickname or email)
         @type username: string
         @param password: the corresponding password
         @type password: string
         @param force_ln: if the arrival page doesn't use the corresponding
             language, then the browser will redirect to it.
         @type force_ln: string
         """
         if not "You can use your nickname or your email address to login." in self.browser.page_source:
             if "You are no longer recognized by our system" in self.browser.page_source:
                 self.find_element_by_link_text_with_timeout("login here")
                 self.browser.find_element_by_link_text("login here").click()
             else:
                 self.find_element_by_link_text_with_timeout("login")
                 self.browser.find_element_by_link_text("login").click()
 
         self.find_element_by_name_with_timeout("p_un")
         self.browser.find_element_by_name("p_un").clear()
         self.fill_textbox(textbox_name="p_un", text=username)
         self.find_element_by_name_with_timeout("p_pw")
         self.browser.find_element_by_name("p_pw").clear()
         self.fill_textbox(textbox_name="p_pw",  text=password)
         self.find_element_by_name_with_timeout("action")
         self.browser.find_element_by_name("action").click()
         if force_ln and CFG_SITE_NAME_INTL[force_ln] not in self.browser.page_source:
             splitted_url = list(urlsplit(self.browser.current_url))
             query = cgi.parse_qs(splitted_url[3])
             query.update({u'ln': unicode(force_ln)})
             splitted_url[3] = urlencode(query)
             new_url = urlunsplit(splitted_url)
             self.browser.get(new_url)
 
     def logout(self):
         """ Logout function
         """
 
         self.find_element_by_link_text_with_timeout("logout")
         self.browser.find_element_by_link_text("logout").click()
 
+    @nottest
     def element_value_test(self, element_name="", element_id="", \
                            expected_element_value="", unexpected_element_value="", in_form=True):
         """ Function to check if the value in the given
         element is the expected (unexpected) value or not
         @param element_name: name of the corresponding element in the form
         @type element_name: string
         @param element_id: id of the corresponding element in the form
         @type element_id: string
         @param expected_element_value: the expected element value
         @type expected_element_value: string
         @param unexpected_element_value: the unexpected element value
         @type unexpected_element_value: string
         @param in_form: depends on this parameter, the value of the given element
         is got in a different way. If it is True, the given element is a textbox
         or a textarea in a form.
         @type in_form: boolean
         """
 
         if element_name:
             self.find_element_by_name_with_timeout(element_name)
             q = self.browser.find_element_by_name(element_name)
         elif element_id:
             self.find_element_by_id_with_timeout(element_id)
             q = self.browser.find_element_by_id(element_id)
 
         if unexpected_element_value:
             try:
                 if in_form:
                     self.assertNotEqual(q.get_attribute('value'), unexpected_element_value)
                 else:
                     self.assertNotEqual(q.text, unexpected_element_value)
             except AssertionError, e:
                 self.errors.append(str(e))
 
         if expected_element_value:
             try:
                 if in_form:
                     self.assertEqual(q.get_attribute('value'), expected_element_value)
                 else:
                     self.assertEqual(q.text, expected_element_value)
             except AssertionError, e:
                 self.errors.append(str(e))
 
+    @nottest
     def page_source_test(self, expected_text="", unexpected_text=""):
         """ Function to check if the current page contains
         the expected text (unexpected text) or not.
         The expected text (unexpected text) can also be
         a link.
         The expected text (unexpected text) can be a list of strings
         in order to check multiple values inside same page
         @param expected_text: the expected text
         @type expected_text: string or list of strings
         @param unexpected_text: the unexpected text
         @type unexpected_text: string or list of strings
         """
 
         self.find_page_source_with_timeout()
         if unexpected_text:
             if isinstance(unexpected_text, str):
                 unexpected_texts = [unexpected_text]
             else:
                 unexpected_texts = unexpected_text
 
             for unexpected_text in unexpected_texts:
                 try:
                     self.assertEqual(-1, self.browser.page_source.find(unexpected_text))
                 except AssertionError, e:
                     self.errors.append(str(e))
 
         if expected_text:
             if isinstance(expected_text, str):
                 expected_texts = [expected_text]
             else:
                 expected_texts = expected_text
 
             for expected_text in expected_texts:
                 try:
                     self.assertNotEqual(-1, self.browser.page_source.find(expected_text))
                 except AssertionError, e:
                     self.errors.append(str(e))
 
     def choose_selectbox_option_by_label(self, selectbox_name="", selectbox_id="", label=""):
         """ Select the option at the given label in
         the corresponding select box
         @param selectbox_name: the name of the corresponding
         select box in the form
         @type selectbox_name: string
         @param selectbox_id: the id of the corresponding
         select box in the form
         @type selectbox_id: string
         @param label: the option at this label will be selected
         @type label: string
         """
 
         if selectbox_name:
             self.find_element_by_name_with_timeout(selectbox_name)
             selectbox = self.browser.find_element_by_name(selectbox_name)
         elif selectbox_id:
             self.find_element_by_id_with_timeout(selectbox_id)
             selectbox = self.browser.find_element_by_id(selectbox_id)
 
         options = selectbox.find_elements_by_tag_name("option")
         for option in options:
             if option.text == label:
                 option.click()
                 break
 
     def choose_selectbox_option_by_index(self, selectbox_name="", selectbox_id="", index=""):
         """ Select the option at the given index in
         the corresponding select box
         @param selectbox_name: the name of the corresponding
         select box in the form
         @type selectbox_name: string
         @param selectbox_id: the id of the corresponding
         select box in the form
         @type selectbox_id: string
         @param index: the option at this index will be selected
         @type index: int
         """
 
         if selectbox_name:
             self.find_element_by_name_with_timeout(selectbox_name)
             selectbox = self.browser.find_element_by_name(selectbox_name)
         elif selectbox_id:
             self.find_element_by_id_with_timeout(selectbox_id)
             selectbox = self.browser.find_element_by_id(selectbox_id)
 
         options = selectbox.find_elements_by_tag_name("option")
         options[int(index)].click()
 
     def choose_selectbox_option_by_value(self, selectbox_name="", selectbox_id="", value=""):
         """ Select the option at the given value in
         the corresponding select box
         @param selectbox_name: the name of the corresponding
         select box in the form
         @type selectbox_id: string
         @param selectbox_id: the id of the corresponding
         select box in the form
         @type selectbox_id: string
         @param value: the option at this value will be selected
         @type value: string
         """
 
         if selectbox_name:
             self.find_element_by_name_with_timeout(selectbox_name)
             selectbox = self.browser.find_element_by_name(selectbox_name)
         elif selectbox_id:
             self.find_element_by_id_with_timeout(selectbox_id)
             selectbox = self.browser.find_element_by_id(selectbox_id)
 
         options = selectbox.find_elements_by_tag_name("option")
         for option in options:
             if option.get_attribute('value') == value:
                 option.click()
                 break
 
     def fill_textbox(self, textbox_name="", textbox_id="", text=""):
         """ Fill in the input textbox or textarea with the given text
         @param textbox_name: the name of the corresponding textbox
         or text area in the form
         @type textbox_name: string
         @param textbox_id: the id of the corresponding textbox
         or text area in the form
         @type textbox_id: string
         @param text: the information that the user wants to send
         @type text: string
         """
 
         if textbox_name:
             self.find_element_by_name_with_timeout(textbox_name)
             textbox = self.browser.find_element_by_name(textbox_name)
         elif textbox_id:
             self.find_element_by_id_with_timeout(textbox_id)
             textbox = self.browser.find_element_by_id(textbox_id)
 
         textbox.send_keys(text)
 
     def handle_popup_dialog(self):
         """ Access the alert after triggering an action
         that opens a popup. """
 
         try:
             alert = self.browser.switch_to_alert()
             alert.accept()
         except:
             pass
 
 
 class InvenioWebTestCaseException(Exception):
     """This exception is thrown if the element
     we are looking for is not found after a set time period.
     The element is not found because the page needs more
     time to be fully loaded. To avoid this exception,
     we should increment the time period for that element in
     the corresponding function. See also:
     find_element_by_name_with_timeout()
     find_element_by_link_text_with_timeout()
     find_element_by_partial_link_text_with_timeout()
     find_element_by_id_with_timeout()
     find_element_by_xpath_with_timeout()
     find_elements_by_class_name_with_timeout()
     find_page_source_with_timeout()
     """
 
     def __init__(self, element):
         """Initialisation."""
         self.element = element
         self.message = "Time for finding the element '%s' has expired" % self.element
 
     def __str__(self):
         """String representation."""
         return repr(self.message)
diff --git a/modules/refextract/lib/refextract_authextract_unit_tests.py b/modules/refextract/lib/refextract_authextract_unit_tests.py
index c0024244c..2186b2366 100644
--- a/modules/refextract/lib/refextract_authextract_unit_tests.py
+++ b/modules/refextract/lib/refextract_authextract_unit_tests.py
@@ -1,289 +1,294 @@
 # -*- coding: utf-8 -*-
 ##
 ## $Id$
 ##
 ## This file is part of CDS Invenio.
-## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2013 CERN.
 ##
 ## CDS Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## CDS Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 __revision__ = "$Id$"
 
 import unittest
 import sys
 import re
 from invenio.config import CFG_TMPDIR, CFG_ETCDIR
 
 try:
     #try local version first
     import refextract
 except ImportError:
     #then get installed version
     print "Using installed refextract\n"
     import invenio.refextract
 
-from invenio.testutils import make_test_suite, run_test_suite
+from invenio.testutils import make_test_suite, run_test_suite, nottest
 
 
 # pylint: disable-msg=C0301
 
 def setup_files(self):
     self.test_pdfname = CFG_TMPDIR + '/demoextract.pdf'
     self.test_txtname = CFG_TMPDIR + '/demoextract.txt'
     from os.path import exists, getsize
     if (not exists(self.test_pdfname) or getsize(self.test_pdfname) is 0):
         from urllib import urlretrieve
         urlretrieve('http://arxiv.org/pdf/0809.4120', self.test_pdfname)
     self.assert_( exists(self.test_pdfname) and getsize(self.test_pdfname) > 0)
 
 
+@nottest
 def set_test_cli_opts():
     refextract.cli_opts = { 'treat_as_raw_section'       : 0,
                             'output_raw'                 : 0,
                             'verbosity'                  : 1,
                             'xmlfile'
 
 
                             : 0,
                             'dictfile'                   : 0,
                             'authors'                    : 0,
                             'first_author'               : "",
     }
 
 
 
 
 class RefExtractPDFTest(unittest.TestCase):
     """ refextract test pdf to text extraction"""
 
     def setUp(self):
         setup_files(self)
         set_test_cli_opts()
 
 
+    @nottest
     def test_PDF_extraction(self):
         """ refextract test basic pdf extraction ---necessary for some remaining tests"""
         (docbody, extract_error) = refextract.get_plaintext_document_body(self.test_pdfname)
         self.assert_(len(docbody) > 10)
         self.assert_(len([1 for line in docbody if line.find('babar') > -1])>0)
         from codecs import open
         file = open(self.test_txtname, 'w', 'utf8')
         for line in docbody:
             file.write(line)
         file.close
 
 
 class RefExtractExtractSectionTest(unittest.TestCase):
     """ refextract - test finding ref and auth sections """
 
     def setUp(self):
         # pylint: disable-msg=C0103
         """Initialize stuff"""
         setup_files(self)
         set_test_cli_opts
         file = open(self.test_txtname, 'r')
         self.textbody = []
         for line in file.readlines():
             self.textbody.append(line.decode("utf-8"))
         file.close()
 
 
+    @nottest
     def test_reference_finding(self):
         """ find a reference section """
         (references, extract_error, how_start) = refextract.extract_section_from_fulltext(self.textbody,'references')
         self.assertEqual(extract_error, 0)
 #        for line in references:
 #           print "found -> %s\n" % line
         self.assertEqual(len(references), 17)
 
+
+    @nottest
     def test_author_finding(self):
         """ find author section """
 
         (authors, extract_error, how_start) = refextract.extract_section_from_fulltext(self.textbody,'authors')
         for line in authors:
             print "%s" % line.encode("utf8")
         self.assertEqual(len(authors), 530)
 
 
 class RefExtractAuthorParsingTest(unittest.TestCase):
     def setUp(self):
         self.authlines = [
             """B. Aubert,1"""
             ,"""M. Bona,1"""
             ,"""Y. Karyotakis,1"""
             ,"""J. P. Lees,1"""
             ,"""V. Poireau,1"""
             ,"""E. Prencipe,1"""
             ,"""X. Prudent,1"""
             ,"""V. Tisserand,1"""
             ,"""J. Garra Tico,2"""
             ,"""E. Grauges,2"""
             ,"""L. Lopezab
             """
             ,"""A. Palanoab
             """
             ,"""M. Pappagalloab
             """
             ,"""N. L. Blount,56"""
             ,"""J. Brau,56"""
             ,"""R. Frey,56"""
             ,"""O. Igonkina,56"""
             ,"""J. A. Kolb,56"""
             ,"""M. Lu,56"""
             ,"""R. Rahmat,56"""
             ,"""N. B. Sinev,56"""
             ,"""D. Strom,56"""
             ,"""J. Strube,56"""
             ,"""E. Torrence,56"""
             ,"""G. Castelliab
             """
             ,"""N. Gagliardiab
             """
             ,"""M. Margoniab
             """
             ,"""M. Morandina
             """
             ,"""M. Posoccoa
             """
             ,"""M. Rotondoa
             """
             ,"""F. Simonettoab
             """
             ,"""R. Stroiliab
             """
             ,"""C. Vociab
             """
             ,"""E. Ben"""
             ,"""H. Briand,58"""
             ,"""G. Calderini,58"""
             ,"""J. Chauveau,58"""
             ,"""P. David,58"""
             ,"""L. Del Buono,58"""
             ,"""O. Hamon,58"""
             ,"""J. Ocariz,58"""
             ,"""A. Perez,58"""
             ,"""J. Prendki,58"""
             ,"""S. Sitt,58"""
             ,"""L. Gladney,59"""
             ,"""M. Biasiniab
             """]
 
 
-
+    @nottest
     def test_reference_parsing(self):
         """Use a hardcoded set of authors to test the parsing"""
         (processed_authors, count_author, \
          count_aff ) = \
          refextract.create_marc_xml_author_section(self.authlines)
         self.assert_(re.search('<subfield code=\"a\">Biasini, M.\s?</subfield>',processed_authors[44]))
         print processed_authors
 
 
 class RefExtractReferenceParsingTest(unittest.TestCase):
     """ Test the parsing of reference strings """
     def setUp(self):
         self.reflines = ["""[1] <a href="http://cdsweb.cern.ch/">CERN Document Server</a> J. Maldacena, Adv. Theor. Math. Phys. 2 (1998) 231; hep-th/9711200. http://cdsweb.cern.ch/ then http://www.itp.ucsb.edu/online/susyc99/discussion/. ; L. Susskind, J. Math. Phys. 36 (1995) 6377; hep-th/9409089. hello world a<a href="http://uk.yahoo.com/">Yahoo!</a>. Fin.""",
                              """[1] J. Maldacena, Adv. Theor. Math. Phys. 2 (1998) 231; hep-th/9711200. http://cdsweb.cern.ch/""",
                              """[2] S. Gubser, I. Klebanov and A. Polyakov, Phys. Lett. B428 (1998) 105; hep-th/9802109. http://cdsweb.cern.ch/search.py?AGE=hello-world&ln=en""",
                              """[3] E. Witten, Adv. Theor. Math. Phys. 2 (1998) 253; hep-th/9802150.""",
                              """[4] O. Aharony, S. Gubser, J. Maldacena, H. Ooguri and Y. Oz, hep-th/9905111.""",
                              """[5] L. Susskind, J. Math. Phys. 36 (1995) 6377; hep-th/9409089.""",
                              """[6] L. Susskind and E. Witten, hep-th/9805114.""",
                              """[7] W. Fischler and L. Susskind, hep-th/9806039; N. Kaloper and A. Linde, Phys. Rev. D60 (1999) 105509, hep-th/9904120.""",
                              """[8] R. Bousso, JHEP 9906:028 (1999); hep-th/9906022.""",
                              """[9] R. Penrose and W. Rindler, Spinors and Spacetime, volume 2, chapter 9 (Cambridge University Press, Cambridge, 1986).""",
                              """[10] R. Britto-Pacumio, A. Strominger and A. Volovich, JHEP 9911:013 (1999); hep-th/9905211. blah hep-th/9905211 blah hep-ph/9711200""",
                              """[11] V. Balasubramanian and P. Kraus, Commun. Math. Phys. 208 (1999) 413; hep-th/9902121.""",
                              """[12] V. Balasubramanian and P. Kraus, Phys. Rev. Lett. 83 (1999) 3605; hep-th/9903190.""",
                              """[13] P. Kraus, F. Larsen and R. Siebelink, hep-th/9906127.""",
                              """[14] L. Randall and R. Sundrum, Phys. Rev. Lett. 83 (1999) 4690; hep-th/9906064. this is a test RN of a different type: CERN-LHC-Project-Report-2006-003. more text.""",
                              """[15] S. Gubser, hep-th/9912001.""",
                              """[16] H. Verlinde, hep-th/9906182; H. Verlinde, hep-th/9912018; J. de Boer, E. Verlinde and H. Verlinde, hep-th/9912012.""",
                              """[17] E. Witten, remarks at ITP Santa Barbara conference, "New dimensions in field theory and string theory": http://www.itp.ucsb.edu/online/susyc99/discussion/.""",
                              """[18] D. Page and C. Pope, Commun. Math. Phys. 127 (1990) 529.""",
                              """[19] M. Duff, B. Nilsson and C. Pope, Physics Reports 130 (1986), chapter 9.""",
                              """[20] D. Page, Phys. Lett. B79 (1978) 235.""",
                              """[21] M. Cassidy and S. Hawking, Phys. Rev. D57 (1998) 2372, hep-th/9709066; S. Hawking, Phys. Rev. D52 (1995) 5681.""",
                              """[22] K. Skenderis and S. Solodukhin, hep-th/9910023.""",
                              """[23] M. Henningson and K. Skenderis, JHEP 9807:023 (1998), hep-th/9806087.""",
                              """[24] C. Fefferman and C. Graham, "Conformal Invariants", in Elie Cartan et les Mathematiques d'aujourd'hui (Asterisque, 1985) 95.""",
                              """[25] C. Graham and J. Lee, Adv. Math. 87 (1991) 186. <a href="http://cdsweb.cern.ch/">CERN Document Server</a>""",
                              """[26] E. Witten and S.-T. Yau, hep-th/9910245.""",
                              """[27] R. Emparan, JHEP 9906:036 (1999); hep-th/9906040.""",
                              """[28] A. Chamblin, R. Emparan, C. Johnson and R. Myers, Phys. Rev. D59 (1999) 64010, hep-th/9808177; S. Hawking, C. Hunter and D. Page, Phys. Rev. D59 (1999) 44033, hep-th/9809035.""",
                              """[29] S. Sethi and L. Susskind, Phys. Lett. B400 (1997) 265, hep-th/9702101; T. Banks and N. Seiberg, Nucl. Phys. B497 (1997) 41, hep-th/9702187.""",
                              """[30] R. Emparan, C. Johnson and R. Myers, Phys. Rev. D60 (1999) 104001; hep-th/9903238.""",
                              """[31] S. Hawking, C. Hunter and M. Taylor-Robinson, Phys. Rev. D59 (1999) 064005; hep-th/9811056.""",
                              """[32] J. Dowker, Class. Quant. Grav. 16 (1999) 1937; hep-th/9812202.""",
                              """[33] J. Brown and J. York, Phys. Rev. D47 (1993) 1407.""",
                              """[34] D. Freedman, S. Mathur, A. Matsuis and L. Rastelli, Nucl. Phys. B546 (1999) 96; hep-th/9804058. More text, followed by an IBID A 546 (1999) 96""",
                              """[35] D. Freedman, S. Mathur, A. Matsuis and L. Rastelli, Nucl. Phys. B546 (1999) 96; hep-th/9804058. More text, followed by an IBID A""",
                              """[36] whatever http://cdsware.cern.ch/""",
                              """[37] some misc  lkjslkdjlksjflksj [hep-th/9804058] lkjlkjlkjlkj [hep-th/0001567], hep-th/1212321, some more misc, Nucl. Phys. B546 (1999) 96""",
                              """[38] R. Emparan, C. Johnson and R.... Myers, Phys. Rev. D60 (1999) 104001; this is :: .... misc! hep-th/9903238. and some ...,.,.,.,::: more hep-ph/9912000""",
                              """[10] A. Ceresole, G. Dall Agata and R. D Auria, JHEP 11(1999) 009, [hep-th/9907216].""",
                              """[12] D.P. Jatkar and S. Randjbar-Daemi, Phys. Lett. B460, 281 (1999) [hep-th/9904187].""",
                              """[14] G. DallAgata, Phys. Lett. B460, (1999) 79, [hep-th/9904198].""",
                              """[13] S.M. Donaldson, Instantons and Geometric Invariant Theory, Comm. Math. Phys., 93, (1984), 453-460.""",
                              """[16] Becchi C., Blasi A., Bonneau G., Collina R., Delduc F., Commun. Math. Phys., 1988, 120, 121.""",
                              """[26]: N. Nekrasov, A. Schwarz, Instantons on noncommutative R4 and (2, 0) superconformal six-dimensional theory, Comm. Math. Phys., 198, (1998), 689-703.""",
                              """[2] H. J. Bhabha, Rev. Mod. Phys. 17, 200(1945); ibid, 21, 451(1949); S. Weinberg, Phys. Rev. 133, B1318(1964); ibid, 134, 882(1964); D. L. Pursey, Ann. Phys(N. Y)32, 157(1965); W. K. Tung, Phys, Rev. Lett. 16, 763(1966); Phys. Rev. 156, 1385(1967); W. J. Hurley, Phys. Rev. Lett. 29, 1475(1972).""",
                              """[21] E. Schrodinger, Sitzungsber. Preuss. Akad. Wiss. Phys. Math. Kl. 24, 418(1930); ibid, 3, 1(1931); K. Huang, Am. J. Phys. 20, 479(1952); H. Jehle, Phys, Rev. D3, 306(1971); G. A. Perkins, Found. Phys. 6, 237(1976); J. A. Lock, Am. J. Phys. 47, 797(1979); A. O. Barut et al, Phys. Rev. D23, 2454(1981); ibid, D24, 3333(1981); ibid, D31, 1386(1985); Phys. Rev. Lett. 52, 2009(1984).""",
                              """[1] P. A. M. Dirac, Proc. R. Soc. London, Ser. A155, 447(1936); ibid, D24, 3333(1981).""",
                          ]
         (self.title_search_kb, \
          self.title_search_standardised_titles, \
          self.title_search_keys) = \
          refextract.build_titles_knowledge_base(refextract.CFG_REFEXTRACT_KB_JOURNAL_TITLES)
         (self.preprint_reportnum_sre, \
          self.standardised_preprint_reportnum_categs) = \
          refextract.build_reportnum_knowledge_base(refextract.CFG_REFEXTRACT_KB_REPORT_NUMBERS)
 
-
+    @nottest
     def test_reference_parsing(self):
         """Use a hardcoded set of refstrings to test the parsing"""
         (processed_references, count_misc, \
              count_title, count_reportnum, \
              count_url, count_doi, record_titles_count) = \
              refextract.create_marc_xml_reference_section(self.reflines,
                                                 preprint_repnum_search_kb=\
                                                   self.preprint_reportnum_sre,
                                                 preprint_repnum_standardised_categs=\
                                                   self.standardised_preprint_reportnum_categs,
                                                 periodical_title_search_kb=\
                                                   self.title_search_kb,
                                                 standardised_periodical_titles=\
                                                   self.title_search_standardised_titles,
                                                 periodical_title_search_keys=\
                                                   self.title_search_keys)
         self.assertEqual(count_title, 56)
         self.assertEqual(count_reportnum, 45)
 
 
 
 
 
 
 ## FIXME: all the tests are disabled since they are no longer in sync
 ## with the current development of Invenio. We keep this file for reference
 ## in case we want to reimplement them
 TEST_SUITE = make_test_suite(#RefExtractPDFTest,
                              #RefExtractExtractSectionTest,
                              #RefExtractAuthorParsingTest,
                              #RefExtractReferenceParsingTest,
                              )
 
 if __name__ == '__main__':
     run_test_suite(TEST_SUITE)
diff --git a/modules/webaccess/lib/external_authentication_cern_unit_tests.py b/modules/webaccess/lib/external_authentication_cern_unit_tests.py
index e91da4ca8..cc40f3767 100644
--- a/modules/webaccess/lib/external_authentication_cern_unit_tests.py
+++ b/modules/webaccess/lib/external_authentication_cern_unit_tests.py
@@ -1,67 +1,69 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
-## Copyright (C) 2007, 2008, 2010, 2011 CERN.
+## Copyright (C) 2007, 2008, 2010, 2011, 2013 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 """Unit tests for the user handling library."""
 
 __revision__ = "$Id$"
 
 import unittest
 
 from invenio.config import CFG_CERN_SITE
-from invenio.testutils import make_test_suite, run_test_suite
+from invenio.testutils import make_test_suite, run_test_suite, nottest
 
 class ExternalAuthenticationCernTest(unittest.TestCase):
     """Test functions related to the CERN authentication."""
 
     def setUp(self):
         # pylint: disable=C0103
         """setting up helper variables for tests"""
         from invenio import external_authentication_cern as cern
         self.username, self.userpwd, self.useremail = \
                 open('demopwd.cfg', 'r').readline().strip().split(':', 2)
         self.cern = cern.ExternalAuthCern()
 
+    @nottest
     def test_auth_user_ok(self):
         """external authentication CERN - authorizing user through CERN system: should pass"""
         self.assertEqual(self.cern.auth_user(self.username, self.userpwd), \
                 self.useremail)
 
+    @nottest
     def test_auth_user_fail(self):
         """external authentication CERN - authorizing user through CERN system: should fail"""
         self.assertEqual(self.cern.auth_user('patata', 'patata'), None)
 
+    @nottest
     def test_fetch_user_groups_membership(self):
         """external authentication CERN - fetching user group membership at CERN"""
         self.assertNotEqual(self.cern.fetch_user_groups_membership(self.useremail, self.userpwd), 0)
         self.assertEqual(self.cern.fetch_user_groups_membership('patata', 'patata'), {})
 
+    @nottest
     def test_fetch_user_preferences(self):
         """external authentication CERN - fetching user setting from CERN"""
         self.assertEqual(self.cern.fetch_user_preferences(self.username, self.userpwd)['email'], self.useremail)
         #self.assertRaises(KeyError, self.cern.fetch_user_preferences('patata', 'patata')['email'])
 
 if CFG_CERN_SITE:
     TEST_SUITE = make_test_suite(ExternalAuthenticationCernTest,)
 else:
     TEST_SUITE = make_test_suite()
 
 if __name__ == "__main__":
     run_test_suite(TEST_SUITE)
-
-
diff --git a/modules/webcomment/lib/webcomment_regression_tests.py b/modules/webcomment/lib/webcomment_regression_tests.py
index 0982948e6..c9ff74c2a 100644
--- a/modules/webcomment/lib/webcomment_regression_tests.py
+++ b/modules/webcomment/lib/webcomment_regression_tests.py
@@ -1,875 +1,875 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
-## Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012 CERN.
+## Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 """WebComment Regression Test Suite."""
 
 __revision__ = "$Id$"
 
 import unittest
 import shutil
 from mechanize import Browser, LinkNotFoundError, HTTPError
 
 from invenio.config import \
      CFG_SITE_URL, \
      CFG_WEBDIR, \
      CFG_TMPDIR, \
      CFG_SITE_RECORD
 from invenio.testutils import make_test_suite, run_test_suite, \
                               test_web_page_content, merge_error_messages
 from invenio.dbquery import run_sql
 from invenio.webcomment import query_add_comment_or_remark
 from invenio.webcommentadminlib import query_delete_comment_auth
 from invenio.webcomment_washer import EmailWasher
 
 
 def prepare_attachments():
     """
     We copy necessary files to temporary directory. Every time we will
     attach files to a comment, these files get moved, so this function
     must be called again.
     """
     shutil.copy(CFG_WEBDIR + '/img/journal_water_dog.gif', CFG_TMPDIR)
     shutil.copy(CFG_WEBDIR + '/img/invenio.css', CFG_TMPDIR)
 
 
 class WebCommentWebPagesAvailabilityTest(unittest.TestCase):
     """Check WebComment web pages whether they are up or not."""
 
     def test_your_baskets_pages_availability(self):
         """webcomment - availability of comments pages"""
 
         baseurl = CFG_SITE_URL + '/%s/10/comments/' % CFG_SITE_RECORD
 
         _exports = ['', 'display', 'add', 'vote', 'report']
 
         error_messages = []
         for url in [baseurl + page for page in _exports]:
             error_messages.extend(test_web_page_content(url))
         if error_messages:
             self.fail(merge_error_messages(error_messages))
         return
 
     def test_webcomment_admin_interface_availability(self):
         """webcomment - availability of WebComment Admin interface pages"""
 
         baseurl = CFG_SITE_URL + '/admin/webcomment/webcommentadmin.py/'
 
         _exports = ['', 'comments', 'delete', 'users']
 
         error_messages = []
         for url in [baseurl + page for page in _exports]:
             # first try as guest:
             error_messages.extend(test_web_page_content(url,
                                                         username='guest',
                                                         expected_text=
                                                         'Authorization failure'))
             # then try as admin:
             error_messages.extend(test_web_page_content(url,
                                                         username='admin'))
         if error_messages:
             self.fail(merge_error_messages(error_messages))
         return
 
     def test_webcomment_admin_guide_availability(self):
         """webcomment - availability of WebComment Admin Guide"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/admin/webcomment-admin-guide',
                                                expected_text="WebComment Admin Guide"))
         return
 
     def test_webcomment_mini_review_availability(self):
         """webcomment - availability of mini-review panel on detailed record page"""
         url = CFG_SITE_URL + '/%s/12' % CFG_SITE_RECORD
         error_messages = test_web_page_content(url,
                                                expected_text="(Not yet reviewed)")
 
 
 class WebCommentRestrictionsTest(unittest.TestCase):
     """Check WebComment restrictions"""
 
     def setUp(self):
         """Insert some comments in some records"""
 
         # Comments have access restrictions when:
         # - the comment is in a restricted collection ('viewrestrcoll' action)
         # - the comment is in a restricted discussion page ('viewcomment' action)
         # - the comment itself is restricted ('viewrestrcomment'
         #   action), either because of the markup of the record, or
         #   because it is a reply to a restricted comment.
 
         self.public_record = 5
         self.public_record_restr_comment = 6
         self.restr_record = 42
         self.restr_record_restr_comment = 41
         self.restricted_discussion = 76
 
         self.romeo_uid = 5
         self.jekyll_uid = 2
         self.attached_files = {'file1': CFG_TMPDIR + '/journal_water_dog.gif',
                                'file2': CFG_TMPDIR + '/invenio.css'}
 
         # Load content of texual file2
         prepare_attachments()
         fp = file(self.attached_files['file2'])
         self.attached_file2_content = fp.read()
         fp.close()
 
         # Insert a public comment in a public record (public collection)
         self.msg1 = "A test comment 1"
         self.public_comid = query_add_comment_or_remark(reviews=0, recID=self.public_record,
                                                         uid=self.romeo_uid, msg=self.msg1,
                                                         editor_type='textarea',
                                                         attached_files=self.attached_files)
 
         # Insert a public comment in a restricted record (restricted collection)
         self.msg2 = "A test comment 2"
         prepare_attachments()
         self.restr_comid_1 = \
                            query_add_comment_or_remark(reviews=0, recID=self.restr_record,
                                                        uid=self.jekyll_uid, msg=self.msg2,
                                                        editor_type='textarea',
                                                        attached_files=self.attached_files)
 
         # Insert a restricted comment in a public collection
         self.msg3 = "A test comment 3"
         prepare_attachments()
         self.restr_comid_2 = \
                            query_add_comment_or_remark(reviews=0, recID=self.public_record_restr_comment,
                                                        uid=self.jekyll_uid, msg=self.msg3,
                                                        editor_type='textarea',
                                                        attached_files=self.attached_files)
 
         # Insert a restricted comment, in a restricted collection
         self.msg5 = "A test comment 5"
         prepare_attachments()
         self.restr_comid_4 = \
                            query_add_comment_or_remark(reviews=0, recID=self.restr_record_restr_comment,
                                                        uid=self.romeo_uid, msg=self.msg5,
                                                        editor_type='textarea',
                                                        attached_files=self.attached_files)
 
         # Insert a public comment in a restricted discussion
         self.msg6 = "A test comment 6"
         prepare_attachments()
         self.restr_comid_5 = \
                            query_add_comment_or_remark(reviews=0, recID=self.restricted_discussion,
                                                        uid=self.romeo_uid, msg=self.msg6,
                                                        editor_type='textarea',
                                                        attached_files=self.attached_files)
         self.restr_comid_3 = None
 
         # Insert a public, deleted comment in a public record (public collection)
         self.msg7 = "A test comment 7"
         prepare_attachments()
         self.deleted_comid = query_add_comment_or_remark(reviews=0, recID=self.public_record,
                                                         uid=self.romeo_uid, msg=self.msg7,
                                                         editor_type='textarea',
                                                         attached_files=self.attached_files)
         query_delete_comment_auth(self.deleted_comid)
 
     def tearDown(self):
         """Remove inserted comments"""
         run_sql("""DELETE FROM cmtRECORDCOMMENT WHERE id=%s""", (self.public_comid,))
         run_sql("""DELETE FROM cmtRECORDCOMMENT WHERE id=%s""", (self.restr_comid_1,))
         run_sql("""DELETE FROM cmtRECORDCOMMENT WHERE id=%s""", (self.restr_comid_2,))
         if self.restr_comid_3:
             run_sql("""DELETE FROM cmtRECORDCOMMENT WHERE id=%s""", (self.restr_comid_3,))
         run_sql("""DELETE FROM cmtRECORDCOMMENT WHERE id=%s""", (self.restr_comid_4,))
         run_sql("""DELETE FROM cmtRECORDCOMMENT WHERE id=%s""", (self.restr_comid_5,))
         run_sql("""DELETE FROM cmtRECORDCOMMENT WHERE id=%s""", (self.deleted_comid,))
         pass
 
     def test_access_public_record_public_discussion_public_comment(self):
         """webcomment - accessing "public" comment in a "public" discussion of a restricted record"""
         # Guest user should not be able to access it
         self.assertNotEqual([],
                          test_web_page_content("%s/%s/%i/comments/" % (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record),
                                                expected_text=self.msg2))
 
         # Accessing a non existing file for a restricted comment should also ask to login
         self.assertEqual([],
                          test_web_page_content("%s/%s/%i/comments/attachments/get/%i/not_existing_file" % \
                                                (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record, self.restr_comid_1),
                                                expected_text='You can use your nickname or your email address to login'))
 
         # Check accessing file of a restricted comment
         self.assertEqual([],
                          test_web_page_content("%s/%s/%i/comments/attachments/get/%i/file2" % \
                                                (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record, self.restr_comid_1),
                                                expected_text='You can use your nickname or your email address to login'))
 
 
     def test_access_restricted_record_public_discussion_public_comment(self):
         """webcomment - accessing "public" comment in a "public" discussion of a restricted record"""
         # Guest user should not be able to access it
         self.assertNotEqual([],
                          test_web_page_content("%s/%s/%i/comments/" % (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record),
                                                expected_text=self.msg2))
 
         # Accessing a non existing file for a restricted comment should also ask to login
         self.assertEqual([],
                          test_web_page_content("%s/%s/%i/comments/attachments/get/%i/not_existing_file" % \
                                                (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record, self.restr_comid_1),
                                                expected_text='You can use your nickname or your email address to login'))
 
         # Check accessing file of a restricted comment
         self.assertEqual([],
                          test_web_page_content("%s/%s/%i/comments/attachments/get/%i/file2" % \
                                                (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record, self.restr_comid_1),
                                                expected_text='You can use your nickname or your email address to login'))
 
         # Juliet should not be able to access the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/" % (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record))
         response = br.response().read()
         if not self.msg2 in response:
             pass
         else:
             self.fail("Oops, this user should not have access to this comment")
 
         # Juliet should not be able to access the attached files
         br.open("%s/%s/%i/comments/attachments/get/%i/file2" % \
                      (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record, self.restr_comid_1))
         response = br.response().read()
         if "You are not authorized" in response:
             pass
         else:
             self.fail("Oops, this user should not have access to this comment attachment")
 
         # Jekyll should be able to access the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'jekyll'
         br['p_pw'] = 'j123ekyll'
         br.submit()
         br.open("%s/%s/%i/comments/" % (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record))
         response = br.response().read()
         if not self.msg2 in response:
             self.fail("Oops, this user should have access to this comment")
 
         # Jekyll should be able to access the attached files
         br.open("%s/%s/%i/comments/attachments/get/%i/file2" % \
                      (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record, self.restr_comid_1))
         response = br.response().read()
         self.assertEqual(self.attached_file2_content, response)
 
     def test_access_public_record_restricted_discussion_public_comment(self):
         """webcomment - accessing "public" comment in a restricted discussion of a public record"""
         # Guest user should not be able to access it
         self.assertNotEqual([],
                          test_web_page_content("%s/%s/%i/comments/" % (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion),
                                                expected_text=self.msg2))
 
         # Accessing a non existing file for a restricted comment should also ask to login
         self.assertEqual([],
                          test_web_page_content("%s/%s/%i/comments/attachments/get/%i/not_existing_file" % \
                                                (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion, self.restr_comid_5),
                                                expected_text='You can use your nickname or your email address to login'))
 
         # Check accessing file of a restricted comment
         self.assertEqual([],
                          test_web_page_content("%s/%s/%i/comments/attachments/get/%i/file2" % \
                                                (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion, self.restr_comid_5),
                                                expected_text='You can use your nickname or your email address to login'))
 
         # Juliet should not be able to access the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/" % (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion))
         response = br.response().read()
         if not self.msg6 in response:
             pass
         else:
             self.fail("Oops, this user should not have access to this comment")
 
         # Juliet should not be able to access the attached files
         br.open("%s/%s/%i/comments/attachments/get/%i/file2" % \
                      (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion, self.restr_comid_5))
         response = br.response().read()
         if "You are not authorized" in response:
             pass
         else:
             self.fail("Oops, this user should not have access to this comment attachment")
 
         # Romeo should be able to access the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'romeo'
         br['p_pw'] = 'r123omeo'
         br.submit()
         br.open("%s/%s/%i/comments/" % (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion))
         response = br.response().read()
         if not self.msg6 in response:
             self.fail("Oops, this user should have access to this comment")
 
         # Romeo should be able to access the attached files
         br.open("%s/%s/%i/comments/attachments/get/%i/file2" % \
                      (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion, self.restr_comid_5))
         response = br.response().read()
         self.assertEqual(self.attached_file2_content, response)
 
     def test_comment_replies_inherit_restrictions(self):
         """webcomment - a reply to a comment inherits restrictions"""
         # In this test we reply to a restricted comment, and check if
         # the restriction is inherited. However, in order to make sure
         # that the comment restriction is inherited, and not the
         # record restriction, we temporary change the restriction of
         # the parent.
         self.public_record_restr_comment
         original_restriction = run_sql("SELECT restriction FROM cmtRECORDCOMMENT WHERE id=%s",
                                        (self.restr_comid_2,))[0][0]
         restriction_to_inherit = 'juliet_only'
         run_sql("UPDATE cmtRECORDCOMMENT SET restriction=%s WHERE id=%s",
                 (restriction_to_inherit, self.restr_comid_2))
 
         # Reply to a restricted comment
         self.msg4 = "A test comment 4"
         prepare_attachments()
         self.restr_comid_3 = \
                            query_add_comment_or_remark(reviews=0, recID=self.public_record_restr_comment,
                                                        uid=self.jekyll_uid, msg=self.msg4,
                                                        editor_type='textarea',
                                                        attached_files=self.attached_files,
                                                        reply_to=self.restr_comid_2)
 
         inherited_restriction = run_sql("SELECT restriction FROM cmtRECORDCOMMENT WHERE id=%s",
                                         (self.restr_comid_3,))[0][0]
 
         self.assertEqual(restriction_to_inherit, inherited_restriction)
 
         # Restore original restriction
         run_sql("UPDATE cmtRECORDCOMMENT SET restriction=%s WHERE id=%s",
                 (original_restriction, self.restr_comid_2))
 
     def test_comment_reply_with_wrong_record(self):
         """webcomment - replying to comment using mismatching recid"""
         # Juliet should not be able to reply to the comment, even through a public record
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/add?action=REPLY&comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.restr_comid_1))
         response = br.response().read()
         if not self.msg2 in response and \
                "Authorization failure" in response:
             pass
         else:
             self.fail("Oops, users should not be able to reply to comment using mismatching recid")
 
         # Jekyll should also not be able to reply the comment using the wrong recid
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'jekyll'
         br['p_pw'] = 'j123ekyll'
         br.submit()
         br.open("%s/%s/%i/comments/add?action=REPLY&comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.restr_comid_1))
         response = br.response().read()
         if not self.msg2 in response and \
                "Authorization failure" in response:
             pass
         else:
             self.fail("Oops, users should not be able to reply to comment using mismatching recid")
 
     def test_comment_access_attachment_with_wrong_record(self):
         """webcomment - accessing attachments using mismatching recid"""
         # Juliet should not be able to access these files, especially with wrong recid
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         try:
             br.open("%s/%s/%i/comments/attachments/get/%i/file2" % \
                      (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.restr_comid_1))
             response = br.response().read()
         except HTTPError:
             pass
         else:
             self.fail("Oops, users should not be able to access comment attachment using mismatching recid")
 
         # Jekyll should also not be able to access these files when using wrong recid
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'jekyll'
         br['p_pw'] = 'j123ekyll'
         br.submit()
         try:
             br.open("%s/%s/%i/comments/attachments/get/%i/file2" % \
                      (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.restr_comid_1))
             response = br.response().read()
             response = br.response().read()
         except HTTPError:
             pass
         else:
             self.fail("Oops, users should not be able to access comment attachment using mismatching recid")
 
     def test_comment_reply_to_deleted_comment(self):
         """webcomment - replying to a deleted comment"""
         # Juliet should not be able to reply to the deleted comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/add?action=REPLY&comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.deleted_comid))
         response = br.response().read()
         if not self.msg7 in response:
             # There should be no authorization failure, in case the
             # comment was deleted in between. We'll simply go on but
             # the orginal comment will not be included
             pass
         else:
             self.fail("Oops, users should not be able to reply to a deleted comment")
 
         # Jekyll should also not be able to reply the deleted comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'jekyll'
         br['p_pw'] = 'j123ekyll'
         br.submit()
         br.open("%s/%s/%i/comments/add?action=REPLY&comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.deleted_comid))
         response = br.response().read()
         if not self.msg7 in response:
             # There should be no authorization failure, in case the
             # comment was deleted in between. We'll simply go on but
             # the orginal comment will not be included
             pass
         else:
             self.fail("Oops, users should not be able to reply to a deleted comment")
 
     def test_comment_access_files_deleted_comment(self):
         """webcomment - access files of a deleted comment"""
         # Juliet should not be able to access the files
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/attachments/get/%i/file2" % \
                      (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.deleted_comid))
         response = br.response().read()
         if "You cannot access files of a deleted comment" in response:
             pass
         else:
             self.fail("Oops, users should not have access to this deleted comment attachment")
 
         # Jekyll should also not be able to access the files
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'jekyll'
         br['p_pw'] = 'j123ekyll'
         br.submit()
         br.open("%s/%s/%i/comments/attachments/get/%i/file2" % \
                      (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.deleted_comid))
         response = br.response().read()
         if "Authorization failure" in response:
             pass
         else:
             self.fail("Oops, users should not have access to this deleted comment attachment")
 
     def test_comment_report_deleted_comment(self):
         """webcomment - report a deleted comment"""
         # Juliet should not be able to report a the deleted comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/report?comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.deleted_comid))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, users should not be able to report a deleted comment")
 
     def test_comment_vote_deleted_comment(self):
         """webcomment - report a deleted comment"""
         # Juliet should not be able to vote for a the deleted comment/review
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/vote?comid=%s&com_value=1&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.deleted_comid))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, users should not be able to vote for a deleted comment")
 
     def test_comment_report_with_wrong_record(self):
         """webcomment - report a comment using mismatching recid"""
         # Juliet should not be able to report a comment she cannot access, even through public recid
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/report?comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.restr_comid_1))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, users should not be able to report using mismatching recid")
 
         # Jekyll should also not be able to report the comment using the wrong recid
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'jekyll'
         br['p_pw'] = 'j123ekyll'
         br.submit()
         br.open("%s/%s/%i/comments/report?comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.restr_comid_1))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, users should not be able to report using mismatching recid")
 
     def test_comment_vote_with_wrong_record(self):
         """webcomment - vote for a comment using mismatching recid"""
         # Juliet should not be able to vote for a comment she cannot access, especially through public recid
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/vote?comid=%s&com_value=1&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.restr_comid_1))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, this user should not be able to report a deleted comment")
 
         # Jekyll should also not be able to vote for the comment using the wrong recid
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'jekyll'
         br['p_pw'] = 'j123ekyll'
         br.submit()
         br.open("%s/%s/%i/comments/vote?comid=%s&com_value=1&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record, self.restr_comid_1))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, users should not be able to report using mismatching recid")
 
     def test_report_restricted_record_public_discussion_public_comment(self):
         """webcomment - report a comment restricted by 'viewrestrcoll'"""
         # Juliet should not be able to report the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/report?comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record, self.restr_comid_1))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, this user should not be able to report this comment")
 
     def test_report_public_record_restricted_discussion_public_comment(self):
         """webcomment - report a comment restricted by 'viewcomment'"""
         # Juliet should not be able to report the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/report?comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion, self.restr_comid_5))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, this user should not be able to report this comment")
 
     def test_report_public_record_public_discussion_restricted_comment(self):
         """webcomment - report a comment restricted by 'viewrestrcomment'"""
         # Juliet should not be able to report the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/report?comid=%s&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record_restr_comment, self.restr_comid_2))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, this user should not be able to report this comment")
 
     def test_vote_restricted_record_public_discussion_public_comment(self):
         """webcomment - vote for a comment restricted by 'viewrestrcoll'"""
         # Juliet should not be able to vote for the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/vote?comid=%s&com_value=1&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record, self.restr_comid_1))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, this user should not be able to report this comment")
 
     def test_vote_public_record_restricted_discussion_public_comment(self):
         """webcomment - vote for a comment restricted by 'viewcomment'"""
         # Juliet should not be able to vote for the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/vote?comid=%s&com_value=1&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion, self.restr_comid_5))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, this user should not be able to report this comment")
 
     def test_vote_public_record_public_discussion_restricted_comment(self):
         """webcomment - vote for a comment restricted by 'viewrestrcomment'"""
         # Juliet should not be able to vote for the comment
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/vote?comid=%s&com_value=1&ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.public_record_restr_comment, self.restr_comid_2))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, this user should not be able to report this comment")
 
     def test_comment_subscribe_restricted_record_public_discussion(self):
         """webcomment - subscribe to a discussion restricted with 'viewrestrcoll'"""
         # Juliet should not be able to subscribe to the discussion
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/subscribe?ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, this user should not be able to subscribe to this discussion")
 
         # Jekyll should be able to subscribe
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'jekyll'
         br['p_pw'] = 'j123ekyll'
         br.submit()
         br.open("%s/%s/%i/comments/subscribe?ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.restr_record))
         response = br.response().read()
         if not "You have been subscribed" in response or \
                "Authorization failure" in response:
             self.fail("Oops, this user should be able to subscribe to this discussion")
 
     def test_comment_subscribe_public_record_restricted_discussion(self):
         """webcomment - subscribe to a discussion restricted with 'viewcomment'"""
         # Juliet should not be able to subscribe to the discussion
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'juliet'
         br['p_pw'] = 'j123uliet'
         br.submit()
         br.open("%s/%s/%i/comments/subscribe?ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion))
         response = br.response().read()
         if not "Authorization failure" in response:
             self.fail("Oops, this user should not be able to subscribe to this discussion")
 
         # Romeo should be able to subscribe
         br = Browser()
         br.open(CFG_SITE_URL + '/youraccount/login')
         br.select_form(nr=0)
         br['p_un'] = 'romeo'
         br['p_pw'] = 'r123omeo'
         br.submit()
         br.open("%s/%s/%i/comments/subscribe?ln=en" % \
                 (CFG_SITE_URL, CFG_SITE_RECORD, self.restricted_discussion))
         response = br.response().read()
         if not "You have been subscribed" in response or \
                "Authorization failure" in response:
             print response
             self.fail("Oops, this user should be able to subscribe to this discussion")
 
 class WebCommentTransformationHTMLMarkupTest(unittest.TestCase):
     """ Test functions related to transforming HTML markup."""
 
     def test_unordered_lists_markup_transformation(self):
         """webcomment - unordered lists markup transformation """
         washer = EmailWasher()
         body_input = """<ul>
           <li>foo</li>
           <li>bar</li>
         </ul>"""
         body_expected = """
   * foo
   * bar
 """
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
         # Without spaces and EOL
         body_input = '<ul><li>foo</li><li>bar</li></ul>'
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
     def test_ordered_lists_markup_transformation(self):
         """ webcomment - ordered lists markup transformation """
         washer = EmailWasher()
         body_input = """<ol>
           <li>foo</li>
           <li>bar</li>
         </ol>"""
         body_expected = """
   1. foo
   2. bar
 """
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
         # Without spaces and EOL
         body_input = '<ol><li>foo</li><li>bar</li></ol>'
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
     def test_nested_lists_markup_transformation(self):
         """ webcomment - nested lists markup transformation """
         washer = EmailWasher()
         body_input =  """<ol>
           <li>foo
             <ol>
               <li>nested foo</li>
             </ol>
           </li>
           <li>bar</li>
         </ol>"""
         body_expected = """
   1. foo
     1. nested foo
   2. bar
 """
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
         # Without spaces and EOL
         body_input = '<ol><li>foo<ol><li>nested foo</li></ol></li><li>bar</li></ol>'
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
     def test_links_markup_transformation(self):
         """ webcomment - links markup transformation """
 
         washer = EmailWasher()
         body_input = 'text http://foo.com some more text'
         body_expected = 'text http://foo.com some more text'
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
         washer = EmailWasher()
         body_input = '<a href="https://cdsweb.cern.ch/">CDS</a>'
         body_expected = '<https://cdsweb.cern.ch/>(CDS)'
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
         washer = EmailWasher()
         body_input = '<a href="https://cdsweb.cern.ch/">https://cdsweb.cern.ch/</a>'
         body_expected = '<https://cdsweb.cern.ch/>'
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
     def test_global_markup_transformation(self):
         """ webcomment - global transformation """
         washer = EmailWasher()
         body_input = """<a href="http://foo.com">http://foo.com</a>
         <ol>
           <li>Main Ordered List item</li>
           <li>Below is an example of HTML nested unordered list
             <ul>
               <li>nested list item 1</li>
 
                  <li>nested list item 2</li>
               <li>Sub nested ordered list
                 <ol>
                   <li>sub nested list item A</li>
                   <li>sub nested list item B</li>
                 </ol>
               </li>
             </ul>
           </li>
           <li>The last line in the main ordered list</li>
         </ol> <a href="http://foo.com">bar</a>"""
         body_expected = """<http://foo.com>
   1. Main Ordered List item
   2. Below is an example of HTML nested unordered list
     * nested list item 1
     * nested list item 2
     * Sub nested ordered list
       1. sub nested list item A
       2. sub nested list item B
   3. The last line in the main ordered list
  <http://foo.com>(bar)"""
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
         # Without spaces and EOL
         body_input = '<a href="http://foo.com">http://foo.com</a><ol><li>Main Ordered List item</li><li>Below is an example of HTML nested unordered list<ul><li>nested list item 1</li><li>nested list item 2</li><li>Sub nested ordered list<ol><li>sub nested list item A</li><li>sub nested list item B</li></ol></li></ul></li><li>The last line in the main ordered list</li></ol> <a href="http://foo.com">bar</a>'
         self.assertEqual(washer.wash(body_input),
                          body_expected)
 
-TEST_SUITE = make_test_suite(#WebCommentWebPagesAvailabilityTest,
-                             #WebCommentRestrictionsTest,
+TEST_SUITE = make_test_suite(WebCommentWebPagesAvailabilityTest,
+                             WebCommentRestrictionsTest,
                              WebCommentTransformationHTMLMarkupTest)
 
 if __name__ == "__main__":
     run_test_suite(TEST_SUITE, warn_user=True)
diff --git a/modules/websearch/lib/websearch_external_collections_unit_tests.py b/modules/websearch/lib/websearch_external_collections_unit_tests.py
index f9d026636..b140bf538 100644
--- a/modules/websearch/lib/websearch_external_collections_unit_tests.py
+++ b/modules/websearch/lib/websearch_external_collections_unit_tests.py
@@ -1,99 +1,100 @@
 # -*- coding: utf-8 -*-
 
 ## This file is part of Invenio.
-## Copyright (C) 2006, 2007, 2008, 2010, 2011 CERN.
+## Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 """Testing functions for the external collections search.
 
    More tests of the page getter module can be done with
        websearch_external_collections_getter_tests.py
 """
 
 __revision__ = "$Id$"
 
 import unittest
 
 from invenio.websearch_external_collections_searcher import external_collections_dictionary
 from invenio.websearch_external_collections_getter import HTTPAsyncPageGetter, async_download
-from invenio.testutils import make_test_suite, run_test_suite
+from invenio.testutils import make_test_suite, run_test_suite, nottest
 
 def download_and_parse():
     """Try to make a query that always return results on all search engines.
     Check that a page is well returned and that the result can be parsed.
 
     This test is not included in the general test suite.
 
     This test give false positive if any of the external server is non working or too slow.
     """
     test = [['+', 'ieee', '', 'w']]
     errors = []
 
     external_collections = external_collections_dictionary.values()
     urls = [engine.build_search_url(test) for engine in external_collections]
     pagegetters = [HTTPAsyncPageGetter(url) for url in urls]
     dummy = async_download(pagegetters, None, None, 30)
 
     for (page, engine, url) in zip(pagegetters, external_collections, urls):
         if not url:
             errors.append("Unable to build url for : " + engine.name)
             continue
         if len(page.data) == 0:
             errors.append("Zero sized page with : " + engine.name)
             continue
         if engine.parser:
             results = engine.parser.parse_and_get_results(page.data)
             num_results = engine.parser.parse_num_results()
             if len(results) == 0:
                 errors.append("Unable to parse results for : " + engine.name)
                 continue
             if not num_results:
                 errors.append("Unable to parse (None returned) number of results for : " + engine.name)
             try:
                 num_results = int(num_results)
             except:
                 errors.append("Unable to parse (not a number) number of results for : " + engine.name)
 
     return errors
 
+@nottest
 def build_search_urls_test():
     """Build some classical urls from basic_search_units."""
     print "Testing external_search_engines build_search_url functions."
     tests = [ [['+', 'ellis', 'author', 'w'], ['+', 'unification', 'title', 'w'],
             ['-', 'Ross', 'author', 'w'], ['+', 'large', '', 'w'], ['-', 'helloworld', '', 'w']],
         [['+', 'ellis', 'author', 'w'], ['+', 'unification', 'title', 'w']],
         [['+', 'ellis', 'author', 'w']],
         [['-', 'Ross', 'author', 'w']] ]
     for engine in external_collections_dictionary.values():
         print engine.name
         for test in tests:
             url = engine.build_search_url(test)
             print "    Url: " + str(url)
 
 class ExtCollTests(unittest.TestCase):
     """Test cases for websearch_external_collections_*"""
 
+    @nottest
     def test_download_and_parse(self):
         """websearch_external_collections - download_and_parse (not reliable, see docstring)"""
         self.assertEqual([], download_and_parse())
 
 # FIXME: the above tests not plugged into global unit test suite
 TEST_SUITE = make_test_suite() #ExtCollTests,)
 
 if __name__ == "__main__":
     build_search_urls_test()
     run_test_suite(TEST_SUITE)
-
diff --git a/modules/websearch/lib/websearch_regression_tests.py b/modules/websearch/lib/websearch_regression_tests.py
index b453b6080..35f20724a 100644
--- a/modules/websearch/lib/websearch_regression_tests.py
+++ b/modules/websearch/lib/websearch_regression_tests.py
@@ -1,2179 +1,2181 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
-## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 CERN.
+## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 # pylint: disable=C0301
 # pylint: disable=E1102
 
 """WebSearch module regression tests."""
 
 __revision__ = "$Id$"
 
 import unittest
 import re
 import urlparse, cgi
 import sys
 
 if sys.hexversion < 0x2040000:
     # pylint: disable=W0622
     from sets import Set as set
     # pylint: enable=W0622
 
 from mechanize import Browser, LinkNotFoundError
 
 from invenio.config import CFG_SITE_URL, CFG_SITE_NAME, CFG_SITE_LANG, \
     CFG_SITE_RECORD, CFG_SITE_LANGS, CFG_WEBSEARCH_SPIRES_SYNTAX
 from invenio.testutils import make_test_suite, \
                               run_test_suite, \
+                              nottest, \
                               make_url, make_surl, test_web_page_content, \
                               merge_error_messages
 from invenio.urlutils import same_urls_p
 from invenio.dbquery import run_sql
 from invenio.search_engine import perform_request_search, \
     guess_primary_collection_of_a_record, guess_collection_of_a_record, \
     collection_restricted_p, get_permitted_restricted_collections, \
     search_pattern, search_unit, search_unit_in_bibrec, \
     wash_colls, record_public_p
 from invenio import search_engine_summarizer
 from invenio.search_engine_utils import get_fieldvalues
 
 
 if 'fr' in CFG_SITE_LANGS:
     lang_french_configured = True
 else:
     lang_french_configured = False
 
 
 def parse_url(url):
     parts = urlparse.urlparse(url)
     query = cgi.parse_qs(parts[4], True)
 
     return parts[2].split('/')[1:], query
 
 class WebSearchWebPagesAvailabilityTest(unittest.TestCase):
     """Check WebSearch web pages whether they are up or not."""
 
     def test_search_interface_pages_availability(self):
         """websearch - availability of search interface pages"""
 
         baseurl = CFG_SITE_URL + '/'
 
         _exports = ['', 'collection/Poetry', 'collection/Poetry?as=1']
 
         error_messages = []
         for url in [baseurl + page for page in _exports]:
             error_messages.extend(test_web_page_content(url))
         if error_messages:
             self.fail(merge_error_messages(error_messages))
         return
 
     def test_search_results_pages_availability(self):
         """websearch - availability of search results pages"""
 
         baseurl = CFG_SITE_URL + '/search'
 
         _exports = ['', '?c=Poetry', '?p=ellis', '/cache', '/log']
 
         error_messages = []
         for url in [baseurl + page for page in _exports]:
             error_messages.extend(test_web_page_content(url))
         if error_messages:
             self.fail(merge_error_messages(error_messages))
         return
 
     def test_search_detailed_record_pages_availability(self):
         """websearch - availability of search detailed record pages"""
 
         baseurl = CFG_SITE_URL + '/'+ CFG_SITE_RECORD +'/'
 
         _exports = ['', '1', '1/', '1/files', '1/files/']
 
         error_messages = []
         for url in [baseurl + page for page in _exports]:
             error_messages.extend(test_web_page_content(url))
         if error_messages:
             self.fail(merge_error_messages(error_messages))
         return
 
     def test_browse_results_pages_availability(self):
         """websearch - availability of browse results pages"""
 
         baseurl = CFG_SITE_URL + '/search'
 
         _exports = ['?p=ellis&f=author&action_browse=Browse']
 
         error_messages = []
         for url in [baseurl + page for page in _exports]:
             error_messages.extend(test_web_page_content(url))
         if error_messages:
             self.fail(merge_error_messages(error_messages))
         return
 
     def test_help_page_availability(self):
         """websearch - availability of Help Central page"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help',
                                                expected_text="Help Central"))
 
     if lang_french_configured:
         def test_help_page_availability_fr(self):
             """websearch - availability of Help Central page in french"""
             self.assertEqual([],
                              test_web_page_content(CFG_SITE_URL + '/help/?ln=fr',
                                                    expected_text="Centre d'aide"))
 
     def test_search_tips_page_availability(self):
         """websearch - availability of Search Tips"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/search-tips',
                                                expected_text="Search Tips"))
 
     if lang_french_configured:
         def test_search_tips_page_availability_fr(self):
             """websearch - availability of Search Tips in french"""
             self.assertEqual([],
                              test_web_page_content(CFG_SITE_URL + '/help/search-tips?ln=fr',
                                                    expected_text="Conseils de recherche"))
 
     def test_search_guide_page_availability(self):
         """websearch - availability of Search Guide"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/search-guide',
                                                expected_text="Search Guide"))
 
     if lang_french_configured:
         def test_search_guide_page_availability_fr(self):
             """websearch - availability of Search Guide in french"""
             self.assertEqual([],
                              test_web_page_content(CFG_SITE_URL + '/help/search-guide?ln=fr',
                                                    expected_text="Guide de recherche"))
 
 class WebSearchTestLegacyURLs(unittest.TestCase):
 
     """ Check that the application still responds to legacy URLs for
     navigating, searching and browsing."""
 
     def test_legacy_collections(self):
         """ websearch - collections handle legacy urls """
 
         browser = Browser()
 
         def check(legacy, new, browser=browser):
             browser.open(legacy)
             got = browser.geturl()
 
             self.failUnless(same_urls_p(got, new), got)
 
         # Use the root URL unless we need more
         check(make_url('/', c=CFG_SITE_NAME),
               make_url('/', ln=CFG_SITE_LANG))
 
         # Other collections are redirected in the /collection area
         check(make_url('/', c='Poetry'),
               make_url('/collection/Poetry', ln=CFG_SITE_LANG))
 
         # Drop unnecessary arguments, like ln and as (when they are
         # the default value)
         args = {'as': 0}
         check(make_url('/', c='Poetry', **args),
               make_url('/collection/Poetry', ln=CFG_SITE_LANG))
 
         # Otherwise, keep them
         args = {'as': 1, 'ln': CFG_SITE_LANG}
         check(make_url('/', c='Poetry', **args),
               make_url('/collection/Poetry', **args))
 
         # Support the /index.py addressing too
         check(make_url('/index.py', c='Poetry'),
               make_url('/collection/Poetry', ln=CFG_SITE_LANG))
 
 
     def test_legacy_search(self):
         """ websearch - search queries handle legacy urls """
 
         browser = Browser()
 
         def check(legacy, new, browser=browser):
             browser.open(legacy)
             got = browser.geturl()
 
             self.failUnless(same_urls_p(got, new), got)
 
         # /search.py is redirected on /search
         # Note that `as' is a reserved word in Python 2.5
         check(make_url('/search.py', p='nuclear', ln='en') + 'as=1',
               make_url('/search', p='nuclear', ln='en') + 'as=1')
 
     if lang_french_configured:
         def test_legacy_search_fr(self):
             """ websearch - search queries handle legacy urls """
 
             browser = Browser()
 
             def check(legacy, new, browser=browser):
                 browser.open(legacy)
                 got = browser.geturl()
 
                 self.failUnless(same_urls_p(got, new), got)
 
             # direct recid searches are redirected to /CFG_SITE_RECORD
             check(make_url('/search.py', recid=1, ln='fr'),
                   make_url('/%s/1' % CFG_SITE_RECORD, ln='fr'))
 
     def test_legacy_search_help_link(self):
         """websearch - legacy Search Help page link"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/search/index.en.html',
                                                expected_text="Help Central"))
 
     if lang_french_configured:
         def test_legacy_search_tips_link(self):
             """websearch - legacy Search Tips page link"""
             self.assertEqual([],
                              test_web_page_content(CFG_SITE_URL + '/help/search/tips.fr.html',
                                                    expected_text="Conseils de recherche"))
 
     def test_legacy_search_guide_link(self):
         """websearch - legacy Search Guide page link"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/search/guide.en.html',
                                                expected_text="Search Guide"))
 
 class WebSearchTestRecord(unittest.TestCase):
     """ Check the interface of the /CFG_SITE_RECORD results """
 
     def test_format_links(self):
         """ websearch - check format links for records """
 
         browser = Browser()
 
         # We open the record in all known HTML formats
         for hformat in ('hd', 'hx', 'hm'):
             browser.open(make_url('/%s/1' % CFG_SITE_RECORD, of=hformat))
 
             if hformat == 'hd':
                 # hd format should have a link to the following
                 # formats
                 for oformat in ('hx', 'hm', 'xm', 'xd'):
                     target = make_url('/%s/1/export/%s?ln=en' % (CFG_SITE_RECORD, oformat))
                     try:
                         browser.find_link(url=target)
                     except LinkNotFoundError:
                         self.fail('link %r should be in page' % target)
             else:
                 # non-hd HTML formats should have a link back to
                 # the main detailed record
                 target = make_url('/%s/1' % CFG_SITE_RECORD)
                 try:
                     browser.find_link(url=target)
                 except LinkNotFoundError:
                     self.fail('link %r should be in page' % target)
 
         return
 
     def test_exported_formats(self):
         """ websearch - check formats exported through /CFG_SITE_RECORD/1/export/ URLs"""
 
         self.assertEqual([],
                          test_web_page_content(make_url('/%s/1/export/hm' % CFG_SITE_RECORD),
                                                expected_text='245__ $$aALEPH experiment'))
         self.assertEqual([],
                          test_web_page_content(make_url('/%s/1/export/hd' % CFG_SITE_RECORD),
                                                expected_text='<strong>ALEPH experiment'))
         self.assertEqual([],
                          test_web_page_content(make_url('/%s/1/export/xm' % CFG_SITE_RECORD),
                                                expected_text='<subfield code="a">ALEPH experiment'))
         self.assertEqual([],
                          test_web_page_content(make_url('/%s/1/export/xd' % CFG_SITE_RECORD),
                                                expected_text='<dc:title>ALEPH experiment'))
         self.assertEqual([],
                          test_web_page_content(make_url('/%s/1/export/hs' % CFG_SITE_RECORD),
                                                expected_text='<a href="/%s/1?ln=%s">ALEPH experiment' % \
                                                (CFG_SITE_RECORD, CFG_SITE_LANG)))
         self.assertEqual([],
                          test_web_page_content(make_url('/%s/1/export/hx' % CFG_SITE_RECORD),
                                                expected_text='title        = "ALEPH experiment'))
         self.assertEqual([],
                          test_web_page_content(make_url('/%s/1/export/t?ot=245' % CFG_SITE_RECORD),
                                                expected_text='245__ $$aALEPH experiment'))
         self.assertNotEqual([],
                          test_web_page_content(make_url('/%s/1/export/t?ot=245' % CFG_SITE_RECORD),
                                                expected_text='001__'))
         self.assertEqual([],
                          test_web_page_content(make_url('/%s/1/export/h?ot=245' % CFG_SITE_RECORD),
                                                expected_text='245__ $$aALEPH experiment'))
         self.assertNotEqual([],
                          test_web_page_content(make_url('/%s/1/export/h?ot=245' % CFG_SITE_RECORD),
                                                expected_text='001__'))
         return
 
     def test_plots_tab(self):
         """ websearch - test to ensure the plots tab is working """
         self.assertEqual([],
                          test_web_page_content(make_url('/%s/8/plots' % CFG_SITE_RECORD),
                                                expected_text='div id="clip"',
                                                unexpected_text='Abstract'))
     def test_meta_header(self):
         """ websearch - test that metadata embedded in header of hd
         relies on hdm format and Default_HTML_meta bft, but hook is in
         websearch to display the format
         """
 
         self.assertEqual([],
                          test_web_page_content(make_url('/record/1'),
                                                expected_text='<meta content="ALEPH experiment: Candidate of Higgs boson production" name="citation_title" />'))
         return
 
 
 class WebSearchTestCollections(unittest.TestCase):
 
     def test_traversal_links(self):
         """ websearch - traverse all the publications of a collection """
 
         browser = Browser()
 
         try:
             for aas in (0, 1):
                 args = {'as': aas}
                 browser.open(make_url('/collection/Preprints', **args))
 
                 for jrec in (11, 21, 11, 28):
                     args = {'jrec': jrec, 'cc': 'Preprints'}
                     if aas:
                         args['as'] = aas
 
                     url = make_url('/search', **args)
                     try:
                         browser.follow_link(url=url)
                     except LinkNotFoundError:
                         args['ln'] = CFG_SITE_LANG
                         url = make_url('/search', **args)
                         browser.follow_link(url=url)
 
         except LinkNotFoundError:
             self.fail('no link %r in %r' % (url, browser.geturl()))
 
     def test_collections_links(self):
         """ websearch - enter in collections and subcollections """
 
         browser = Browser()
 
         def tryfollow(url):
             cur = browser.geturl()
             body = browser.response().read()
             try:
                 browser.follow_link(url=url)
             except LinkNotFoundError:
                 print body
                 self.fail("in %r: could not find %r" % (
                     cur, url))
             return
 
         for aas in (0, 1):
             if aas:
                 kargs = {'as': 1}
             else:
                 kargs = {}
 
             kargs['ln'] = CFG_SITE_LANG
 
             # We navigate from immediate son to immediate son...
             browser.open(make_url('/', **kargs))
             tryfollow(make_url('/collection/Articles%20%26%20Preprints',
                                **kargs))
             tryfollow(make_url('/collection/Articles', **kargs))
 
             # But we can also jump to a grandson immediately
             browser.back()
             browser.back()
             tryfollow(make_url('/collection/ALEPH', **kargs))
 
         return
 
     def test_records_links(self):
         """ websearch - check the links toward records in leaf collections """
 
         browser = Browser()
         browser.open(make_url('/collection/Preprints'))
 
         def harvest():
 
             """ Parse all the links in the page, and check that for
             each link to a detailed record, we also have the
             corresponding link to the similar records."""
 
             records = set()
             similar = set()
 
             for link in browser.links():
                 path, q = parse_url(link.url)
 
                 if not path:
                     continue
 
                 if path[0] == CFG_SITE_RECORD:
                     records.add(int(path[1]))
                     continue
 
                 if path[0] == 'search':
                     if not q.get('rm') == ['wrd']:
                         continue
 
                     recid = q['p'][0].split(':')[1]
                     similar.add(int(recid))
 
             self.failUnlessEqual(records, similar)
 
             return records
 
         # We must have 10 links to the corresponding /CFG_SITE_RECORD
         found = harvest()
         self.failUnlessEqual(len(found), 10)
 
         # When clicking on the "Search" button, we must also have
         # these 10 links on the records.
         browser.select_form(name="search")
         browser.submit()
 
         found = harvest()
         self.failUnlessEqual(len(found), 10)
         return
 
 
 class WebSearchTestBrowse(unittest.TestCase):
 
     def test_browse_field(self):
         """ websearch - check that browsing works """
 
         browser = Browser()
         browser.open(make_url('/'))
 
         browser.select_form(name='search')
         browser['f'] = ['title']
         browser.submit(name='action_browse')
 
         def collect():
             # We'll get a few links to search for the actual hits, plus a
             # link to the following results.
             res = []
             for link in browser.links(url_regex=re.compile(CFG_SITE_URL +
                                                            r'/search\?')):
                 if link.text == 'Advanced Search':
                     continue
 
                 dummy, q = parse_url(link.url)
                 res.append((link, q))
 
             return res
 
         # if we follow the last link, we should get another
         # batch. There is an overlap of one item.
         batch_1 = collect()
 
         browser.follow_link(link=batch_1[-1][0])
 
         batch_2 = collect()
 
         # FIXME: we cannot compare the whole query, as the collection
         # set is not equal
         self.failUnlessEqual(batch_1[-2][1]['p'], batch_2[0][1]['p'])
 
 class WebSearchTestOpenURL(unittest.TestCase):
 
     def test_isbn_01(self):
         """ websearch - isbn query via OpenURL 0.1"""
 
         browser = Browser()
 
         # We do a precise search in an isolated collection
         browser.open(make_url('/openurl', isbn='0387940758'))
 
         dummy, current_q = parse_url(browser.geturl())
 
         self.failUnlessEqual(current_q, {
             'sc' : ['1'],
             'p' : ['isbn:"0387940758"'],
             'of' : ['hd']
         })
 
     def test_isbn_10_rft_id(self):
         """ websearch - isbn query via OpenURL 1.0 - rft_id"""
 
         browser = Browser()
 
         # We do a precise search in an isolated collection
         browser.open(make_url('/openurl', rft_id='urn:ISBN:0387940758'))
 
         dummy, current_q = parse_url(browser.geturl())
 
         self.failUnlessEqual(current_q, {
             'sc' : ['1'],
             'p' : ['isbn:"0387940758"'],
             'of' : ['hd']
         })
 
     def test_isbn_10(self):
         """ websearch - isbn query via OpenURL 1.0"""
 
         browser = Browser()
 
         # We do a precise search in an isolated collection
         browser.open(make_url('/openurl?rft.isbn=0387940758'))
 
         dummy, current_q = parse_url(browser.geturl())
 
         self.failUnlessEqual(current_q, {
             'sc' : ['1'],
             'p' : ['isbn:"0387940758"'],
             'of' : ['hd']
         })
 
 
 class WebSearchTestSearch(unittest.TestCase):
 
     def test_hits_in_other_collection(self):
         """ websearch - check extension of a query to the home collection """
 
         browser = Browser()
 
         # We do a precise search in an isolated collection
         browser.open(make_url('/collection/ISOLDE', ln='en'))
 
         browser.select_form(name='search')
         browser['f'] = ['author']
         browser['p'] = 'matsubara'
         browser.submit()
 
         dummy, current_q = parse_url(browser.geturl())
 
         link = browser.find_link(text_regex=re.compile('.*hit', re.I))
         dummy, target_q = parse_url(link.url)
 
         # the target query should be the current query without any c
         # or cc specified.
         for f in ('cc', 'c', 'action_search'):
             if f in current_q:
                 del current_q[f]
 
         self.failUnlessEqual(current_q, target_q)
 
     def test_nearest_terms(self):
         """ websearch - provide a list of nearest terms """
 
         browser = Browser()
         browser.open(make_url(''))
 
         # Search something weird
         browser.select_form(name='search')
         browser['p'] = 'gronf'
         browser.submit()
 
         dummy, original = parse_url(browser.geturl())
 
         for to_drop in ('cc', 'action_search', 'f'):
             if to_drop in original:
                 del original[to_drop]
 
         if 'ln' not in original:
             original['ln'] = [CFG_SITE_LANG]
 
         # we should get a few searches back, which are identical
         # except for the p field being substituted (and the cc field
         # being dropped).
         if 'cc' in original:
             del original['cc']
 
         for link in browser.links(url_regex=re.compile(CFG_SITE_URL + r'/search\?')):
             if link.text == 'Advanced Search':
                 continue
 
             dummy, target = parse_url(link.url)
 
             if 'ln' not in target:
                 target['ln'] = [CFG_SITE_LANG]
 
             original['p'] = [link.text]
             self.failUnlessEqual(original, target)
 
         return
 
     def test_switch_to_simple_search(self):
         """ websearch - switch to simple search """
 
         browser = Browser()
         args = {'as': 1}
         browser.open(make_url('/collection/ISOLDE', **args))
 
         browser.select_form(name='search')
         browser['p1'] = 'tandem'
         browser['f1'] = ['title']
         browser.submit()
 
         browser.follow_link(text='Simple Search')
 
         dummy, q = parse_url(browser.geturl())
 
         self.failUnlessEqual(q, {'cc': ['ISOLDE'],
                                  'p': ['tandem'],
                                  'f': ['title'],
                                  'ln': ['en']})
 
     def test_switch_to_advanced_search(self):
         """ websearch - switch to advanced search """
 
         browser = Browser()
         browser.open(make_url('/collection/ISOLDE'))
 
         browser.select_form(name='search')
         browser['p'] = 'tandem'
         browser['f'] = ['title']
         browser.submit()
 
         browser.follow_link(text='Advanced Search')
 
         dummy, q = parse_url(browser.geturl())
 
         self.failUnlessEqual(q, {'cc': ['ISOLDE'],
                                  'p1': ['tandem'],
                                  'f1': ['title'],
                                  'as': ['1'],
                                  'ln' : ['en']})
 
     def test_no_boolean_hits(self):
         """ websearch - check the 'no boolean hits' proposed links """
 
         browser = Browser()
         browser.open(make_url(''))
 
         browser.select_form(name='search')
         browser['p'] = 'quasinormal muon'
         browser.submit()
 
         dummy, q = parse_url(browser.geturl())
 
         for to_drop in ('cc', 'action_search', 'f'):
             if to_drop in q:
                 del q[to_drop]
 
         for bsu in ('quasinormal', 'muon'):
             l = browser.find_link(text=bsu)
             q['p'] = bsu
 
             if not same_urls_p(l.url, make_url('/search', **q)):
                 self.fail(repr((l.url, make_url('/search', **q))))
 
     def test_similar_authors(self):
         """ websearch - test similar authors box """
 
         browser = Browser()
         browser.open(make_url(''))
 
         browser.select_form(name='search')
         browser['p'] = 'Ellis, R K'
         browser['f'] = ['author']
         browser.submit()
 
         l = browser.find_link(text="Ellis, R S")
         self.failUnless(same_urls_p(l.url, make_url('/search',
                                                     p="Ellis, R S",
                                                     f='author',
                                                     ln='en')))
 
 class WebSearchTestWildcardLimit(unittest.TestCase):
     """Checks if the wildcard limit is correctly passed and that
     users without autorization can not exploit it"""
 
     def test_wildcard_limit_correctly_passed_when_not_set(self):
         """websearch - wildcard limit is correctly passed when default"""
         self.assertEqual(search_pattern(p='e*', f='author'),
                          search_pattern(p='e*', f='author', wl=1000))
 
     def test_wildcard_limit_correctly_passed_when_set(self):
         """websearch - wildcard limit is correctly passed when set"""
         self.assertEqual([],
             test_web_page_content(CFG_SITE_URL + '/search?p=e*&f=author&of=id&wl=5&rg=100',
                                   expected_text="[9, 10, 11, 17, 46, 48, 50, 51, 52, 53, 54, 67, 72, 74, 81, 88, 92, 96]"))
 
     def test_wildcard_limit_correctly_not_active(self):
         """websearch - wildcard limit is not active when there is no wildcard query"""
         self.assertEqual(search_pattern(p='ellis', f='author'),
                          search_pattern(p='ellis', f='author', wl=1))
 
     def test_wildcard_limit_increased_by_authorized_users(self):
         """websearch - wildcard limit increased by authorized user"""
 
         browser = Browser()
 
         #try a search query, with no wildcard limit set by the user
         browser.open(make_url('/search?p=a*&of=id'))
         recid_list_guest_no_limit = browser.response().read() # so the limit is CGF_WEBSEARCH_WILDCARD_LIMIT
 
         #try a search query, with a wildcard limit imposed by the user
         #wl=1000000 - a very high limit,higher then what the CFG_WEBSEARCH_WILDCARD_LIMIT might be
         browser.open(make_url('/search?p=a*&of=id&wl=1000000'))
         recid_list_guest_with_limit = browser.response().read()
 
         #same results should be returned for a search without the wildcard limit set by the user
         #and for a search with a large limit set by the user
         #in this way we know that nomatter how large the limit is, the wildcard query will be
         #limitted by CFG_WEBSEARCH_WILDCARD_LIMIT (for a guest user)
         self.failIf(len(recid_list_guest_no_limit.split(',')) != len(recid_list_guest_with_limit.split(',')))
 
         ##login as admin
         browser.open(make_surl('/youraccount/login'))
         browser.select_form(nr=0)
         browser['p_un'] = 'admin'
         browser['p_pw'] = ''
         browser.submit()
 
         #try a search query, with a wildcard limit imposed by an authorized user
         #wl = 10000 a very high limit, higher then what the CFG_WEBSEARCH_WILDCARD_LIMIT might be
         browser.open(make_surl('/search?p=a*&of=id&wl=10000'))
         recid_list_authuser_with_limit = browser.response().read()
 
         #the authorized user can set whatever limit he might wish
         #so, the results returned for the auth. users should exceed the results returned for unauth. users
         self.failUnless(len(recid_list_guest_no_limit.split(',')) <= len(recid_list_authuser_with_limit.split(',')))
 
         #logout
         browser.open(make_surl('/youraccount/logout'))
         browser.response().read()
         browser.close()
 
 class WebSearchNearestTermsTest(unittest.TestCase):
     """Check various alternatives of searches leading to the nearest
     terms box."""
 
     def test_nearest_terms_box_in_okay_query(self):
         """ websearch - no nearest terms box for a successful query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis',
                                                expected_text="jump to record"))
 
     def test_nearest_terms_box_in_unsuccessful_simple_query(self):
         """ websearch - nearest terms box for unsuccessful simple query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellisz',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=embed",
                                                expected_link_label='embed'))
 
     def test_nearest_terms_box_in_unsuccessful_simple_accented_query(self):
         """ websearch - nearest terms box for unsuccessful accented query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=elliszà',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=embed",
                                                expected_link_label='embed'))
 
     def test_nearest_terms_box_in_unsuccessful_structured_query(self):
         """ websearch - nearest terms box for unsuccessful structured query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellisz&f=author',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=fabbro&f=author",
                                                expected_link_label='fabbro'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=author%3Aellisz',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=author%3Afabbro",
                                                expected_link_label='fabbro'))
 
     def test_nearest_terms_box_in_query_with_invalid_index(self):
         """ websearch - nearest terms box for queries with invalid indexes specified """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=bednarz%3Aellis',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=bednarz",
                                                expected_link_label='bednarz'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=1%3Aellis',
                                                expected_text="no index 1.",
                                                expected_link_target=CFG_SITE_URL+"/record/47?ln=en",
                                                expected_link_label="Detailed record"))
 
     def test_nearest_terms_box_in_unsuccessful_phrase_query(self):
         """ websearch - nearest terms box for unsuccessful phrase query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=author%3A%22Ellis%2C+Z%22',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=author%3A%22Enqvist%2C+K%22",
                                                expected_link_label='Enqvist, K'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%22ellisz%22&f=author',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=%22Enqvist%2C+K%22&f=author",
                                                expected_link_label='Enqvist, K'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%22elliszà%22&f=author',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=%22Enqvist%2C+K%22&f=author",
                                                expected_link_label='Enqvist, K'))
 
     def test_nearest_terms_box_in_unsuccessful_partial_phrase_query(self):
         """ websearch - nearest terms box for unsuccessful partial phrase query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=author%3A%27Ellis%2C+Z%27',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=author%3A%27Enqvist%2C+K%27",
                                                expected_link_label='Enqvist, K'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%27ellisz%27&f=author',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=%27Enqvist%2C+K%27&f=author",
                                                expected_link_label='Enqvist, K'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%27elliszà%27&f=author',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=%27Enqvist%2C+K%27&f=author",
                                                expected_link_label='Enqvist, K'))
 
     def test_nearest_terms_box_in_unsuccessful_partial_phrase_advanced_query(self):
         """ websearch - nearest terms box for unsuccessful partial phrase advanced search query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p1=aaa&f1=title&m1=p&as=1',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&f1=title&as=1&p1=A+simple+functional+form+for+proton-nucleus+total+reaction+cross+sections&m1=p",
                                                expected_link_label='A simple functional form for proton-nucleus total reaction cross sections'))
 
     def test_nearest_terms_box_in_unsuccessful_exact_phrase_advanced_query(self):
         """ websearch - nearest terms box for unsuccessful exact phrase advanced search query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p1=aaa&f1=title&m1=e&as=1',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&f1=title&as=1&p1=A+simple+functional+form+for+proton-nucleus+total+reaction+cross+sections&m1=e",
                                                expected_link_label='A simple functional form for proton-nucleus total reaction cross sections'))
 
     def test_nearest_terms_box_in_unsuccessful_boolean_query(self):
         """ websearch - nearest terms box for unsuccessful boolean query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=title%3Aellisz+author%3Aellisz',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=title%3Aenergi+author%3Aellisz",
                                                expected_link_label='energi'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=title%3Aenergi+author%3Aenergie',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=title%3Aenergi+author%3Aenqvist",
                                                expected_link_label='enqvist'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=title%3Aellisz+author%3Aellisz&f=keyword',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=title%3Aenergi+author%3Aellisz&f=keyword",
                                                expected_link_label='energi'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=title%3Aenergi+author%3Aenergie&f=keyword',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=title%3Aenergi+author%3Aenqvist&f=keyword",
                                                expected_link_label='enqvist'))
 
     def test_nearest_terms_box_in_unsuccessful_uppercase_query(self):
         """ websearch - nearest terms box for unsuccessful uppercase query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=fOo%3Atest',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=food",
                                                expected_link_label='food'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=arXiv%3A1007.5048',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=artist",
                                                expected_link_label='artist'))
 
     def test_nearest_terms_box_in_unsuccessful_spires_query(self):
         """ websearch - nearest terms box for unsuccessful spires query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=find+a+foobar',
                                                expected_text="Nearest terms in any collection are",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=find+a+finch",
                                                expected_link_label='finch'))
 
 
 class WebSearchBooleanQueryTest(unittest.TestCase):
     """Check various boolean queries."""
 
     def test_successful_boolean_query(self):
         """ websearch - successful boolean query """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis+muon',
                                                expected_text="records found",
                                                expected_link_label="Detailed record"))
 
     def test_unsuccessful_boolean_query_where_all_individual_terms_match(self):
         """ websearch - unsuccessful boolean query where all individual terms match """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis+muon+letter',
                                                expected_text="Boolean query returned no hits. Please combine your search terms differently."))
 
 class WebSearchAuthorQueryTest(unittest.TestCase):
     """Check various author-related queries."""
 
     def test_propose_similar_author_names_box(self):
         """ websearch - propose similar author names box """
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=Ellis%2C+R&f=author',
                                                expected_text="See also: similar author names",
                                                expected_link_target=CFG_SITE_URL+"/search?ln=en&p=Ellis%2C+R+K&f=author",
                                                expected_link_label="Ellis, R K"))
 
     def test_do_not_propose_similar_author_names_box(self):
         """ websearch - do not propose similar author names box """
         errmsgs = test_web_page_content(CFG_SITE_URL + '/search?p=author%3A%22Ellis%2C+R%22',
                                         expected_link_target=CFG_SITE_URL+"/search?ln=en&p=Ellis%2C+R+K&f=author",
                                         expected_link_label="Ellis, R K")
         if errmsgs[0].find("does not contain link to") > -1:
             pass
         else:
             self.fail("Should not propose similar author names box.")
         return
 
 class WebSearchSearchEnginePythonAPITest(unittest.TestCase):
     """Check typical search engine Python API calls on the demo data."""
 
     def test_search_engine_python_api_for_failed_query(self):
         """websearch - search engine Python API for failed query"""
         self.assertEqual([],
                          perform_request_search(p='aoeuidhtns'))
 
     def test_search_engine_python_api_for_successful_query(self):
         """websearch - search engine Python API for successful query"""
         self.assertEqual([8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 47],
                          perform_request_search(p='ellis'))
 
     def test_search_engine_web_api_ignore_paging_parameter(self):
         """websearch - search engine Python API for successful query, ignore paging parameters"""
         self.assertEqual([8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 47],
                          perform_request_search(p='ellis', rg=5, jrec=3))
 
     def test_search_engine_web_api_respect_sorting_parameter(self):
         """websearch - search engine Python API for successful query, respect sorting parameters"""
         self.assertEqual([77, 84, 85],
                          perform_request_search(p='klebanov'))
         self.assertEqual([77, 85, 84],
                          perform_request_search(p='klebanov', sf='909C4v'))
 
     def test_search_engine_web_api_respect_ranking_parameter(self):
         """websearch - search engine Python API for successful query, respect ranking parameters"""
         self.assertEqual([77, 84, 85],
                          perform_request_search(p='klebanov'))
         self.assertEqual([85, 77, 84],
                          perform_request_search(p='klebanov', rm='citation'))
 
     def test_search_engine_python_api_for_existing_record(self):
         """websearch - search engine Python API for existing record"""
         self.assertEqual([8],
                          perform_request_search(recid=8))
 
     def test_search_engine_python_api_for_nonexisting_record(self):
         """websearch - search engine Python API for non-existing record"""
         self.assertEqual([],
                          perform_request_search(recid=16777215))
 
     def test_search_engine_python_api_for_nonexisting_collection(self):
         """websearch - search engine Python API for non-existing collection"""
         self.assertEqual([],
                          perform_request_search(c='Foo'))
 
     def test_search_engine_python_api_for_range_of_records(self):
         """websearch - search engine Python API for range of records"""
         self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8, 9],
                          perform_request_search(recid=1, recidb=10))
 
     def test_search_engine_python_api_ranked_by_citation(self):
         """websearch - search engine Python API for citation ranking"""
         self.assertEqual([82, 83, 87, 89],
                 perform_request_search(p='recid:81', rm='citation'))
 
     def test_search_engine_python_api_textmarc(self):
         """websearch - search engine Python API for Text MARC output"""
         # we are testing example from /help/hacking/search-engine-api
         import cStringIO
         tmp = cStringIO.StringIO()
         perform_request_search(req=tmp, p='higgs', of='tm', ot=['100', '700'])
         out = tmp.getvalue()
         tmp.close()
         self.assertEqual(out, """\
 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca
 000000085 700__ $$aPorrati, Massimo
 000000085 700__ $$aZaffaroni, A
 000000001 100__ $$aPhotolab
 """)
 
 
 class WebSearchSearchEngineWebAPITest(unittest.TestCase):
     """Check typical search engine Web API calls on the demo data."""
 
     def test_search_engine_web_api_for_failed_query(self):
         """websearch - search engine Web API for failed query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=aoeuidhtns&of=id',
                                                expected_text="[]"))
 
 
     def test_search_engine_web_api_for_successful_query(self):
         """websearch - search engine Web API for successful query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=id',
                                                expected_text="[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 47]"))
 
     def test_search_engine_web_api_ignore_paging_parameter(self):
         """websearch - search engine Web API for successful query, ignore paging parameters"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=id&rg=5&jrec=3',
                                                expected_text="[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 47]"))
 
     def test_search_engine_web_api_respect_sorting_parameter(self):
         """websearch - search engine Web API for successful query, respect sorting parameters"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id',
                                                expected_text="[77, 84, 85]"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id&sf=909C4v',
                                                expected_text="[77, 85, 84]"))
 
     def test_search_engine_web_api_respect_ranking_parameter(self):
         """websearch - search engine Web API for successful query, respect ranking parameters"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id',
                                                expected_text="[77, 84, 85]"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id&rm=citation',
                                                expected_text="[85, 77, 84]"))
 
     def test_search_engine_web_api_for_existing_record(self):
         """websearch - search engine Web API for existing record"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?recid=8&of=id',
                                                expected_text="[8]"))
 
     def test_search_engine_web_api_for_nonexisting_record(self):
         """websearch - search engine Web API for non-existing record"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?recid=123456789&of=id',
                                                expected_text="[]"))
 
     def test_search_engine_web_api_for_nonexisting_collection(self):
         """websearch - search engine Web API for non-existing collection"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?c=Foo&of=id',
                                                expected_text="[]"))
 
     def test_search_engine_web_api_for_range_of_records(self):
         """websearch - search engine Web API for range of records"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?recid=1&recidb=10&of=id',
                                                expected_text="[1, 2, 3, 4, 5, 6, 7, 8, 9]"))
 
 class WebSearchRestrictedCollectionTest(unittest.TestCase):
     """Test of the restricted Theses collection behaviour."""
 
     def test_restricted_collection_interface_page(self):
         """websearch - restricted collection interface page body"""
         # there should be no Latest additions box for restricted collections
         self.assertNotEqual([],
                             test_web_page_content(CFG_SITE_URL + '/collection/Theses',
                                                   expected_text="Latest additions"))
 
     def test_restricted_search_as_anonymous_guest(self):
         """websearch - restricted collection not searchable by anonymous guest"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/search?c=Theses')
         response = browser.response().read()
         if response.find("If you think you have right to access it, please authenticate yourself.") > -1:
             pass
         else:
             self.fail("Oops, searching restricted collection without password should have redirected to login dialog.")
         return
 
     def test_restricted_search_as_authorized_person(self):
         """websearch - restricted collection searchable by authorized person"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/search?c=Theses')
         browser.select_form(nr=0)
         browser['p_un'] = 'jekyll'
         browser['p_pw'] = 'j123ekyll'
         browser.submit()
         if browser.response().read().find("records found") > -1:
             pass
         else:
             self.fail("Oops, Dr. Jekyll should be able to search Theses collection.")
 
     def test_restricted_search_as_unauthorized_person(self):
         """websearch - restricted collection not searchable by unauthorized person"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/search?c=Theses')
         browser.select_form(nr=0)
         browser['p_un'] = 'hyde'
         browser['p_pw'] = 'h123yde'
         browser.submit()
         # Mr. Hyde should not be able to connect:
         if browser.response().read().find("Authorization failure") <= -1:
             # if we got here, things are broken:
             self.fail("Oops, Mr.Hyde should not be able to search Theses collection.")
 
     def test_restricted_detailed_record_page_as_anonymous_guest(self):
         """websearch - restricted detailed record page not accessible to guests"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/%s/35' % CFG_SITE_RECORD)
         if browser.response().read().find("You can use your nickname or your email address to login.") > -1:
             pass
         else:
             self.fail("Oops, searching restricted collection without password should have redirected to login dialog.")
         return
 
     def test_restricted_detailed_record_page_as_authorized_person(self):
         """websearch - restricted detailed record page accessible to authorized person"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/youraccount/login')
         browser.select_form(nr=0)
         browser['p_un'] = 'jekyll'
         browser['p_pw'] = 'j123ekyll'
         browser.submit()
         browser.open(CFG_SITE_URL + '/%s/35' % CFG_SITE_RECORD)
         # Dr. Jekyll should be able to connect
         # (add the pw to the whole CFG_SITE_URL because we shall be
         # redirected to '/reordrestricted/'):
         if browser.response().read().find("A High-performance Video Browsing System") > -1:
             pass
         else:
             self.fail("Oops, Dr. Jekyll should be able to access restricted detailed record page.")
 
     def test_restricted_detailed_record_page_as_unauthorized_person(self):
         """websearch - restricted detailed record page not accessible to unauthorized person"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/youraccount/login')
         browser.select_form(nr=0)
         browser['p_un'] = 'hyde'
         browser['p_pw'] = 'h123yde'
         browser.submit()
         browser.open(CFG_SITE_URL + '/%s/35' % CFG_SITE_RECORD)
         # Mr. Hyde should not be able to connect:
         if browser.response().read().find('You are not authorized') <= -1:
             # if we got here, things are broken:
             self.fail("Oops, Mr.Hyde should not be able to access restricted detailed record page.")
 
     def test_collection_restricted_p(self):
         """websearch - collection_restricted_p"""
         self.failUnless(collection_restricted_p('Theses'), True)
         self.failIf(collection_restricted_p('Books & Reports'))
 
     def test_get_permitted_restricted_collections(self):
         """websearch - get_permitted_restricted_collections"""
         from invenio.webuser import get_uid_from_email, collect_user_info
         self.assertEqual(get_permitted_restricted_collections(collect_user_info(get_uid_from_email('jekyll@cds.cern.ch'))), ['Theses'])
         self.assertEqual(get_permitted_restricted_collections(collect_user_info(get_uid_from_email('hyde@cds.cern.ch'))), [])
 
     def test_restricted_record_has_restriction_flag(self):
         """websearch - restricted record displays a restriction flag"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/%s/42/files/' % CFG_SITE_RECORD)
         browser.select_form(nr=0)
         browser['p_un'] = 'jekyll'
         browser['p_pw'] = 'j123ekyll'
         browser.submit()
         if browser.response().read().find("Restricted") > -1:
             pass
         else:
             self.fail("Oops, a 'Restricted' flag should appear on restricted records.")
 
         browser.open(CFG_SITE_URL + '/%s/42/files/comments' % CFG_SITE_RECORD)
         if browser.response().read().find("Restricted") > -1:
             pass
         else:
             self.fail("Oops, a 'Restricted' flag should appear on restricted records.")
 
 class WebSearchRestrictedPicturesTest(unittest.TestCase):
     """
     Check whether restricted pictures on the demo site can be accessed
     well by people who have rights to access them.
     """
 
     def test_restricted_pictures_guest(self):
         """websearch - restricted pictures not available to guest"""
         error_messages = test_web_page_content(CFG_SITE_URL + '/%s/1/files/0106015_01.jpg' % CFG_SITE_RECORD,
                                                expected_text=['This file is restricted.  If you think you have right to access it, please authenticate yourself.'])
         if error_messages:
             self.fail(merge_error_messages(error_messages))
 
     def test_restricted_pictures_romeo(self):
         """websearch - restricted pictures available to Romeo"""
         error_messages = test_web_page_content(CFG_SITE_URL + '/%s/1/files/0106015_01.jpg' % CFG_SITE_RECORD,
                                                username='romeo',
                                                password='r123omeo',
                                                expected_text=[],
                                                unexpected_text=['This file is restricted',
                                                                 'You are not authorized'])
         if error_messages:
             self.fail(merge_error_messages(error_messages))
 
     def test_restricted_pictures_hyde(self):
         """websearch - restricted pictures not available to Mr. Hyde"""
 
         error_messages = test_web_page_content(CFG_SITE_URL + '/%s/1/files/0106015_01.jpg' % CFG_SITE_RECORD,
                                                username='hyde',
                                                password='h123yde',
                                                expected_text=['This file is restricted',
                                                               'You are not authorized'])
         if error_messages:
             self.failUnless("HTTP Error 401: Unauthorized" in merge_error_messages(error_messages))
 
 class WebSearchRestrictedWebJournalFilesTest(unittest.TestCase):
     """
     Check whether files attached to a WebJournal article are well
     accessible when the article is published
     """
     def test_restricted_files_guest(self):
         """websearch - files of unreleased articles are not available to guest"""
 
         # Record is not public...
         self.assertEqual(record_public_p(106), False)
 
         # ... and guest cannot access attached files
         error_messages = test_web_page_content(CFG_SITE_URL + '/%s/106/files/journal_galapagos_archipelago.jpg' % CFG_SITE_RECORD,
                                                expected_text=['This file is restricted.  If you think you have right to access it, please authenticate yourself.'])
         if error_messages:
             self.fail(merge_error_messages(error_messages))
 
     def test_restricted_files_editor(self):
         """websearch - files of unreleased articles are available to editor"""
 
         # Record is not public...
         self.assertEqual(record_public_p(106), False)
 
         # ... but editor can access attached files
         error_messages = test_web_page_content(CFG_SITE_URL + '/%s/106/files/journal_galapagos_archipelago.jpg' % CFG_SITE_RECORD,
                                                username='balthasar',
                                                password='b123althasar',
                                                expected_text=[],
                                                unexpected_text=['This file is restricted',
                                                                 'You are not authorized'])
         if error_messages:
             self.fail(merge_error_messages(error_messages))
 
     def test_public_files_guest(self):
         """websearch - files of released articles are available to guest"""
 
         # Record is not public...
         self.assertEqual(record_public_p(105), False)
 
         # ... but user can access attached files, as article is released
         error_messages = test_web_page_content(CFG_SITE_URL + '/%s/105/files/journal_scissor_beak.jpg' % CFG_SITE_RECORD,
                                                expected_text=[],
                                                 unexpected_text=['This file is restricted',
                                                                  'You are not authorized'])
         if error_messages:
             self.fail(merge_error_messages(error_messages))
 
     def test_really_restricted_files_guest(self):
         """websearch - restricted files of released articles are not available to guest"""
 
         # Record is not public...
         self.assertEqual(record_public_p(105), False)
 
         # ... and user cannot access restricted attachements, even if
         # article is released
         error_messages = test_web_page_content(CFG_SITE_URL + '/%s/105/files/restricted-journal_scissor_beak.jpg' % CFG_SITE_RECORD,
                                                expected_text=['This file is restricted.  If you think you have right to access it, please authenticate yourself.'])
         if error_messages:
             self.fail(merge_error_messages(error_messages))
 
     def test_restricted_picture_has_restriction_flag(self):
         """websearch - restricted files displays a restriction flag"""
         error_messages = test_web_page_content(CFG_SITE_URL + '/%s/1/files/' % CFG_SITE_RECORD,
                                                   expected_text="Restricted")
         if error_messages:
             self.fail(merge_error_messages(error_messages))
 
 class WebSearchRSSFeedServiceTest(unittest.TestCase):
     """Test of the RSS feed service."""
 
     def test_rss_feed_service(self):
         """websearch - RSS feed service"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/rss',
                                                expected_text='<rss version="2.0"'))
 
 class WebSearchXSSVulnerabilityTest(unittest.TestCase):
     """Test possible XSS vulnerabilities of the search engine."""
 
     def test_xss_in_collection_interface_page(self):
         """websearch - no XSS vulnerability in collection interface pages"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/?c=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E',
                                                expected_text='Collection &amp;lt;SCRIPT&amp;gt;alert("XSS");&amp;lt;/SCRIPT&amp;gt; Not Found'))
 
     def test_xss_in_collection_search_page(self):
         """websearch - no XSS vulnerability in collection search pages"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?c=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E',
                                                expected_text='Collection &lt;SCRIPT&gt;alert("XSS");&lt;/SCRIPT&gt; Not Found'))
 
     def test_xss_in_simple_search(self):
         """websearch - no XSS vulnerability in simple search"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E',
                                                expected_text='Search term <em>&lt;SCRIPT&gt;alert("XSS");&lt;/SCRIPT&gt;</em> did not match any record.'))
 
     def test_xss_in_structured_search(self):
         """websearch - no XSS vulnerability in structured search"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E&f=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E',
                                                expected_text='No word index is available for <em>&lt;script&gt;alert("xss");&lt;/script&gt;</em>.'))
 
     def test_xss_in_advanced_search(self):
         """websearch - no XSS vulnerability in advanced search"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?as=1&p1=ellis&f1=author&op1=a&p2=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E&f2=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E&m2=e',
                                                expected_text='Search term <em>&lt;SCRIPT&gt;alert("XSS");&lt;/SCRIPT&gt;</em> inside index <em>&lt;script&gt;alert("xss");&lt;/script&gt;</em> did not match any record.'))
 
     def test_xss_in_browse(self):
         """websearch - no XSS vulnerability in browse"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E&f=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E&action_browse=Browse',
                                                expected_text='&lt;SCRIPT&gt;alert("XSS");&lt;/SCRIPT&gt;'))
 
 class WebSearchResultsOverview(unittest.TestCase):
     """Test of the search results page's Results overview box and links."""
 
     def test_results_overview_split_off(self):
         """websearch - results overview box when split by collection is off"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/search?p=of&sc=0')
         body = browser.response().read()
         if body.find("Results overview") > -1:
             self.fail("Oops, when split by collection is off, "
                       "results overview should not be present.")
         if body.find('<a name="1"></a>') == -1:
             self.fail("Oops, when split by collection is off, "
                       "Atlantis collection should be found.")
         if body.find('<a name="15"></a>') > -1:
             self.fail("Oops, when split by collection is off, "
                       "Multimedia & Arts should not be found.")
         try:
             browser.find_link(url='#15')
             self.fail("Oops, when split by collection is off, "
                       "a link to Multimedia & Arts should not be found.")
         except LinkNotFoundError:
             pass
 
     def test_results_overview_split_on(self):
         """websearch - results overview box when split by collection is on"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/search?p=of&sc=1')
         body = browser.response().read()
         if body.find("Results overview") == -1:
             self.fail("Oops, when split by collection is on, "
                       "results overview should be present.")
         if body.find('<a name="Atlantis%20Institute%20of%20Fictive%20Science"></a>') > -1:
             self.fail("Oops, when split by collection is on, "
                       "Atlantis collection should not be found.")
         if body.find('<a name="15"></a>') == -1:
             self.fail("Oops, when split by collection is on, "
                       "Multimedia & Arts should be found.")
         try:
             browser.find_link(url='#15')
         except LinkNotFoundError:
             self.fail("Oops, when split by collection is on, "
                       "a link to Multimedia & Arts should be found.")
 
 class WebSearchSortResultsTest(unittest.TestCase):
     """Test of the search results page's sorting capability."""
 
     def test_sort_results_default(self):
         """websearch - search results sorting, default method"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=of&f=title&rg=1',
                                                expected_text="CMS animation of the high-energy collisions"))
 
     def test_sort_results_ascending(self):
         """websearch - search results sorting, ascending field"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=of&f=title&rg=2&sf=reportnumber&so=a',
                                                expected_text="[astro-ph/0104076]"))
 
     def test_sort_results_descending(self):
         """websearch - search results sorting, descending field"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=of&f=title&rg=1&sf=reportnumber&so=d',
                                                expected_text=" [TESLA-FEL-99-07]"))
 
     def test_sort_results_sort_pattern(self):
         """websearch - search results sorting, preferential sort pattern"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=of&f=title&rg=1&sf=reportnumber&so=d&sp=cern',
                                                expected_text="[CERN-TH-2002-069]"))
 
 class WebSearchSearchResultsXML(unittest.TestCase):
     """Test search results in various output"""
 
     def test_search_results_xm_output_split_on(self):
         """ websearch - check document element of search results in xm output (split by collection on)"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/search?sc=1&of=xm')
         body = browser.response().read()
 
         num_doc_element = body.count("<collection "
                                      "xmlns=\"http://www.loc.gov/MARC21/slim\">")
         if num_doc_element == 0:
             self.fail("Oops, no document element <collection "
                       "xmlns=\"http://www.loc.gov/MARC21/slim\">"
                       "found in search results.")
         elif num_doc_element > 1:
             self.fail("Oops, multiple document elements <collection> "
                       "found in search results.")
 
         num_doc_element = body.count("</collection>")
         if num_doc_element == 0:
             self.fail("Oops, no document element </collection> "
                       "found in search results.")
         elif num_doc_element > 1:
             self.fail("Oops, multiple document elements </collection> "
                       "found in search results.")
 
 
     def test_search_results_xm_output_split_off(self):
         """ websearch - check document element of search results in xm output (split by collection off)"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/search?sc=0&of=xm')
         body = browser.response().read()
 
         num_doc_element = body.count("<collection "
                                      "xmlns=\"http://www.loc.gov/MARC21/slim\">")
         if num_doc_element == 0:
             self.fail("Oops, no document element <collection "
                       "xmlns=\"http://www.loc.gov/MARC21/slim\">"
                       "found in search results.")
         elif num_doc_element > 1:
             self.fail("Oops, multiple document elements <collection> "
                       "found in search results.")
 
         num_doc_element = body.count("</collection>")
         if num_doc_element == 0:
             self.fail("Oops, no document element </collection> "
                       "found in search results.")
         elif num_doc_element > 1:
             self.fail("Oops, multiple document elements </collection> "
                       "found in search results.")
 
     def test_search_results_xd_output_split_on(self):
         """ websearch - check document element of search results in xd output (split by collection on)"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/search?sc=1&of=xd')
         body = browser.response().read()
 
         num_doc_element = body.count("<collection")
         if num_doc_element == 0:
             self.fail("Oops, no document element <collection "
                       "xmlns=\"http://www.loc.gov/MARC21/slim\">"
                       "found in search results.")
         elif num_doc_element > 1:
             self.fail("Oops, multiple document elements <collection> "
                       "found in search results.")
 
         num_doc_element = body.count("</collection>")
         if num_doc_element == 0:
             self.fail("Oops, no document element </collection> "
                       "found in search results.")
         elif num_doc_element > 1:
             self.fail("Oops, multiple document elements </collection> "
                       "found in search results.")
 
 
     def test_search_results_xd_output_split_off(self):
         """ websearch - check document element of search results in xd output (split by collection off)"""
         browser = Browser()
         browser.open(CFG_SITE_URL + '/search?sc=0&of=xd')
         body = browser.response().read()
 
         num_doc_element = body.count("<collection>")
         if num_doc_element == 0:
             self.fail("Oops, no document element <collection "
                       "xmlns=\"http://www.loc.gov/MARC21/slim\">"
                       "found in search results.")
         elif num_doc_element > 1:
             self.fail("Oops, multiple document elements <collection> "
                       "found in search results.")
 
         num_doc_element = body.count("</collection>")
         if num_doc_element == 0:
             self.fail("Oops, no document element </collection> "
                       "found in search results.")
         elif num_doc_element > 1:
             self.fail("Oops, multiple document elements </collection> "
                       "found in search results.")
 
 class WebSearchUnicodeQueryTest(unittest.TestCase):
     """Test of the search results for queries containing Unicode characters."""
 
     def test_unicode_word_query(self):
         """websearch - Unicode word query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=title%3A%CE%99%CE%B8%CE%AC%CE%BA%CE%B7',
                                                expected_text="[76]"))
 
     def test_unicode_word_query_not_found_term(self):
         """websearch - Unicode word query, not found term"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=title%3A%CE%99%CE%B8',
                                                expected_text="ιθάκη"))
 
     def test_unicode_exact_phrase_query(self):
         """websearch - Unicode exact phrase query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=title%3A%22%CE%99%CE%B8%CE%AC%CE%BA%CE%B7%22',
                                                expected_text="[76]"))
 
     def test_unicode_partial_phrase_query(self):
         """websearch - Unicode partial phrase query"""
         # no hit here for example title partial phrase query due to
         # removed difference between double-quoted and single-quoted
         # search:
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=title%3A%27%CE%B7%27',
                                                expected_text="[]"))
 
     def test_unicode_regexp_query(self):
         """websearch - Unicode regexp query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=title%3A%2F%CE%B7%2F',
                                                expected_text="[76]"))
 
 class WebSearchMARCQueryTest(unittest.TestCase):
     """Test of the search results for queries containing physical MARC tags."""
 
     def test_single_marc_tag_exact_phrase_query(self):
         """websearch - single MARC tag, exact phrase query (100__a)"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=100__a%3A%22Ellis%2C+J%22',
                                                expected_text="[9, 14, 18]"))
 
     def test_single_marc_tag_partial_phrase_query(self):
         """websearch - single MARC tag, partial phrase query (245__b)"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=245__b%3A%27and%27',
                                                expected_text="[28]"))
 
     def test_many_marc_tags_partial_phrase_query(self):
         """websearch - many MARC tags, partial phrase query (245)"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=245%3A%27and%27&rg=100',
                                                expected_text="[1, 8, 9, 14, 15, 20, 22, 24, 28, 33, 47, 48, 49, 51, 53, 64, 69, 71, 79, 82, 83, 85, 91, 96]"))
 
     def test_single_marc_tag_regexp_query(self):
         """websearch - single MARC tag, regexp query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=245%3A%2Fand%2F&rg=100',
                                                expected_text="[1, 8, 9, 14, 15, 20, 22, 24, 28, 33, 47, 48, 49, 51, 53, 64, 69, 71, 79, 82, 83, 85, 91, 96]"))
 
 class WebSearchExtSysnoQueryTest(unittest.TestCase):
     """Test of queries using external system numbers."""
 
     def test_existing_sysno_html_output(self):
         """websearch - external sysno query, existing sysno, HTML output"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?sysno=000289446CER',
                                                expected_text="The wall of the cave"))
 
     def test_existing_sysno_id_output(self):
         """websearch - external sysno query, existing sysno, ID output"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?sysno=000289446CER&of=id',
                                                expected_text="[95]"))
 
     def test_nonexisting_sysno_html_output(self):
         """websearch - external sysno query, non-existing sysno, HTML output"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?sysno=000289446CERRRR',
                                                expected_text="Requested record does not seem to exist."))
 
     def test_nonexisting_sysno_id_output(self):
         """websearch - external sysno query, non-existing sysno, ID output"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?sysno=000289446CERRRR&of=id',
                                                expected_text="[]"))
 
 class WebSearchResultsRecordGroupingTest(unittest.TestCase):
     """Test search results page record grouping (rg)."""
 
     def test_search_results_rg_guest(self):
         """websearch - search results, records in groups of, guest"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?rg=17',
                                                expected_text="1 - 17"))
 
     def test_search_results_rg_nonguest(self):
         """websearch - search results, records in groups of, non-guest"""
         # This test used to fail due to saved user preference fetching
         # not overridden by URL rg argument.
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?rg=17',
                                                username='admin',
                                                expected_text="1 - 17"))
 
 class WebSearchSpecialTermsQueryTest(unittest.TestCase):
     """Test of the search results for queries containing special terms."""
 
     def test_special_terms_u1(self):
         """websearch - query for special terms, U(1)"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=U%281%29',
                                                expected_text="[57, 79, 80, 88]"))
 
     def test_special_terms_u1_and_sl(self):
         """websearch - query for special terms, U(1) SL(2,Z)"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=U%281%29+SL%282%2CZ%29',
                                                expected_text="[88]"))
 
     def test_special_terms_u1_and_sl_or(self):
         """websearch - query for special terms, U(1) OR SL(2,Z)"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=U%281%29+OR+SL%282%2CZ%29',
                                                expected_text="[57, 79, 80, 88]"))
 
+    @nottest
     def FIXME_TICKET_453_test_special_terms_u1_and_sl_or_parens(self):
         """websearch - query for special terms, (U(1) OR SL(2,Z))"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=%28U%281%29+OR+SL%282%2CZ%29%29',
                                                expected_text="[57, 79, 80, 88]"))
 
     def test_special_terms_u1_and_sl_in_quotes(self):
         """websearch - query for special terms, ('SL(2,Z)' OR 'U(1)')"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + "/search?of=id&p=%28%27SL%282%2CZ%29%27+OR+%27U%281%29%27%29",
                                                expected_text="[57, 79, 80, 88, 96]"))
 
 
 class WebSearchJournalQueryTest(unittest.TestCase):
     """Test of the search results for journal pubinfo queries."""
 
     def test_query_journal_title_only(self):
         """websearch - journal publication info query, title only"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&f=journal&p=Phys.+Lett.+B',
                                                expected_text="[77, 78, 85, 87]"))
 
     def test_query_journal_full_pubinfo(self):
         """websearch - journal publication info query, full reference"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&f=journal&p=Phys.+Lett.+B+531+%282002%29+301',
                                                expected_text="[78]"))
 
 class WebSearchStemmedIndexQueryTest(unittest.TestCase):
     """Test of the search results for queries using stemmed indexes."""
 
     def test_query_stemmed_lowercase(self):
         """websearch - stemmed index query, lowercase"""
         # note that dasse/Dasse is stemmed into dass/Dass, as expected
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=dasse',
                                                expected_text="[25, 26]"))
 
     def test_query_stemmed_uppercase(self):
         """websearch - stemmed index query, uppercase"""
         # ... but note also that DASSE is stemmed into DASSE(!); so
         # the test would fail if the search engine would not lower the
         # query term.  (Something that is not necessary for
         # non-stemmed indexes.)
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?of=id&p=DASSE',
                                                expected_text="[25, 26]"))
 
 class WebSearchSummarizerTest(unittest.TestCase):
     """Test of the search results summarizer functions."""
 
     def test_most_popular_field_values_singletag(self):
         """websearch - most popular field values, simple tag"""
         from invenio.search_engine import get_most_popular_field_values
         self.assertEqual((('PREPRINT', 37), ('ARTICLE', 28), ('BOOK', 14), ('THESIS', 8), ('PICTURE', 7), ('POETRY', 2), ('REPORT', 2),  ('ATLANTISTIMESNEWS', 1)),
                          get_most_popular_field_values(range(0,100), '980__a'))
 
     def test_most_popular_field_values_singletag_multiexclusion(self):
         """websearch - most popular field values, simple tag, multiple exclusions"""
         from invenio.search_engine import get_most_popular_field_values
         self.assertEqual((('PREPRINT', 37), ('ARTICLE', 28), ('BOOK', 14), ('REPORT', 2), ('ATLANTISTIMESNEWS', 1)),
                          get_most_popular_field_values(range(0,100), '980__a', ('THESIS', 'PICTURE', 'POETRY')))
 
     def test_most_popular_field_values_multitag(self):
         """websearch - most popular field values, multiple tags"""
         from invenio.search_engine import get_most_popular_field_values
         self.assertEqual((('Ellis, J', 3), ('Enqvist, K', 1), ('Ibanez, L E', 1), ('Nanopoulos, D V', 1), ('Ross, G G', 1)),
                          get_most_popular_field_values((9, 14, 18), ('100__a', '700__a')))
 
     def test_most_popular_field_values_multitag_singleexclusion(self):
         """websearch - most popular field values, multiple tags, single exclusion"""
         from invenio.search_engine import get_most_popular_field_values
         self.assertEqual((('Enqvist, K', 1), ('Ibanez, L E', 1), ('Nanopoulos, D V', 1), ('Ross, G G', 1)),
                          get_most_popular_field_values((9, 14, 18), ('100__a', '700__a'), ('Ellis, J')))
 
     def test_most_popular_field_values_multitag_countrepetitive(self):
         """websearch - most popular field values, multiple tags, counting repetitive occurrences"""
         from invenio.search_engine import get_most_popular_field_values
         self.assertEqual((('THESIS', 2), ('REPORT', 1)),
                          get_most_popular_field_values((41,), ('690C_a', '980__a'), count_repetitive_values=True))
         self.assertEqual((('REPORT', 1), ('THESIS', 1)),
                          get_most_popular_field_values((41,), ('690C_a', '980__a'), count_repetitive_values=False))
 
     def test_ellis_citation_summary(self):
         """websearch - query ellis, citation summary output format"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=hcs',
                                                expected_text="Less known papers (1-9)",
                                                expected_link_target=CFG_SITE_URL+"/search?p=ellis%20AND%20cited%3A1-%3E9",
                                                expected_link_label='1'))
 
     def test_ellis_not_quark_citation_summary_advanced(self):
         """websearch - ellis and not quark, citation summary format advanced"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?ln=en&as=1&m1=a&p1=ellis&f1=author&op1=n&m2=a&p2=quark&f2=&op2=a&m3=a&p3=&f3=&action_search=Search&sf=&so=a&rm=&rg=10&sc=1&of=hcs',
                                                expected_text="Less known papers (1-9)",
                                                expected_link_target=CFG_SITE_URL+'/search?p=author%3Aellis%20and%20not%20quark%20AND%20cited%3A1-%3E9',
                                                expected_link_label='1'))
 
     def test_ellis_not_quark_citation_summary_regular(self):
         """websearch - ellis and not quark, citation summary format advanced"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=author%3Aellis+and+not+quark&f=&action_search=Search&sf=&so=d&rm=&rg=10&sc=0&of=hcs',
                                                expected_text="Less known papers (1-9)",
                                                expected_link_target=CFG_SITE_URL+'/search?p=author%3Aellis%20and%20not%20quark%20AND%20cited%3A1-%3E9',
                                                expected_link_label='1'))
 
     def test_compute_self_citations(self):
         """websearch - computing self-citations"""
         tags = search_engine_summarizer.get_authors_tags()
         recids = [row[0] for row in run_sql('select id from bibrec limit 300')]
         citers = search_engine_summarizer.get_cited_by_list(recids)
         authors_cache = {}
         total_citations = sum(len(lciters) for recid,lciters in citers)
         total_citations_minus_self_citations = 0
         for recid, lciters in citers:
             total_citations_minus_self_citations += \
                 search_engine_summarizer.compute_self_citations(recid,
                                                                 lciters,
                                                                 authors_cache,
                                                                 tags)
         self.assert_(total_citations_minus_self_citations < total_citations)
 
 
 class WebSearchRecordCollectionGuessTest(unittest.TestCase):
     """Primary collection guessing tests."""
 
     def test_guess_primary_collection_of_a_record(self):
         """websearch - guess_primary_collection_of_a_record"""
         self.assertEqual(guess_primary_collection_of_a_record(96), 'Articles')
 
     def test_guess_collection_of_a_record(self):
         """websearch - guess_collection_of_a_record"""
         self.assertEqual(guess_collection_of_a_record(96), 'Articles')
         self.assertEqual(guess_collection_of_a_record(96, '%s/collection/Theoretical Physics (TH)?ln=en' % CFG_SITE_URL), 'Articles')
         self.assertEqual(guess_collection_of_a_record(12, '%s/collection/Theoretical Physics (TH)?ln=en' % CFG_SITE_URL), 'Theoretical Physics (TH)')
         self.assertEqual(guess_collection_of_a_record(12, '%s/collection/Theoretical%%20Physics%%20%%28TH%%29?ln=en' % CFG_SITE_URL), 'Theoretical Physics (TH)')
 
 class WebSearchGetFieldValuesTest(unittest.TestCase):
     """Testing get_fieldvalues() function."""
 
     def test_get_fieldvalues_001(self):
         """websearch - get_fieldvalues() for bibxxx-agnostic tags"""
         self.assertEqual(get_fieldvalues(10, '001___'), ['10'])
 
     def test_get_fieldvalues_980(self):
         """websearch - get_fieldvalues() for bibxxx-powered tags"""
         self.assertEqual(get_fieldvalues(18, '700__a'), ['Enqvist, K', 'Nanopoulos, D V'])
         self.assertEqual(get_fieldvalues(18, '909C1u'), ['CERN'])
 
     def test_get_fieldvalues_wildcard(self):
         """websearch - get_fieldvalues() for tag wildcards"""
         self.assertEqual(get_fieldvalues(18, '%'), [])
         self.assertEqual(get_fieldvalues(18, '7%'), [])
         self.assertEqual(get_fieldvalues(18, '700%'), ['Enqvist, K', 'Nanopoulos, D V'])
         self.assertEqual(get_fieldvalues(18, '909C0%'), ['1985', '13','TH'])
 
     def test_get_fieldvalues_recIDs(self):
         """websearch - get_fieldvalues() for list of recIDs"""
         self.assertEqual(get_fieldvalues([], '001___'), [])
         self.assertEqual(get_fieldvalues([], '700__a'), [])
         self.assertEqual(get_fieldvalues([10, 13], '001___'), ['10', '13'])
         self.assertEqual(get_fieldvalues([18, 13], '700__a'),
                          ['Dawson, S', 'Ellis, R K', 'Enqvist, K', 'Nanopoulos, D V'])
 
     def test_get_fieldvalues_repetitive(self):
         """websearch - get_fieldvalues() for repetitive values"""
         self.assertEqual(get_fieldvalues([17, 18], '909C1u'),
                          ['CERN', 'CERN'])
         self.assertEqual(get_fieldvalues([17, 18], '909C1u', repetitive_values=True),
                          ['CERN', 'CERN'])
         self.assertEqual(get_fieldvalues([17, 18], '909C1u', repetitive_values=False),
                          ['CERN'])
 
 class WebSearchAddToBasketTest(unittest.TestCase):
     """Test of the add-to-basket presence depending on user rights."""
 
     def test_add_to_basket_guest(self):
         """websearch - add-to-basket facility allowed for guests"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10',
                                                expected_text='Add to basket'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10',
                                                expected_text='<input name="recid" type="checkbox" value="10" />'))
 
     def test_add_to_basket_jekyll(self):
         """websearch - add-to-basket facility allowed for Dr. Jekyll"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10',
                                                expected_text='Add to basket',
                                                username='jekyll',
                                                password='j123ekyll'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10',
                                                expected_text='<input name="recid" type="checkbox" value="10" />',
                                                username='jekyll',
                                                password='j123ekyll'))
 
     def test_add_to_basket_hyde(self):
         """websearch - add-to-basket facility denied to Mr. Hyde"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10',
                                                unexpected_text='Add to basket',
                                                username='hyde',
                                                password='h123yde'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10',
                                                unexpected_text='<input name="recid" type="checkbox" value="10" />',
                                                username='hyde',
                                                password='h123yde'))
 
 class WebSearchAlertTeaserTest(unittest.TestCase):
     """Test of the alert teaser presence depending on user rights."""
 
     def test_alert_teaser_guest(self):
         """websearch - alert teaser allowed for guests"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis',
                                                expected_link_label='email alert'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis',
                                                expected_text='RSS feed'))
 
     def test_alert_teaser_jekyll(self):
         """websearch - alert teaser allowed for Dr. Jekyll"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis',
                                                expected_text='email alert',
                                                username='jekyll',
                                                password='j123ekyll'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis',
                                                expected_text='RSS feed',
                                                username='jekyll',
                                                password='j123ekyll'))
 
     def test_alert_teaser_hyde(self):
         """websearch - alert teaser allowed for Mr. Hyde"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis',
                                                expected_text='email alert',
                                                username='hyde',
                                                password='h123yde'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=ellis',
                                                expected_text='RSS feed',
                                                username='hyde',
                                                password='h123yde'))
 
 
 class WebSearchSpanQueryTest(unittest.TestCase):
     """Test of span queries."""
 
     def test_span_in_word_index(self):
         """websearch - span query in a word index"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=year%3A1992-%3E1996&of=id&ap=0',
                                                expected_text='[17, 66, 69, 71]'))
 
     def test_span_in_phrase_index(self):
         """websearch - span query in a phrase index"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=year%3A%221992%22-%3E%221996%22&of=id&ap=0',
                                                expected_text='[17, 66, 69, 71]'))
 
     def test_span_in_bibxxx(self):
         """websearch - span query in MARC tables"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=909C0y%3A%221992%22-%3E%221996%22&of=id&ap=0',
                                                expected_text='[17, 66, 69, 71]'))
 
     def test_span_with_spaces(self):
         """websearch - no span query when a space is around"""
         # useful for reaction search
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=title%3A%27mu%20--%3E%20e%27&of=id&ap=0',
                                                expected_text='[67]'))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=245%3A%27mu%20--%3E%20e%27&of=id&ap=0',
                                                expected_text='[67]'))
 
     def test_span_in_author(self):
         """websearch - span query in special author index"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=author%3A%22Ellis,%20K%22-%3E%22Ellis,%20RZ%22&of=id&ap=0',
                                                expected_text='[8, 11, 13, 17, 47]'))
 
 
 class WebSearchReferstoCitedbyTest(unittest.TestCase):
     """Test of refersto/citedby search operators."""
 
     def test_refersto_recid(self):
         'websearch - refersto:recid:84'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Arecid%3A84&of=id&ap=0',
                                                expected_text='[85, 88, 91]'))
 
     def test_refersto_repno(self):
         'websearch - refersto:reportnumber:hep-th/0205061'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Areportnumber%3Ahep-th/0205061&of=id&ap=0',
                                                expected_text='[91]'))
 
     def test_refersto_author_word(self):
         'websearch - refersto:author:klebanov'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Aauthor%3Aklebanov&of=id&ap=0',
                                                expected_text='[85, 86, 88, 91]'))
 
     def test_refersto_author_phrase(self):
         'websearch - refersto:author:"Klebanov, I"'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Aauthor%3A%22Klebanov,%20I%22&of=id&ap=0',
                                                expected_text='[85, 86, 88, 91]'))
 
     def test_citedby_recid(self):
         'websearch - citedby:recid:92'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Arecid%3A92&of=id&ap=0',
                                                expected_text='[74, 91]'))
 
     def test_citedby_repno(self):
         'websearch - citedby:reportnumber:hep-th/0205061'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Areportnumber%3Ahep-th/0205061&of=id&ap=0',
                                                expected_text='[78]'))
 
     def test_citedby_author_word(self):
         'websearch - citedby:author:klebanov'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Aauthor%3Aklebanov&of=id&ap=0',
                                                expected_text='[95]'))
 
     def test_citedby_author_phrase(self):
         'websearch - citedby:author:"Klebanov, I"'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Aauthor%3A%22Klebanov,%20I%22&of=id&ap=0',
                                                expected_text='[95]'))
 
     def test_refersto_bad_query(self):
         'websearch - refersto:title:'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Atitle%3A',
                                                expected_text='There are no records referring to title:.'))
 
     def test_citedby_bad_query(self):
         'websearch - citedby:title:'
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Atitle%3A',
                                                expected_text='There are no records cited by title:.'))
 
 
 class WebSearchSPIRESSyntaxTest(unittest.TestCase):
     """Test of SPIRES syntax issues"""
 
     if CFG_WEBSEARCH_SPIRES_SYNTAX > 0:
         def test_and_not_parens(self):
             'websearch - find a ellis, j and not a enqvist'
             self.assertEqual([],
                              test_web_page_content(CFG_SITE_URL +'/search?p=find+a+ellis%2C+j+and+not+a+enqvist&of=id&ap=0',
                                                    expected_text='[9, 12, 14, 47]'))
 
         def test_dadd_search(self):
             'websearch - find da > today - 3650'
             # XXX: assumes we've reinstalled our site in the last 10 years
             # should return every document in the system
             self.assertEqual([],
                              test_web_page_content(CFG_SITE_URL +'/search?ln=en&p=find+da+%3E+today+-+3650&f=&of=id',
                                                    expected_text='[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 107]'))
 
 
 class WebSearchDateQueryTest(unittest.TestCase):
     """Test various date queries."""
 
     def setUp(self):
         """Establish variables we plan to re-use"""
         from invenio.intbitset import intbitset
         self.empty = intbitset()
 
     def test_search_unit_hits_for_datecreated_previous_millenia(self):
         """websearch - search_unit with datecreated returns >0 hits for docs in the last 1000 years"""
         self.assertNotEqual(self.empty, search_unit('1000-01-01->9999-12-31', 'datecreated'))
 
     def test_search_unit_hits_for_datemodified_previous_millenia(self):
         """websearch - search_unit with datemodified returns >0 hits for docs in the last 1000 years"""
         self.assertNotEqual(self.empty, search_unit('1000-01-01->9999-12-31', 'datemodified'))
 
     def test_search_unit_in_bibrec_for_datecreated_previous_millenia(self):
         """websearch - search_unit_in_bibrec with creationdate gets >0 hits for past 1000 years"""
         self.assertNotEqual(self.empty, search_unit_in_bibrec("1000-01-01", "9999-12-31", 'creationdate'))
 
     def test_search_unit_in_bibrec_for_datecreated_next_millenia(self):
         """websearch - search_unit_in_bibrec with creationdate gets 0 hits for after year 3000"""
         self.assertEqual(self.empty, search_unit_in_bibrec("3000-01-01", "9999-12-31", 'creationdate'))
 
 
 class WebSearchSynonymQueryTest(unittest.TestCase):
     """Test of queries using synonyms."""
 
     def test_journal_phrvd(self):
         """websearch - search-time synonym search, journal title"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=PHRVD&f=journal&of=id',
                                                expected_text="[66, 72]"))
 
     def test_journal_phrvd_54_1996_4234(self):
         """websearch - search-time synonym search, journal article"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=PHRVD%2054%20%281996%29%204234&f=journal&of=id',
                                                expected_text="[66]"))
 
     def test_journal_beta_decay_title(self):
         """websearch - index-time synonym search, beta decay in title"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=beta+decay&f=title&of=id',
                                                expected_text="[59]"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%CE%B2+decay&f=title&of=id',
                                                expected_text="[59]"))
 
     def test_journal_beta_decay_global(self):
         """websearch - index-time synonym search, beta decay in any field"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=beta+decay&of=id',
                                                expected_text="[52, 59]"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%CE%B2+decay&of=id',
                                                expected_text="[52, 59]"))
 
     def test_journal_beta_title(self):
         """websearch - index-time synonym search, beta in title"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=beta&f=title&of=id',
                                                expected_text="[59]"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%CE%B2&f=title&of=id',
                                                expected_text="[59]"))
 
     def test_journal_beta_global(self):
         """websearch - index-time synonym search, beta in any field"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=beta&of=id',
                                                expected_text="[52, 59]"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%CE%B2&of=id',
                                                expected_text="[52, 59]"))
 
 class WebSearchWashCollectionsTest(unittest.TestCase):
     """Test if the collection argument is washed correctly"""
 
     def test_wash_coll_when_coll_restricted(self):
         """websearch - washing of restricted daughter collections"""
         self.assertEqual(
             sorted(wash_colls(cc='', c=['Books & Reports', 'Theses'])[1]),
             ['Books & Reports', 'Theses'])
         self.assertEqual(
             sorted(wash_colls(cc='', c=['Books & Reports', 'Theses'])[2]),
             ['Books & Reports', 'Theses'])
 
 
 class WebSearchAuthorCountQueryTest(unittest.TestCase):
     """Test of queries using authorcount fields."""
 
     def test_journal_authorcount_word(self):
         """websearch - author count, word query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=4&f=authorcount&of=id',
                                                expected_text="[51, 54, 59, 66, 92, 96]"))
 
     def test_journal_authorcount_phrase(self):
         """websearch - author count, phrase query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=%224%22&f=authorcount&of=id',
                                                expected_text="[51, 54, 59, 66, 92, 96]"))
 
     def test_journal_authorcount_span(self):
         """websearch - author count, span query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=authorcount%3A9-%3E16&of=id',
                                                expected_text="[69, 71]"))
 
     def test_journal_authorcount_plus(self):
         """websearch - author count, plus query"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/search?p=50%2B&f=authorcount&of=id',
                                                expected_text="[10, 17]"))
 
 TEST_SUITE = make_test_suite(WebSearchWebPagesAvailabilityTest,
                              WebSearchTestSearch,
                              WebSearchTestBrowse,
                              WebSearchTestOpenURL,
                              WebSearchTestCollections,
                              WebSearchTestRecord,
                              WebSearchTestLegacyURLs,
                              WebSearchNearestTermsTest,
                              WebSearchBooleanQueryTest,
                              WebSearchAuthorQueryTest,
                              WebSearchSearchEnginePythonAPITest,
                              WebSearchSearchEngineWebAPITest,
                              WebSearchRestrictedCollectionTest,
                              WebSearchRestrictedPicturesTest,
                              WebSearchRestrictedWebJournalFilesTest,
                              WebSearchRSSFeedServiceTest,
                              WebSearchXSSVulnerabilityTest,
                              WebSearchResultsOverview,
                              WebSearchSortResultsTest,
                              WebSearchSearchResultsXML,
                              WebSearchUnicodeQueryTest,
                              WebSearchMARCQueryTest,
                              WebSearchExtSysnoQueryTest,
                              WebSearchResultsRecordGroupingTest,
                              WebSearchSpecialTermsQueryTest,
                              WebSearchJournalQueryTest,
                              WebSearchStemmedIndexQueryTest,
                              WebSearchSummarizerTest,
                              WebSearchRecordCollectionGuessTest,
                              WebSearchGetFieldValuesTest,
                              WebSearchAddToBasketTest,
                              WebSearchAlertTeaserTest,
                              WebSearchSpanQueryTest,
                              WebSearchReferstoCitedbyTest,
                              WebSearchSPIRESSyntaxTest,
                              WebSearchDateQueryTest,
                              WebSearchTestWildcardLimit,
                              WebSearchSynonymQueryTest,
                              WebSearchWashCollectionsTest,
                              WebSearchAuthorCountQueryTest)
 
 if __name__ == "__main__":
     run_test_suite(TEST_SUITE, warn_user=True)
diff --git a/modules/websubmit/lib/websubmit_regression_tests.py b/modules/websubmit/lib/websubmit_regression_tests.py
index c0c7f233a..fe7384edf 100644
--- a/modules/websubmit/lib/websubmit_regression_tests.py
+++ b/modules/websubmit/lib/websubmit_regression_tests.py
@@ -1,268 +1,268 @@
 # -*- coding: utf-8 -*-
 ##
 ## This file is part of Invenio.
-## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 CERN.
+## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013 CERN.
 ##
 ## Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 """WebSubmit Regression Test Suite."""
 
 __revision__ = "$Id$"
 
 import unittest
 import os
 from logging import StreamHandler, DEBUG
 from cStringIO import StringIO
 
 from invenio.websubmit_file_converter import get_file_converter_logger
 from invenio.errorlib import register_exception
 from invenio.config import CFG_SITE_URL, CFG_PREFIX, CFG_TMPDIR
 from invenio.testutils import make_test_suite, run_test_suite, \
                               test_web_page_content, merge_error_messages
 from invenio import websubmit_file_stamper
 
 class WebSubmitWebPagesAvailabilityTest(unittest.TestCase):
     """Check WebSubmit web pages whether they are up or not."""
 
     def test_submission_pages_availability(self):
         """websubmit - availability of submission pages"""
 
         baseurl = CFG_SITE_URL + '/submit/'
 
         _exports = ['', 'direct']
 
         error_messages = []
         for url in [baseurl + page for page in _exports]:
             error_messages.extend(test_web_page_content(url))
         if error_messages:
             self.fail(merge_error_messages(error_messages))
         return
 
     def test_publiline_pages_availability(self):
         """websubmit - availability of approval pages"""
 
         baseurl = CFG_SITE_URL
 
         _exports = ['/approve.py', '/publiline.py',
                     '/yourapprovals.py']
 
         error_messages = []
         for url in [baseurl + page for page in _exports]:
             error_messages.extend(test_web_page_content(url))
         if error_messages:
             self.fail(merge_error_messages(error_messages))
         return
 
     def test_your_submissions_pages_availability(self):
         """websubmit - availability of Your Submissions pages"""
 
         baseurl = CFG_SITE_URL
 
         _exports = ['/yoursubmissions.py']
 
         error_messages = []
         for url in [baseurl + page for page in _exports]:
             error_messages.extend(test_web_page_content(url))
         if error_messages:
             self.fail(merge_error_messages(error_messages))
         return
 
     def test_help_page_availability(self):
         """websubmit - availability of WebSubmit help page"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/submit-guide',
                                                expected_text="Submit Guide"))
 
 class WebSubmitLegacyURLsTest(unittest.TestCase):
     """ Check that the application still responds to legacy URLs"""
 
     def test_legacy_help_page_link(self):
         """websubmit - legacy Submit Guide page link"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/submit',
                                                expected_text="Submit Guide"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/submit/',
                                                expected_text="Submit Guide"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/submit/index.en.html',
                                               expected_text="Submit Guide"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/help/submit/access.en.html',
                                               expected_text="Submit Guide"))
 
 class WebSubmitXSSVulnerabilityTest(unittest.TestCase):
     """Test possible XSS vulnerabilities of the submission engine."""
 
     def test_xss_in_submission_doctype(self):
         """websubmit - no XSS vulnerability in doctype parameter"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/submit?doctype=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E',
                                                expected_text='Unable to find document type: &lt;SCRIPT&gt;alert("XSS")', username="jekyll",
                           password="j123ekyll"))
 
     def test_xss_in_submission_act(self):
         """websubmit - no XSS vulnerability in act parameter"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL + '/submit?doctype=DEMOTHE&access=1_1&act=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E',
                                                expected_text='Invalid doctype and act parameters', username="jekyll",
                           password="j123ekyll"))
 
     def test_xss_in_submission_page(self):
         """websubmit - no XSS vulnerability in access parameter"""
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL +
                           '/submit?doctype=DEMOTHE&access=/../../../etc/passwd&act=SBI&startPg=1&ln=en&ln=en',                                               expected_text='Invalid parameters', username="jekyll",
                           password="j123ekyll"))
         self.assertEqual([],
                          test_web_page_content(CFG_SITE_URL +
                           '/submit?doctype=DEMOTHE&access=%3CSCRIPT%3Ealert%28%22XSS%22%29%3B%3C%2FSCRIPT%3E&act=SBI',                                               expected_text='Invalid parameters', username="jekyll",
                           password="j123ekyll"))
 
 def WebSubmitFileConverterTestGenerator():
     from invenio.websubmit_file_converter import get_conversion_map, can_convert
     if can_convert('.odt', '.txt'):
         ## Special test for unoconv/LibreOffice
         yield WebSubmitFileConverterTest(os.path.join(CFG_PREFIX, 'lib', 'webtest', 'invenio', 'test.odt'), '.odt', '.txt')
     if can_convert('.doc', '.txt'):
         ## Special test for unoconv/LibreOffice
         yield WebSubmitFileConverterTest(os.path.join(CFG_PREFIX, 'lib', 'webtest', 'invenio', 'test.doc'), '.doc', '.txt')
     for from_format in get_conversion_map().keys():
         input_file = os.path.join(CFG_PREFIX, 'lib', 'webtest', 'invenio', 'test%s' % from_format)
         if not os.path.exists(input_file):
             ## Can't run such a test because there is no test example
             continue
         for to_format in get_conversion_map().keys():
             if from_format == to_format:
                 continue
             conversion_map = can_convert(from_format, to_format)
             if conversion_map:
                 if [converter for converter in conversion_map if converter[0].__name__ == 'unoconv']:
                     ## We don't want to test unoconv which is tested separately
                     continue
                 yield WebSubmitFileConverterTest(input_file, from_format, to_format)
 
 class WebSubmitFileConverterTest(unittest.TestCase):
     """Test WebSubmit file converter tool"""
 
     def __init__(self, input_file, from_format, to_format):
-        super(WebSubmitFileConverterTest, self).__init__('runTest')
+        super(WebSubmitFileConverterTest, self).__init__('_run_test')
         self.from_format = from_format
         self.to_format = to_format
         self.input_file = input_file
 
     def setUp(self):
         logger = get_file_converter_logger()
         self.log = StringIO()
         logger.setLevel(DEBUG)
         for handler in logger.handlers:
             logger.removeHandler(handler)
         handler = StreamHandler(self.log)
         handler.setLevel(DEBUG)
         logger.addHandler(handler)
 
 
     def shortDescription(self):
         return """websubmit - test %s to %s conversion""" % (self.from_format, self.to_format)
 
-    def runTest(self):
+    def _run_test(self):
         from invenio.websubmit_file_converter import InvenioWebSubmitFileConverterError, convert_file
         try:
             tmpdir_snapshot1 = set(os.listdir(CFG_TMPDIR))
             output_file = convert_file(self.input_file, output_format=self.to_format)
             tmpdir_snapshot2 = set(os.listdir(CFG_TMPDIR))
             tmpdir_snapshot2.discard(os.path.basename(output_file))
             if not os.path.exists(output_file):
                 raise InvenioWebSubmitFileConverterError("output_file %s was not correctly created" % output_file)
             if tmpdir_snapshot2 - tmpdir_snapshot1:
                 raise InvenioWebSubmitFileConverterError("Some temporary files were left over: %s" % (tmpdir_snapshot2 - tmpdir_snapshot1))
         except Exception, err:
             register_exception(alert_admin=True)
             self.fail("ERROR: when converting from %s to %s: %s, the log contained: %s" % (self.from_format, self.to_format, err, self.log.getvalue()))
 
 class WebSubmitStampingTest(unittest.TestCase):
     """Test WebSubmit file stamping tool"""
 
     def test_stamp_coverpage(self):
         """websubmit - creation of a PDF cover page stamp (APIs)"""
         file_stamper_options = { 'latex-template'      : "demo-stamp-left.tex",
                                  'latex-template-var'  : {'REPORTNUMBER':'TEST-2010','DATE':'10/10/2000'},
                                  'input-file'          : CFG_PREFIX + "/lib/webtest/invenio/test.pdf",
                                  'output-file'         : "test-stamp-coverpage.pdf",
                                  'stamp'               : "coverpage",
                                  'layer'               : "foreground",
                                  'verbosity'           : 0,
                                  }
         try:
             (stamped_file_path_only, stamped_file_name) = \
                     websubmit_file_stamper.stamp_file(file_stamper_options)
         except:
             self.fail("Stamping failed")
 
         # Test that file is now bigger...
         assert os.path.getsize(os.path.join(stamped_file_path_only,
                                             stamped_file_name)) > 12695
 
     def test_stamp_firstpage(self):
         """websubmit - stamping first page of a PDF (APIs)"""
         file_stamper_options = { 'latex-template'      : "demo-stamp-left.tex",
                                  'latex-template-var'  : {'REPORTNUMBER':'TEST-2010','DATE':'10/10/2000'},
                                  'input-file'          : CFG_PREFIX + "/lib/webtest/invenio/test.pdf",
                                  'output-file'         : "test-stamp-firstpage.pdf",
                                  'stamp'               : "first",
                                  'layer'               : "background",
                                  'verbosity'           : 0,
                                  }
         try:
             (stamped_file_path_only, stamped_file_name) = \
                     websubmit_file_stamper.stamp_file(file_stamper_options)
         except:
             self.fail("Stamping failed")
 
         # Test that file is now bigger...
         assert os.path.getsize(os.path.join(stamped_file_path_only,
                                             stamped_file_name)) > 12695
 
     def test_stamp_allpages(self):
         """websubmit - stamping all pages of a PDF (APIs)"""
         file_stamper_options = { 'latex-template'      : "demo-stamp-left.tex",
                                  'latex-template-var'  : {'REPORTNUMBER':'TEST-2010','DATE':'10/10/2000'},
                                  'input-file'          : CFG_PREFIX + "/lib/webtest/invenio/test.pdf",
                                  'output-file'         : "test-stamp-allpages.pdf",
                                  'stamp'               : "all",
                                  'layer'               : "foreground",
                                  'verbosity'           : 0,
                                  }
         try:
             (stamped_file_path_only, stamped_file_name) = \
                     websubmit_file_stamper.stamp_file(file_stamper_options)
         except:
             self.fail("Stamping failed")
 
         # Test that file is now bigger...
         assert os.path.getsize(os.path.join(stamped_file_path_only,
                                             stamped_file_name)) > 12695
 
 
 TEST_SUITE = make_test_suite(WebSubmitWebPagesAvailabilityTest,
                              WebSubmitLegacyURLsTest,
                              WebSubmitXSSVulnerabilityTest,
                              WebSubmitStampingTest)
 
 for test in WebSubmitFileConverterTestGenerator():
     TEST_SUITE.addTest(test)
 
 if __name__ == "__main__":
     run_test_suite(TEST_SUITE, warn_user=True)