Skip to content
This repository
Browse code

Updated tests to test Flask-SQLAlchemy models, if that package is ins…

…talled.
  • Loading branch information...
commit c3489c58141bb29145cd25043c810538013a71bc 1 parent 70fa31b
authored April 16, 2012
31  tests/helpers.py
@@ -65,7 +65,25 @@ def tearDownModule():
65 65
         DB['filename'] = None
66 66
 
67 67
 
68  
-class TestSupport(TestCase):
  68
+class FlaskTestBase(TestCase):
  69
+    """Base class for tests which use a Flask application."""
  70
+
  71
+    def setUp(self):
  72
+        """Creates the Flask application and the APIManager."""
  73
+        super(FlaskTestBase, self).setUp()
  74
+
  75
+        # create the Flask application
  76
+        app = Flask(__name__)
  77
+        app.config['DEBUG'] = True
  78
+        app.config['TESTING'] = True
  79
+        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///%s' % DB['filename']
  80
+        self.flaskapp = app
  81
+
  82
+        # create the test client
  83
+        self.app = app.test_client()
  84
+
  85
+
  86
+class TestSupport(FlaskTestBase):
69 87
     """Base class for tests which use a database and have an
70 88
     :class:`flask_restless.APIManager` with a :class:`flask.Flask` app object.
71 89
 
@@ -77,14 +95,10 @@ class TestSupport(TestCase):
77 95
 
78 96
     def setUp(self):
79 97
         """Creates the Flask application and the APIManager."""
80  
-        # create the Flask application
81  
-        app = Flask(__name__)
82  
-        app.config['DEBUG'] = True
83  
-        app.config['TESTING'] = True
84  
-        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///%s' % DB['filename']
85  
-        self.flaskapp = app
  98
+        super(TestSupport, self).setUp()
86 99
 
87 100
         # initialize SQLAlchemy and Flask-Restless
  101
+        app = self.flaskapp
88 102
         engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'],
89 103
                                convert_unicode=True)
90 104
         self.session = scoped_session(sessionmaker(autocommit=False,
@@ -119,9 +133,6 @@ class Person(self.Base):
119 133
         # create all the tables required for the models
120 134
         self.Base.metadata.create_all()
121 135
 
122  
-        # create the test client
123  
-        self.app = app.test_client()
124  
-
125 136
     def tearDown(self):
126 137
         """Drops all tables from the temporary database."""
127 138
         #self.session.remove()
97  tests/test_manager.py
@@ -9,14 +9,23 @@
9 9
 
10 10
 """
11 11
 import datetime
  12
+from unittest2 import skipUnless
  13
+from unittest2 import TestCase
12 14
 from unittest2 import TestSuite
13 15
 
14 16
 from flask import Flask
15 17
 from flask import json
  18
+try:
  19
+    from flask.ext.sqlalchemy import SQLAlchemy
  20
+except:
  21
+    has_flask_sqlalchemy = False
  22
+else:
  23
+    has_flask_sqlalchemy = True
16 24
 
17 25
 from flask.ext.restless import APIManager
18 26
 from flask.ext.restless.views import _get_columns
19 27
 
  28
+from .helpers import FlaskTestBase
20 29
 from .helpers import setUpModule
21 30
 from .helpers import tearDownModule
22 31
 from .helpers import TestSupport
@@ -260,8 +269,96 @@ def test_different_urls(self):
260 269
         self.assertEqual(response.status_code, 404)
261 270
 
262 271
 
  272
+class FSATest(FlaskTestBase):
  273
+    """Tests which use models defined using Flask-SQLAlchemy instead of pure
  274
+    SQLAlchemy.
  275
+
  276
+    """
  277
+
  278
+    def setUp(self):
  279
+        """Creates the Flask application, the APIManager, the database, and the
  280
+        Flask-SQLAlchemy models.
  281
+
  282
+        """
  283
+        super(FSATest, self).setUp()
  284
+
  285
+        # initialize SQLAlchemy and Flask-Restless
  286
+        self.db = SQLAlchemy(self.flaskapp)
  287
+        self.manager = APIManager(self.flaskapp, flask_sqlalchemy_db=self.db)
  288
+
  289
+        # for the sake of brevity...
  290
+        db = self.db
  291
+
  292
+        # declare the models
  293
+        class Computer(db.Model):
  294
+            id = db.Column(db.Integer, primary_key=True)
  295
+            name = db.Column(db.Unicode, unique=True)
  296
+            vendor = db.Column(db.Unicode)
  297
+            buy_date = db.Column(db.DateTime)
  298
+            owner_id = db.Column(db.Integer, db.ForeignKey('person.id'))
  299
+
  300
+        class Person(db.Model):
  301
+            id = db.Column(db.Integer, primary_key=True)
  302
+            name = db.Column(db.Unicode, unique=True)
  303
+            age = db.Column(db.Float)
  304
+            other = db.Column(db.Float)
  305
+            birth_date = db.Column(db.Date)
  306
+            computers = db.relationship('Computer',
  307
+                                        backref=db.backref('owner',
  308
+                                                           lazy='dynamic'))
  309
+        self.Person = Person
  310
+        self.Computer = Computer
  311
+
  312
+        # create all the tables required for the models
  313
+        self.db.create_all()
  314
+
  315
+    def tearDown(self):
  316
+        """Drops all tables from the temporary database."""
  317
+        self.db.drop_all()
  318
+
  319
+    def test_flask_sqlalchemy(self):
  320
+        """Tests that :class:`flask.ext.restless.APIManager` correctly exposes
  321
+        models defined using Flask-SQLAlchemy.
  322
+
  323
+        """
  324
+        # create three different APIs for the same model
  325
+        self.manager.create_api(self.Person, methods=['GET', 'POST'])
  326
+        self.manager.create_api(self.Person, methods=['PATCH'],
  327
+                                url_prefix='/api2')
  328
+        self.manager.create_api(self.Person, methods=['GET'],
  329
+                                url_prefix='/readonly')
  330
+
  331
+        # test that specified endpoints exist
  332
+        response = self.app.post('/api/person', data=dumps(dict(name='foo')))
  333
+        self.assertEqual(response.status_code, 201)
  334
+        self.assertEqual(loads(response.data)['id'], 1)
  335
+        response = self.app.get('/api/person')
  336
+        self.assertEqual(response.status_code, 200)
  337
+        self.assertEqual(len(loads(response.data)['objects']), 1)
  338
+        self.assertEqual(loads(response.data)['objects'][0]['id'], 1)
  339
+        response = self.app.patch('/api2/person/1',
  340
+                                  data=dumps(dict(name='bar')))
  341
+        self.assertEqual(response.status_code, 200)
  342
+        self.assertEqual(loads(response.data)['id'], 1)
  343
+        self.assertEqual(loads(response.data)['name'], 'bar')
  344
+
  345
+        # test that the model is the same as before
  346
+        response = self.app.get('/readonly/person')
  347
+        self.assertEqual(response.status_code, 200)
  348
+        self.assertEqual(len(loads(response.data)['objects']), 1)
  349
+        self.assertEqual(loads(response.data)['objects'][0]['id'], 1)
  350
+        self.assertEqual(loads(response.data)['objects'][0]['name'], 'bar')
  351
+
  352
+
  353
+# skipUnless should be used as a decorator, but Python 2.5 doesn't have
  354
+# decorators.
  355
+FSATest = skipUnless(has_flask_sqlalchemy,
  356
+                     'Flask-SQLAlchemy not found.')(FSATest)
  357
+
  358
+
263 359
 def load_tests(loader, standard_tests, pattern):
264 360
     """Returns the test suite for this module."""
265 361
     suite = TestSuite()
266 362
     suite.addTest(loader.loadTestsFromTestCase(APIManagerTest))
  363
+    suite.addTest(loader.loadTestsFromTestCase(FSATest))
267 364
     return suite

0 notes on commit c3489c5

Please sign in to comment.
Something went wrong with that request. Please try again.