# HG changeset patch # User Marcin Kuzminski # Date 2010-09-12 23:23:58 # Node ID 6b934c9607e714b5f715edb3d507a7aa347e5e73 # Parent 91292686c1edb8dcf9e503a3e2f69930aabbc7cc Improved testing scenarios. Made test env creator Fixed hg_model error message some other tweeks and fixes Models fixe for uniq email, and removed some extra not needed imports from model main module diff --git a/pylons_app/config/environment.py b/pylons_app/config/environment.py --- a/pylons_app/config/environment.py +++ b/pylons_app/config/environment.py @@ -49,7 +49,10 @@ def load_environment(global_conf, app_co #sets the c attribute access when don't existing attribute are accessed config['pylons.strict_tmpl_context'] = True - test = os.path.split(config['__file__'])[-1] == 'tests.ini' + test = os.path.split(config['__file__'])[-1] == 'test.ini' + if test: + from pylons_app.lib.utils import make_test_env + make_test_env() #MULTIPLE DB configs # Setup the SQLAlchemy database engine if config['debug'] and not test: diff --git a/pylons_app/controllers/admin/settings.py b/pylons_app/controllers/admin/settings.py --- a/pylons_app/controllers/admin/settings.py +++ b/pylons_app/controllers/admin/settings.py @@ -106,7 +106,7 @@ class SettingsController(BaseController) if setting_id == 'whoosh': repo_location = get_hg_ui_settings()['paths_root_path'] full_index = request.POST.get('full_index',False) - task = run_task(tasks.whoosh_index,True,repo_location,full_index) + task = run_task(tasks.whoosh_index,repo_location,full_index) h.flash(_('Whoosh reindex task scheduled'), category='success') if setting_id == 'global': diff --git a/pylons_app/controllers/summary.py b/pylons_app/controllers/summary.py --- a/pylons_app/controllers/summary.py +++ b/pylons_app/controllers/summary.py @@ -61,7 +61,7 @@ class SummaryController(BaseController): for name, hash in c.repo_info.branches.items()[:10]: c.repo_branches[name] = c.repo_info.get_changeset(hash) - task = run_task(get_commits_stats,False,c.repo_info.name) + task = run_task(get_commits_stats,c.repo_info.name) c.ts_min = task.result[0] c.ts_max = task.result[1] c.commit_data = task.result[2] diff --git a/pylons_app/lib/utils.py b/pylons_app/lib/utils.py --- a/pylons_app/lib/utils.py +++ b/pylons_app/lib/utils.py @@ -16,6 +16,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. +import shutil """ Created on April 18, 2010 @@ -31,6 +32,8 @@ from vcs.backends.base import BaseChange from vcs.utils.lazy import LazyProperty import logging import os +from os.path import dirname as dn, join as jn +import tarfile log = logging.getLogger(__name__) @@ -362,3 +365,68 @@ class OrderedDict(dict, DictMixin): def __ne__(self, other): return not self == other + +def make_test_env(): + """Makes a fresh database from base64+zlib dump and + install test repository into tmp dir + """ + new_db_dump = """ +eJztXN1vE8sVn9nxR+wAIXDpFiiXjSAXfEOc2ElwQkVLPjYf5NNOAklUydrYG3tv1t5ldx0nuUJV\noL +cPrVr1X7jSfUJ96nMfK1Xty23VqlWlPlRIlahUXbXqFUL0pTNjx5614xAoKEDmJ3t2zpkzM2fO\neHe+ +zno+PqU5qrRmWDnFkXqAB0AIbkkSAKANf8+BKprwFzI0G28ECXQ+PufFEYT+Tehz6L/oaSnK\nwcFxGP +igFQfHjuMg4CehH7UA9Af0Y2ShWdSPLmOSg+N9x7U9eKf9PiC2nIWm4mTtri4nZ3Z9DE/5\nfOD0+RZY +VFdXFVstWHoXPOPFvDbKU3TdKCbNgp39GLZ5MPtKW5WtWKmstqFmtqVtzZRWt6NQRFjk\ngkhESJ6kbe +trim6rcFTAdcfuwqxhrNuprJLPqBnLKJhhSzWNpK1tq+aWkzXyN8wt3cjbScU0w7q2\nGqbyVSHYAXE5 +kSv15RTMtOKo2YxUikjf+SgKg4Dc/38C6Dn6Gn2FnqDH6K+Y5ODgeGfhRRD6/ST0\n+Ujo9ZLQ4yEhQi +QUBBJCeFy4BLywHaCfCEXM+AJHOWpx39sMrux4IbzQ3gMc1XaSlpop6IoVvRxV\nLke6L4/cmx7vjedG +4qmVmXvTW5nl7PDaSmFEXR6ejC+YVrpnsNi1fn17fHldj06p6YH84tzaGKBF\n5ZWcSq66Uorn8Iih5W +/ZBolqejhl5O57mkEPqf6sOFCq3lRsu2hYaayHrTplJeJD/Uu3p7u3Er19\nS4sb26PmemQiE54vLKfn +I8Wx2/Nd+XurmbH4TOpupHdk25I/sYbmCgDQstK0oHLdpWGmc1U3MqR6\nbICF123RHb/QDNpIm1rFnk +HaJiWd0/Llpgzq41lzIJMrjMXi2/JmdyGxMDKnjs1FR9WMcduMb3TZ\nfZuZTXVs1uiS53NxY9yan4Vw +PDNICqEl3dKNlKJnDdshbYh2R7o7uwc6I1EpGr3RHbvREwn3D/T3\nd/fuBFAzaHdpUu7csi6Tw4ou94 +zOLt3JxTNZo7g8muvV1Lg6sNj/SX4dD7srqenpfCJ6d3g5vKRM\njq/Ob3VHIXgJXaKx8PWBvoHrvfdg +MzhPVDl/vgek1TWloO927tbUdsqeNzfurK5Frq+v5NbHZ1bG\nCnZxdnxxbGStmOudnwub6+rQYNxZku +Wh28Ph9Nos2C3EfblVvhJlyPjvRY+Z8f91dzUHB8fhYf/x\nv3T/PwL47v87+iX6I45ycHC8dWhFV6Br +7ukVUQ/cYzroOYnaXZLoBGqD1TmW0IzOw/IUAJL9v6Dg\nA+jP6Ofo+yiBelFA+IvwC2EFMzmOCBJBD/ +huMZsJ41+MZjuqFVYKjpFUUo62oThqosyV8mpRKtg4\nUtScrJTNdCqmSeNGwZFIFqmcRTPydwIeMPwp +W2ZOyRcU/SVLLWViym1v8oDOLrbcvJGvFpbWbGVV\nV9NhvweEZCyWslRcWVnINGzNMawtiXJxaRX5kM +8D+rqq8lZFtjaX+i2vB1zoxKL0dhrPSHSmj6u3\nFCzV4cH6fbuavSTFFEJp3KCUatsdqEa4aGkOqyel +y8IhwQM6BhhhrE2akSVkWfQKxKJ9jGhN8/NG\nWZCM/0H0q5r9P/Q79FvM5ODgeOtBZvLBIAkDARI2Nb +3E/h/O7wdDAAzBj+Cy8IXwpfAc/eZlat9R\noF+8eBE+bHXIgzSbIQcTyYJWiQjDCXlwQZYWBoemZKnC +lq4GAwUtqaWliZkFeUxOSDOzC9LM4tTU\nNYmm2GqKPqEX5KWFMmtd3WLJDUUvqCyDjhKqNDQ7OyUPzh +DmXGJiejCxLE3Ky9JVWl2IsBdnJuKL\nMssZHpeHJymjXMjEjHS1+5oUCYWCoYjgE+WLEGj5tLpp39Px +MzlJhjtKJytNSkYqUfRgHPlFUYQ/\nMKhZyPhm08DjMgdlUVPgSENj4DSyN1hp6u6Er8Kob3hplGEYrg +J2dxsrDLrZ6EpO6kYGlzCCdV2Y\nmJbrjVlS2G1Ohlc2aJ012TSqozuJLYpoiK0f8vjEm2Ij61MLJiP0 +4g15XywapRffzpTPL166BB8k\naQeZqpXTbBv/4Gwm6nd1FpNAuqxKNuo4RsLdf1W+buQzrjSXkV1VuO +zjTgmG+vw+ceJSo5Yzmicj\nDNFE7n8BfQnQ33DAwcHxLqMFLxHEs47mkIGYrKM+xAsBMYZXBnquvLDC +D4Wsmne0FF3/kPm/gL6m\n8//DVp6Dg+PNo3b+7wOPAHgEH8F/CFfRT9GvD1u/vbFzv8kvdnTAhxF2nW +GrjqPlM3YNGdxrzbGb\nSOZuLN1o9uaScc3RXCnuVYhr+lZTi2sCd+C08iz4ZsAnxjtesAapZIrUMJpv +Bl8me7SGcfxBqtkv\ntrfDzwLU+pWdJU212fgJl93ZFGJ06qPWwNg0rWLkuuVPwxm2RfcS2YVOWrVTlm +a61o6uXimr4bJ4\npfp67r6So7MJeWJshhRcWf1ICXlUTsgzw/L87vpuj4XRrubsOjN2zCdOtjfqJNac +yQhLtcSOHzhj\nlKVOlsb/fwL0FAccHBzvLQJIhHRpIJAYXRPQ8R+i3wP84eDgeNfRCX3gAoRjGyk7Sc +78BUDPZdlJ\n0ZphSbvJZPyH6D8Afzg4ON5/HEMX4O7tD0v3/3OAPxwcHEcG1f0/hJ4A9Az9C184ODje +Q/gQ+WcP\nKPgEevX5IL0GyPiP0Fdl/7/D1pKDg+PNYe/3f+j4/wSP/88OWz8ODo43Ab+H3O0CKl19Qu +kaoPN/\nD/gcgM+FD4W7ws8OW886PNg+UTp4jlX8aJOOQR0a2XhrnVftbkrFubZM7+dkewA/zgYS9a6x +1erq\nXWRr0thDZLdfJ3uU7PI+rXcMfYWT6Bq33WtSrVNprGW/Y2VXUyIsdSp28sAZoyx1+kGulXqTfx +aq\ndrduZOxK5Ex9RxN2pZcx8So9XEozKw4D1Vdn6v0RFLdfeolM0r/U2d9buqRbvekZ/iv0IpulqrYr +\nl9sRo+rBEAyR+x8/ADg4OI4gyPyf3/8cHEcTJf+fpwB/ODg4jgSaoBfQ/QB+/s/BcSRR3f+H6Bng\n +e/8cHEcHpf1/CI+jHwEP3AToLtx8e9/9e//w8Hun6bHGDz+tvE+3uwfOxsW69+nYYw2WfjPHGtX9\n5A +MdfNQo9P+eS7youNdyVuJq4ot2zRsdnLgLCYYip/b7w5jKqUX51IREv4F/FJ7YBy96ja963sJS\n34yd +OXDGKEud/R8efZUt\n +""" + newdb = open('test.db','wb') + newdb.write(new_db_dump.decode('base64').decode('zlib')) + newdb.close() + + + #PART TWO make test repo + if os.path.isdir('/tmp/vcs_test'): + shutil.rmtree('/tmp/vcs_test') + + cur_dir = dn(dn(os.path.abspath(__file__))) + tar = tarfile.open(jn(cur_dir,'tests',"vcs_test.tar.gz")) + tar.extractall('/tmp') + tar.close() + + + \ No newline at end of file diff --git a/pylons_app/model/__init__.py b/pylons_app/model/__init__.py --- a/pylons_app/model/__init__.py +++ b/pylons_app/model/__init__.py @@ -1,15 +1,8 @@ """The application's model objects""" import logging -import sqlalchemy as sa -from sqlalchemy import orm from pylons_app.model import meta -from pylons_app.model.meta import Session log = logging.getLogger(__name__) -# Add these two imports: -import datetime -from sqlalchemy import schema, types - def init_model(engine): """Call me before using any of the tables or classes in the model""" log.info("INITIALIZING DB MODELS") diff --git a/pylons_app/model/db.py b/pylons_app/model/db.py --- a/pylons_app/model/db.py +++ b/pylons_app/model/db.py @@ -26,7 +26,7 @@ class HgAppUi(Base): class User(Base): __tablename__ = 'users' - __table_args__ = (UniqueConstraint('username'), {'useexisting':True}) + __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True}) user_id = Column("user_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) password = Column("password", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) @@ -56,7 +56,7 @@ class User(Base): self.last_login = datetime.datetime.now() session.add(self) session.commit() - log.debug('updated user %s lastlogin',self.username) + log.debug('updated user %s lastlogin', self.username) except Exception: session.rollback() diff --git a/pylons_app/model/hg_model.py b/pylons_app/model/hg_model.py --- a/pylons_app/model/hg_model.py +++ b/pylons_app/model/hg_model.py @@ -102,7 +102,7 @@ class HgModel(object): if repos_path[0] != '/': repos_path[0] = '/' if not os.path.isdir(os.path.join(*repos_path)): - raise RepositoryError('Not a valid repository in %s' % path[0][1]) + raise RepositoryError('Not a valid repository in %s' % path) if not repos_path.endswith('*'): raise VCSError('You need to specify * or ** at the end of path ' 'for recursive scanning') diff --git a/pylons_app/tests/__init__.py b/pylons_app/tests/__init__.py --- a/pylons_app/tests/__init__.py +++ b/pylons_app/tests/__init__.py @@ -16,12 +16,15 @@ from routes.util import URLGenerator from webtest import TestApp import os from pylons_app.model import meta +import logging +log = logging.getLogger(__name__) + import pylons.test __all__ = ['environ', 'url', 'TestController'] # Invoke websetup with the current config file -SetupCommand('setup-app').run([pylons.test.pylonsapp.config['__file__']]) +#SetupCommand('setup-app').run([pylons.test.pylonsapp.config['__file__']]) environ = {} @@ -42,4 +45,5 @@ class TestController(TestCase): 'password':'test'}) assert response.status == '302 Found', 'Wrong response code from login got %s' % response.status assert response.session['hg_app_user'].username == 'test_admin', 'wrong logged in user' - return response.follow() \ No newline at end of file + return response.follow() + \ No newline at end of file diff --git a/pylons_app/tests/functional/test_admin.py b/pylons_app/tests/functional/test_admin.py --- a/pylons_app/tests/functional/test_admin.py +++ b/pylons_app/tests/functional/test_admin.py @@ -3,5 +3,7 @@ from pylons_app.tests import * class TestAdminController(TestController): def test_index(self): + self.log_user() response = self.app.get(url(controller='admin/admin', action='index')) + assert 'Admin dashboard - journal' in response.body,'No proper title in dashboard' # Test response... diff --git a/pylons_app/tests/functional/test_branches.py b/pylons_app/tests/functional/test_branches.py --- a/pylons_app/tests/functional/test_branches.py +++ b/pylons_app/tests/functional/test_branches.py @@ -3,5 +3,6 @@ from pylons_app.tests import * class TestBranchesController(TestController): def test_index(self): + self.log_user() response = self.app.get(url(controller='branches', action='index',repo_name='vcs_test')) # Test response... diff --git a/pylons_app/tests/functional/test_changelog.py b/pylons_app/tests/functional/test_changelog.py --- a/pylons_app/tests/functional/test_changelog.py +++ b/pylons_app/tests/functional/test_changelog.py @@ -3,5 +3,6 @@ from pylons_app.tests import * class TestChangelogController(TestController): def test_index(self): + self.log_user() response = self.app.get(url(controller='changelog', action='index',repo_name='vcs_test')) # Test response... diff --git a/pylons_app/tests/functional/test_feed.py b/pylons_app/tests/functional/test_feed.py --- a/pylons_app/tests/functional/test_feed.py +++ b/pylons_app/tests/functional/test_feed.py @@ -3,11 +3,13 @@ from pylons_app.tests import * class TestFeedController(TestController): def test_rss(self): + self.log_user() response = self.app.get(url(controller='feed', action='rss', repo_name='vcs_test')) # Test response... def test_atom(self): + self.log_user() response = self.app.get(url(controller='feed', action='atom', repo_name='vcs_test')) # Test response... \ No newline at end of file diff --git a/pylons_app/tests/functional/test_files.py b/pylons_app/tests/functional/test_files.py --- a/pylons_app/tests/functional/test_files.py +++ b/pylons_app/tests/functional/test_files.py @@ -3,6 +3,7 @@ from pylons_app.tests import * class TestFilesController(TestController): def test_index(self): + self.log_user() response = self.app.get(url(controller='files', action='index', repo_name='vcs_test', revision='tip', diff --git a/pylons_app/tests/functional/test_login.py b/pylons_app/tests/functional/test_login.py --- a/pylons_app/tests/functional/test_login.py +++ b/pylons_app/tests/functional/test_login.py @@ -82,9 +82,9 @@ class TestLoginController(TestController def test_register_ok(self): - username = 'test_regular2' + username = 'test_regular4' password = 'qweqwe' - email = 'goodmail@mail.com' + email = 'marcin@somemail.com' name = 'testname' lastname = 'testlastname' @@ -94,10 +94,11 @@ class TestLoginController(TestController 'email':email, 'name':name, 'lastname':lastname}) - + print response.body assert response.status == '302 Found', 'Wrong response from register page got %s' % response.status + assert 'You have successfully registered into hg-app' in response.session['flash'][0], 'No flash message about user registration' - ret = self.sa.query(User).filter(User.username == 'test_regular2').one() + ret = self.sa.query(User).filter(User.username == 'test_regular4').one() assert ret.username == username , 'field mismatch %s %s' % (ret.username, username) assert check_password(password,ret.password) == True , 'password mismatch' assert ret.email == email , 'field mismatch %s %s' % (ret.email, email) @@ -105,7 +106,34 @@ class TestLoginController(TestController assert ret.lastname == lastname , 'field mismatch %s %s' % (ret.lastname, lastname) + def test_forgot_password_wrong_mail(self): + response = self.app.post(url(controller='login', action='password_reset'), + {'email':'marcin@wrongmail.org',}) + + assert "That e-mail address doesn't exist" in response.body,'Missing error message about wrong email' + + def test_forgot_password(self): + response = self.app.get(url(controller='login', action='password_reset')) + assert response.status == '200 OK', 'Wrong response from login page got %s' % response.status + + username = 'test_password_reset_1' + password = 'qweqwe' + email = 'marcin@python-works.com' + name = 'passwd' + lastname = 'reset' + + response = self.app.post(url(controller='login', action='register'), + {'username':username, + 'password':password, + 'email':email, + 'name':name, + 'lastname':lastname}) + #register new user for email test + response = self.app.post(url(controller='login', action='password_reset'), + {'email':email,}) + print response.session['flash'] + assert 'You have successfully registered into hg-app' in response.session['flash'][0], 'No flash message about user registration' + assert 'Your new password was sent' in response.session['flash'][1], 'No flash message about password reset' - diff --git a/pylons_app/tests/functional/test_settings.py b/pylons_app/tests/functional/test_settings.py --- a/pylons_app/tests/functional/test_settings.py +++ b/pylons_app/tests/functional/test_settings.py @@ -3,6 +3,7 @@ from pylons_app.tests import * class TestSettingsController(TestController): def test_index(self): + self.log_user() response = self.app.get(url(controller='settings', action='index', repo_name='vcs_test')) # Test response... diff --git a/pylons_app/tests/functional/test_shortlog.py b/pylons_app/tests/functional/test_shortlog.py --- a/pylons_app/tests/functional/test_shortlog.py +++ b/pylons_app/tests/functional/test_shortlog.py @@ -3,5 +3,6 @@ from pylons_app.tests import * class TestShortlogController(TestController): def test_index(self): + self.log_user() response = self.app.get(url(controller='shortlog', action='index',repo_name='vcs_test')) # Test response... diff --git a/pylons_app/tests/functional/test_summary.py b/pylons_app/tests/functional/test_summary.py --- a/pylons_app/tests/functional/test_summary.py +++ b/pylons_app/tests/functional/test_summary.py @@ -3,5 +3,6 @@ from pylons_app.tests import * class TestSummaryController(TestController): def test_index(self): + self.log_user() response = self.app.get(url(controller='summary', action='index',repo_name='vcs_test')) # Test response... diff --git a/pylons_app/tests/functional/test_tags.py b/pylons_app/tests/functional/test_tags.py --- a/pylons_app/tests/functional/test_tags.py +++ b/pylons_app/tests/functional/test_tags.py @@ -3,5 +3,6 @@ from pylons_app.tests import * class TestTagsController(TestController): def test_index(self): + self.log_user() response = self.app.get(url(controller='tags', action='index',repo_name='vcs_test')) # Test response... diff --git a/pylons_app/websetup.py b/pylons_app/websetup.py --- a/pylons_app/websetup.py +++ b/pylons_app/websetup.py @@ -1,40 +1,38 @@ """Setup the pylons_app application""" -from os.path import dirname as dn, join as jn +from os.path import dirname as dn from pylons_app.config.environment import load_environment from pylons_app.lib.db_manage import DbManage -import datetime -from time import mktime import logging import os import sys -import tarfile log = logging.getLogger(__name__) ROOT = dn(dn(os.path.realpath(__file__))) sys.path.append(ROOT) + def setup_app(command, conf, vars): """Place any commands to setup pylons_app here""" log_sql = True tests = False + REPO_TEST_PATH = None dbname = os.path.split(conf['sqlalchemy.db1.url'])[-1] - filename = os.path.split(conf.filename)[-1] - - if filename == 'tests.ini': - uniq_suffix = str(int(mktime(datetime.datetime.now().timetuple()))) - REPO_TEST_PATH = '/tmp/hg_app_test_%s' % uniq_suffix - - if not os.path.isdir(REPO_TEST_PATH): - os.mkdir(REPO_TEST_PATH) - cur_dir = dn(os.path.abspath(__file__)) - tar = tarfile.open(jn(cur_dir,'tests',"vcs_test.tar.gz")) - tar.extractall(REPO_TEST_PATH) - tar.close() - - tests = True +# filename = os.path.split(conf.filename)[-1] +# if filename == 'test.ini': +# uniq_suffix = str(int(mktime(datetime.datetime.now().timetuple()))) +# REPO_TEST_PATH = '/tmp/hg_app_test_%s' % uniq_suffix +# +# if not os.path.isdir(REPO_TEST_PATH): +# os.mkdir(REPO_TEST_PATH) +# cur_dir = dn(os.path.abspath(__file__)) +# tar = tarfile.open(jn(cur_dir,'tests',"vcs_test.tar.gz")) +# tar.extractall(REPO_TEST_PATH) +# tar.close() +# +# tests = True dbmanage = DbManage(log_sql, dbname, tests) dbmanage.create_tables(override=True) diff --git a/setup.cfg b/setup.cfg --- a/setup.cfg +++ b/setup.cfg @@ -8,7 +8,7 @@ find_links = http://www.pylonshq.com/dow [nosetests] verbose=True verbosity=2 -with-pylons=tests.ini +with-pylons=test.ini detailed-errors=1 # Babel configuration diff --git a/tests.ini b/test.ini rename from tests.ini rename to test.ini