From a14257f17b1fb9d566dd433b56768ad8bb65e214 Mon Sep 17 00:00:00 2001 From: Nathan Weizenbaum Date: Tue, 22 May 2012 14:23:38 -0700 Subject: [PATCH] Add tests for the package creation workflow. --- test.py | 42 ++++++++++++++++++++++++++ test/test_packages.py | 70 +++++++++++++++++++++++++++++++++++++++++++ test/testcase.py | 60 +++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100755 test.py create mode 100644 test/test_packages.py create mode 100644 test/testcase.py diff --git a/test.py b/test.py new file mode 100755 index 0000000..84067b2 --- /dev/null +++ b/test.py @@ -0,0 +1,42 @@ +#!/usr/bin/python +import optparse +import os +import sys +import subprocess + +import unittest2 + +USAGE = """%prog [SDK_PATH] +Run unit tests. + +SDK_PATH Path to the SDK installation. + Auto-detected if dev_appserver.py is on $PATH.""" + + +def main(sdk_path, test_path): + sys.path.insert(0, sdk_path) + import dev_appserver + dev_appserver.fix_sys_path() + suite = unittest2.loader.TestLoader().discover(test_path) + unittest2.TextTestRunner(verbosity=2).run(suite) + +parser = optparse.OptionParser(USAGE) +options, args = parser.parse_args() +sdk_path = None +if len(args) > 1: + print 'Error: 0 or 1 arguments required.' + parser.print_help() + sys.exit(1) +elif len(args) == 1: + sdk_path = args[0] +else: + process = subprocess.Popen(["which", "dev_appserver.py"], + stdout=subprocess.PIPE) + stdout = process.communicate()[0] + if process.returncode > 0: + print('Error: could not find SDK path.') + parser.print_help() + sys.exit(1) + sdk_path = os.path.dirname(stdout.strip()) + +main(sdk_path, os.path.join(os.path.dirname(__file__), 'test')) diff --git a/test/test_packages.py b/test/test_packages.py new file mode 100644 index 0000000..e2051f6 --- /dev/null +++ b/test/test_packages.py @@ -0,0 +1,70 @@ +from google.appengine.api import users + +from testcase import TestCase +from models.package import Package + +class PackagesTest(TestCase): + def testAdminCreatesPackage(self): + self.beAdminUser() + + get_response = self.testapp.get('/packages/create') + self.assertEqual(get_response.status_int, 200) + form = get_response.form + self.assertEqual(form.action, '/packages/') + self.assertEqual(form.method, 'POST') + + form['name'] = 'test-package' + post_response = form.submit() + + self.assertEqual(post_response.status_int, 302) + self.assertEqual(post_response.headers['Location'], + 'http://localhost:80/packages/') + self.assertTrue(post_response.cookies_set.has_key('flash')) + + package = Package.get_by_key_name('test-package') + self.assertTrue(package is not None) + self.assertEqual(package.name, 'test-package') + self.assertEqual(package.owner, users.get_current_user()) + + def testGetCreateRequiresLogin(self): + response = self.testapp.get('/packages/create') + self.assertEqual(response.status_int, 302) + self.assertEqual(response.headers['Location'], + 'https://www.google.com/accounts/Login?continue=http' + '%3A//localhost%3A80/packages/create') + + def testGetCreateRequiresAdmin(self): + self.beNormalUser() + + response = self.testapp.get('/packages/create') + self.assertEqual(response.status_int, 302) + self.assertEqual(response.headers['Location'], + 'http://localhost:80/packages/') + self.assertTrue(response.cookies_set.has_key('flash')) + + def testPostPackagesRequiresLogin(self): + response = self.testapp.post('/packages/', {'name': 'test-package'}, + status=403) + self.assertErrorPage(response) + + def testPostPackagesRequiresAdmin(self): + self.beNormalUser() + + response = self.testapp.post('/packages/', {'name': 'test-package'}, + status=403) + self.assertErrorPage(response) + + def testPostPackagesRequiresNewPackageName(self): + self.beAdminUser() + + other_admin = self.adminUser('other') + Package(name='test-package', owner=other_admin).put() + + response = self.testapp.post('/packages/', {'name': 'test-package'}) + self.assertEqual(response.status_int, 302) + self.assertEqual(response.headers['Location'], + 'http://localhost:80/packages/create') + self.assertTrue(response.cookies_set.has_key('flash')) + + package = Package.get_by_key_name('test-package') + self.assertEqual(package.owner, other_admin) diff --git a/test/testcase.py b/test/testcase.py new file mode 100644 index 0000000..a763271 --- /dev/null +++ b/test/testcase.py @@ -0,0 +1,60 @@ +import unittest + +import cherrypy +import webtest +from google.appengine.ext.testbed import Testbed +from google.appengine.api import users + +from handlers.root import Root + +class TestCase(unittest.TestCase): + def setUp(self): + self.__users = {} + self.__admins = {} + + self.testbed = Testbed() + self.testbed.activate() + self.testbed.init_datastore_v3_stub() + self.testbed.init_user_stub() + + self.testapp = webtest.TestApp(cherrypy.Application(Root())) + + def tearDown(self): + self.testbed.deactivate() + + def normalUser(self, name = None): + if self.__users.has_key(name): + return self.__users[name] + + email = 'test-user@example.com' + if name: + email = 'test-user-%s@example.com' % name + + self.__users[name] = users.User(email = email) + return self.__users[name] + + def adminUser(self, name = None): + if self.__admins.has_key(name): + return self.__admins[name] + + email = 'test-admin@example.com' + if name: + email = 'test-admin-%s@example.com' % name + + self.__admins[name] = users.User(email = email) + return self.__admins[name] + + def beNormalUser(self, name = None): + self.testbed.setup_env( + user_email = self.normalUser(name).email(), + overwrite = True) + + def beAdminUser(self, name = None): + self.testbed.setup_env( + user_email = self.adminUser(name).email(), + user_is_admin = '1', + overwrite = True) + + def assertErrorPage(self, response): + # TODO(nweiz): Make a better error page that's easier to detect + self.assertTrue(response.html.find('pre', id='traceback') is not None)