python - (unittest) Testing Flask-Security: Cannot get past login page -
i'm trying add tests basic app. accessing requires login.
here's test case class:
class myapptestcase(flasktestcasemixin): def _create_app(self): raise notimplementederror def _create_fixtures(self): self.user = employeefactory() def setup(self): super(myapptestcase, self).setup() self.app = self._create_app() self.client = self.app.test_client() self.app_context = self.app.app_context() self.app_context.push() db.create_all() self._create_fixtures() self._create_csrf_token() def teardown(self): super(myapptestcase, self).teardown() db.drop_all() self.app_context.pop() def _post(self, route, data=none, content_type=none, follow_redirects=true, headers=none): content_type = content_type or 'application/x-www-form-urlencoded' return self.client.post(route, data=data, follow_redirects=follow_redirects, content_type=content_type, headers=headers) def _login(self, email=none, password=none): email = email or self.user.email password = password or 'password' data = { 'email': email, 'password': password, 'remember': 'y' } return self._post('/login', data=data) class myfrontendtestcase(myapptestcase): def _create_app(self): return create_app(settings) def setup(self): super(myfrontendtestcase, self).setup() self._login() i running tests use nosetests in terminal so: source my_env/bin/activate && nosetests --exe
basic tests these fail:
class cooltestcase(myfrontendtestcase): def test_logged_in(self): r = self._login() self.assertin('myappname', r.data) def test_authenticated_access(self): r = self.get('/myroute/') self.assertin('myappname', r.data) from output, see r.data html of login page no errors (e.g., wrong username or password) or alerts ("please log in access page").
i logging in during setup process, test_authenticated_access should have let me either access /myroute/ or redirect me login page flashed message "please log in access page". didn't.
i can't figure out what's wrong. based test off of ones found in flask documentation , this app boilerplate
i figured out after week of killing myself...
there several problems:
there conflict between flask-security , flask-sslify. although automatic https redirection works fine on actual web server, in tests prevent logging in completely. figured out making fake test routes , trying
postrandom data. nopostin test client worked. fix this, had change test configdebugtrue. note not great workaround, since stuff css , js won't compiled , other app behavior might different...flask-security not work factory_boy(or not using factory_boy correctly?). trying create users , roles through factory_boy because saw sample app tutorial used it. after fixed above problem, kept telling me user did not exist. ended stealing code flask-security's own tests creating fake users different roles.
the problematic code:
session = db.create_scoped_session() class rolefactory(sqlalchemymodelfactory): factory_for = role factory_session = session id = sequence(int) name = 'admin' description = 'administrator' class employeefactory(sqlalchemymodelfactory): factory_for = employee factory_session = session id = sequence(int) email = sequence(lambda n: 'user{0}@app.com'.format(n)) password = lazyattribute(lambda a: encrypt_password('password')) username = sequence(lambda n: 'user{0}'.format(n)) #last_login_at = datetime.utcnow() #current_login_at = datetime.utcnow() last_login_ip = '127.0.0.1' current_login_ip = '127.0.0.1' login_count = 1 roles = lazyattribute(lambda _: [rolefactory()]) active = true this test case:
class myapptestcase(flasktestcasemixin, mytestcase): def _create_app(self): raise notimplementederror def _create_fixtures(self): #self.user = employeefactory() populate_data(1) def setup(self): super(myapptestcase, self).setup() self.app = self._create_app() self.client = self.app.test_client() self.app_context = self.app.app_context() self.app_context.push() db.create_all() self._create_fixtures() self._create_csrf_token() def teardown(self): super(myapptestcase, self).teardown() db.drop_all() self.app_context.pop() def _post(self, route, data=none, content_type=none, follow_redirects=true, headers=none): content_type = content_type or 'application/x-www-form-urlencoded' return self.client.post(route, data=data, follow_redirects=follow_redirects, content_type=content_type, headers=headers) def _login(self, email=none, password=none): email = email or 'matt@lp.com' #self.user.email password = password or 'password' data = { 'email': email, 'password': password, 'remember': 'y' } return self._post('/login', data=data)
Comments
Post a Comment