diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | bootstrap.py | 11 | ||||
-rw-r--r-- | pyaggr3g470r/controllers/abstract.py | 17 | ||||
-rw-r--r-- | pyaggr3g470r/models/__init__.py | 3 | ||||
-rw-r--r-- | pyaggr3g470r/models/article.py | 10 | ||||
-rw-r--r-- | tests/__init__.py | 0 | ||||
-rw-r--r-- | tests/base.py | 41 | ||||
-rw-r--r-- | tests/controllers/__init__.py | 5 | ||||
-rw-r--r-- | tests/controllers/article.py | 12 | ||||
-rw-r--r-- | tests/controllers/feed.py | 15 | ||||
-rw-r--r-- | tests/fixtures.py | 32 |
11 files changed, 132 insertions, 15 deletions
@@ -24,3 +24,4 @@ build conf/conf.cfg +.coverage diff --git a/bootstrap.py b/bootstrap.py index 7a5a9b6e..9cab7417 100644 --- a/bootstrap.py +++ b/bootstrap.py @@ -22,7 +22,15 @@ from flask.ext.sqlalchemy import SQLAlchemy # Create Flask application application = Flask('pyaggr3g470r') -application.debug = conf.LOG_LEVEL <= logging.DEBUG +if os.environ.get('PYAGG_TESTING', False) == 'true': + application.debug = logging.DEBUG + application.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' + application.config['TESTING'] = True +else: + application.debug = conf.LOG_LEVEL <= logging.DEBUG + application.config['SQLALCHEMY_DATABASE_URI'] \ + = conf.SQLALCHEMY_DATABASE_URI + scheme, domain, _, _, _ = urlsplit(conf.PLATFORM_URL) application.config['SERVER_NAME'] = domain application.config['PREFERRED_URL_SCHEME'] = scheme @@ -33,7 +41,6 @@ set_logging(conf.LOG_PATH, log_level=conf.LOG_LEVEL) application.config['SECRET_KEY'] = getattr(conf, 'WEBSERVER_SECRET', None) if not application.config['SECRET_KEY']: application.config['SECRET_KEY'] = os.urandom(12) -application.config['SQLALCHEMY_DATABASE_URI'] = conf.SQLALCHEMY_DATABASE_URI application.config['RECAPTCHA_USE_SSL'] = True application.config['RECAPTCHA_PUBLIC_KEY'] = conf.RECAPTCHA_PUBLIC_KEY diff --git a/pyaggr3g470r/controllers/abstract.py b/pyaggr3g470r/controllers/abstract.py index 3ea4fbff..f67f932c 100644 --- a/pyaggr3g470r/controllers/abstract.py +++ b/pyaggr3g470r/controllers/abstract.py @@ -19,9 +19,12 @@ class AbstractController(object): allowing for a kind of "super user" mode. """ self.user_id = user_id - if self.user_id is not None \ - and self.user_id != g.user.id and not g.user.is_admin(): - self.user_id = g.user.id + try: + if self.user_id is not None \ + and self.user_id != g.user.id and not g.user.is_admin(): + self.user_id = g.user.id + except RuntimeError: # passing on out of context errors + pass def _to_filters(self, **filters): """ @@ -67,13 +70,13 @@ class AbstractController(object): def get(self, **filters): """Will return one single objects corresponding to filters""" obj = self._get(**filters).first() - if not obj: - raise NotFound({'message': 'No %r (%r)' - % (self._db_cls.__class__.__name__, filters)}) - if not self._has_right_on(obj): + if obj and not self._has_right_on(obj): raise Forbidden({'message': 'No authorized to access %r (%r)' % (self._db_cls.__class__.__name__, filters)}) + if not obj: + raise NotFound({'message': 'No %r (%r)' + % (self._db_cls.__class__.__name__, filters)}) return obj def create(self, **attrs): diff --git a/pyaggr3g470r/models/__init__.py b/pyaggr3g470r/models/__init__.py index 42903f4e..ba52b0de 100644 --- a/pyaggr3g470r/models/__init__.py +++ b/pyaggr3g470r/models/__init__.py @@ -98,4 +98,5 @@ def db_create(db): user1.roles.extend([role_admin, role_user]) db.session.add(user1) - db.session.commit()
\ No newline at end of file + db.session.commit() + return role_admin, role_user diff --git a/pyaggr3g470r/models/article.py b/pyaggr3g470r/models/article.py index 58cd0384..3151071a 100644 --- a/pyaggr3g470r/models/article.py +++ b/pyaggr3g470r/models/article.py @@ -66,14 +66,14 @@ class Article(db.Model): .order_by(asc("Article.date")).first() def __repr__(self): - return json.dumps({ - "title": self.title, - "link": self.link, - "content": self.content - }) + return json.dumps({"title": self.title, + "link": self.link, + "content": self.content + }) def dump(self): return {"id": self.id, + "user_id": self.user_id, "title": self.title, "link": self.link, "content": self.content, diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/__init__.py diff --git a/tests/base.py b/tests/base.py new file mode 100644 index 00000000..d6f62583 --- /dev/null +++ b/tests/base.py @@ -0,0 +1,41 @@ +import os +os.environ['PYAGG_TESTING'] = 'true' + +import unittest +from bootstrap import db +import runserver +from tests.fixtures import populate_db, reset_db +from werkzeug.exceptions import NotFound + + +class BasePyaggTest(unittest.TestCase): + _contr_cls = None + + def _get_from_contr(self, obj_id, user_id=None): + return self._contr_cls(user_id).get(id=obj_id).dump() + + def _test_controller_rights(self, obj, user_id): + obj_id = obj['id'] + self.assertEquals(obj, self._get_from_contr(obj_id)) + self.assertEquals(obj, self._get_from_contr(obj_id, user_id)) + # fetching non existent object + self.assertRaises(NotFound, self._get_from_contr, 99, user_id) + # fetching object with inexistent user + self.assertRaises(NotFound, self._get_from_contr, obj_id, 99) + # fetching object with wrong user + self.assertRaises(NotFound, self._get_from_contr, obj_id, user_id + 1) + self.assertRaises(NotFound, self._contr_cls().delete, 99) + self.assertRaises(NotFound, self._contr_cls(user_id).delete, 99) + self.assertEquals(obj['id'], + self._contr_cls(user_id).delete(obj_id).id) + self.assertRaises(NotFound, self._contr_cls(user_id).delete, obj_id) + + def setUp(self): + populate_db(db) + + def tearDown(self): + reset_db(db) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/controllers/__init__.py b/tests/controllers/__init__.py new file mode 100644 index 00000000..26922c43 --- /dev/null +++ b/tests/controllers/__init__.py @@ -0,0 +1,5 @@ +from tests.controllers.feed import FeedControllerTest +from tests.controllers.article import ArticleControllerTest + + +__all__ = ['FeedControllerTest', 'ArticleControllerTest'] diff --git a/tests/controllers/article.py b/tests/controllers/article.py new file mode 100644 index 00000000..b6c5225c --- /dev/null +++ b/tests/controllers/article.py @@ -0,0 +1,12 @@ +from tests.base import BasePyaggTest +from pyaggr3g470r.controllers import ArticleController + + +class ArticleControllerTest(BasePyaggTest): + _contr_cls = ArticleController + + def test_controller(self): + article = ArticleController(2).read()[0].dump() + self.assertFalse(article['readed']) + article['readed'] = True # article get read when retreived through get + self._test_controller_rights(article, article['user_id']) diff --git a/tests/controllers/feed.py b/tests/controllers/feed.py new file mode 100644 index 00000000..d8d6378b --- /dev/null +++ b/tests/controllers/feed.py @@ -0,0 +1,15 @@ +from tests.base import BasePyaggTest +from pyaggr3g470r.controllers import FeedController +from pyaggr3g470r.controllers import ArticleController + + +class FeedControllerTest(BasePyaggTest): + _contr_cls = FeedController + + def test_controller(self): + feed = FeedController(2).read()[0].dump() + self.assertTrue(3, ArticleController().read(feed_id=feed['id']).count()) + self._test_controller_rights(feed, feed['user_id']) + # checking articles are deleted after the feed has been deleted + self.assertFalse(0, + ArticleController().read(feed_id=feed['id']).count()) diff --git a/tests/fixtures.py b/tests/fixtures.py new file mode 100644 index 00000000..bc783847 --- /dev/null +++ b/tests/fixtures.py @@ -0,0 +1,32 @@ +from pyaggr3g470r.models import db_create, db_empty, User, Article, Feed + + +def populate_db(db): + role_admin, role_user = db_create(db) + user1, user2 = [User(nickname=name, email="%s@test.te" % name, + pwdhash=name, roles=[role_user], activation_key="") + for name in ["user1", "user2"]] + db.session.add(user1) + db.session.add(user2) + db.session.commit() + + for user in (user1, user2): + for feed_name in ['feed1', 'feed2', 'feed3']: + feed = Feed(link=feed_name, user_id=user.id, + title="%r %r" % (user.nickname, feed_name)) + db.session.add(feed) + db.session.commit() + for article in ['article1', 'article2', 'article3']: + article = Article(entry_id=article, link=article, + feed_id=feed.id, user_id=user.id, + title="%r %r %r" % (user.nickname, + feed.title, article), + content=article) + db.session.add(article) + db.session.commit() + + db.session.commit() + + +def reset_db(db): + db_empty(db) |