diff --git a/examples/minitwit/README b/examples/minitwit/README index f054fd8f..e47c8792 100644 --- a/examples/minitwit/README +++ b/examples/minitwit/README @@ -19,3 +19,8 @@ 3. now you can run the minitwit.py file with your python interpreter and the application will greet you on http://localhost:5000/ + + ~ Is it tested? + + You betcha. Run the `minitwit_tests.py` file to + see the tests pass. diff --git a/examples/minitwit/minitwit.py b/examples/minitwit/minitwit.py index f3bbe7c3..05f0689d 100644 --- a/examples/minitwit/minitwit.py +++ b/examples/minitwit/minitwit.py @@ -216,7 +216,7 @@ def register(): elif not request.form['password']: error = 'You have to enter a password' elif request.form['password'] != request.form['password2']: - error = 'The two passwords to not match' + error = 'The two passwords do not match' elif get_user_id(request.form['username']) is not None: error = 'The username is already taken' else: diff --git a/examples/minitwit/minitwit_tests.py b/examples/minitwit/minitwit_tests.py new file mode 100644 index 00000000..a3502f64 --- /dev/null +++ b/examples/minitwit/minitwit_tests.py @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- +""" + MiniTwit Tests + ~~~~~~~~~~~~~~ + + Tests the MiniTwit application. + + :copyright: (c) 2010 by Armin Ronacher. + :license: BSD, see LICENSE for more details. +""" +import minitwit +import unittest +import tempfile +from contextlib import closing + + +class MiniTwitTestCase(unittest.TestCase): + + def setUp(self): + """Before each test, set up a blank database""" + self.db = tempfile.NamedTemporaryFile() + self.app = minitwit.app.test_client() + minitwit.DATABASE = self.db.name + minitwit.init_db() + + # helper functions + + def register(self, username, password, password2=None, email=None): + """Helper function to register a user""" + if password2 is None: + password2 = password + if email is None: + email = username + '@example.com' + return self.app.post('/register', data={ + 'username': username, + 'password': password, + 'password2': password2, + 'email': email, + }, follow_redirects=True) + + def login(self, username, password): + """Helper function to login""" + return self.app.post('/login', data={ + 'username': username, + 'password': password + }, follow_redirects=True) + + def register_and_login(self, username, password): + """Registers and logs in in one go""" + self.register(username, password) + return self.login(username, password) + + def logout(self): + """Helper function to logout""" + return self.app.get('/logout', follow_redirects=True) + + def add_message(self, text): + """Records a message""" + rv = self.app.post('/add_message', data={'text': text}, + follow_redirects=True) + if text: + assert 'Your message was recorded' in rv.data + return rv + + # testing functions + + def test_register(self): + """Make sure registering works""" + rv = self.register('user1', 'default') + assert 'You were successfully registered ' \ + 'and can login now' in rv.data + rv = self.register('user1', 'default') + assert 'The username is already taken' in rv.data + rv = self.register('', 'default') + assert 'You have to enter a username' in rv.data + rv = self.register('meh', '') + assert 'You have to enter a password' in rv.data + rv = self.register('meh', 'x', 'y') + assert 'The two passwords do not match' in rv.data + rv = self.register('meh', 'foo', email='broken') + assert 'You have to enter a valid email address' in rv.data + + def test_login_logout(self): + """Make sure logging in and logging out works""" + rv = self.register_and_login('user1', 'default') + assert 'You were logged in' in rv.data + rv = self.logout() + assert 'You were logged out' in rv.data + rv = self.login('user1', 'wrongpassword') + assert 'Invalid password' in rv.data + rv = self.login('user2', 'wrongpassword') + assert 'Invalid username' in rv.data + + def test_message_recording(self): + """Check if adding messages works""" + self.register_and_login('foo', 'default') + self.add_message('test message 1') + self.add_message('') + rv = self.app.get('/') + assert 'test message 1' in rv.data + assert '<test message 2>' in rv.data + + def test_timelines(self): + """Make sure that timelines work""" + self.register_and_login('foo', 'default') + self.add_message('the message by foo') + self.logout() + self.register_and_login('bar', 'default') + self.add_message('the message by bar') + rv = self.app.get('/public') + assert 'the message by foo' in rv.data + assert 'the message by bar' in rv.data + + # bar's timeline should just show bar's message + rv = self.app.get('/') + assert 'the message by foo' not in rv.data + assert 'the message by bar' in rv.data + + # now let's follow foo + rv = self.app.get('/foo/follow', follow_redirects=True) + assert 'You are now following "foo"' in rv.data + + # we should now see foo's message + rv = self.app.get('/') + assert 'the message by foo' in rv.data + assert 'the message by bar' in rv.data + + # but on the user's page we only want the user's message + rv = self.app.get('/bar') + assert 'the message by foo' not in rv.data + assert 'the message by bar' in rv.data + rv = self.app.get('/foo') + assert 'the message by foo' in rv.data + assert 'the message by bar' not in rv.data + + # now unfollow and check if that worked + rv = self.app.get('/foo/unfollow', follow_redirects=True) + assert 'You are no longer following "foo"' in rv.data + rv = self.app.get('/') + assert 'the message by foo' not in rv.data + assert 'the message by bar' in rv.data + + +if __name__ == '__main__': + unittest.main() diff --git a/flask.py b/flask.py index 1ea239f8..21858f5e 100644 --- a/flask.py +++ b/flask.py @@ -265,9 +265,8 @@ class Flask(object): options.setdefault('use_debugger', self.debug) return run_simple(host, port, self, **options) - @cached_property - def test(self): - """A test client for this application""" + def test_client(self): + """Creates a test client for this application""" from werkzeug import Client return Client(self, self.response_class, use_cookies=True)