2014-04-16 13 views
5

Tôi đang cố thêm các thử nghiệm vào ứng dụng cơ bản của mình. Truy cập mọi thứ yêu cầu đăng nhập.(unittest) Kiểm tra Flask-Security: Không thể truy cập trang đăng nhập trước đây

Dưới đây là bài kiểm tra trường hợp lớp học của tôi:

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() 

Tôi đang chạy thử nghiệm của tôi sử dụng nosetests trong Terminal như vậy: source my_env/bin/activate && nosetests --exe

xét nghiệm cơ bản như thế này không:

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) 

Từ đầu ra , Tôi thấy rằng r.data chỉ là HTML của trang đăng nhập không có lỗi (ví dụ: tên người dùng hoặc mật khẩu sai) hoặc cảnh báo ("Vui lòng đăng nhập để truy cập vào trang này trang").

Tôi đang đăng nhập trong quá trình setUp, vì vậy test_authenticated_accessnên có cho tôi hoặc truy cập /myroute/ hoặc chuyển hướng tôi đến trang đăng nhập với thông điệp lóe lên "Xin hãy đăng nhập để truy cập vào trang này". Nhưng nó không.

Tôi không thể tìm ra điều gì sai. Tôi dựa thử nghiệm của tôi tắt của những người tôi tìm thấy trong tài liệu hướng dẫn Flask và this app boilerplate

+0

Tôi thấy bạn đang sử dụng CSRF mã thông báo - bạn đã thử tắt chúng và nhìn thấy nếu mà được bạn xa hơn? Tôi biết họ đã cắn tôi trong các bài kiểm tra nhiều lần hơn tôi có thể nhớ. –

+0

Nếu bạn đang sử dụng (hoặc có thể sử dụng) Flask 0.10, tôi khuyên bạn nên sử dụng nội dung giả mạo mới: http://flask.pocoo.org/docs/testing/#faking-resources-and-context Chúng tôi hiện đang làm một cái gì đó rất giống với những gì bạn đang làm cho các bài kiểm tra của chúng tôi, và ngay sau khi chúng tôi có thể nâng cấp, tôi trích xuất nó tất cả ra ủng hộ điều này. –

+0

@RachelSanders - Tôi đã đặt 'WTF_CSRF_ENABLED' thành' False' –

Trả lời

2

Cuối cùng tôi figured it out sau một tuần giết chết bản thân mình ...

Có một vài vấn đề:

  1. Có là một số xung đột giữa Flask-Security và Flask-SSLify. Mặc dù chuyển hướng https tự động hoạt động tốt trên máy chủ web thực tế, trong các thử nghiệm nó ngăn việc đăng nhập hoàn toàn. Tôi đã tìm ra điều này bằng cách thực hiện các tuyến đường thử nghiệm giả và cố gắng để POST dữ liệu ngẫu nhiên. Không POST trong ứng dụng khách thử nghiệm đã hoạt động. Để khắc phục điều này, tôi phải thay đổi cấu hình thử nghiệm của mình DEBUG thành True. Lưu ý rằng đây không phải là giải pháp tuyệt vời vì các nội dung như CSS và JS sẽ không được biên soạn và hành vi ứng dụng khác có thể khác ...

  2. Flask-Security không hoạt động với factory_boy (hoặc tôi không sử dụng factory_boy chính xác?). Tôi đã cố gắng tạo người dùng và vai trò thông qua factory_boy vì tôi thấy một số hướng dẫn ứng dụng mẫu sử dụng nó. Sau khi tôi khắc phục vấn đề trên, nó vẫn nói với tôi rằng người dùng không tồn tại. Tôi đã kết thúc việc ăn cắp mã từ các thử nghiệm riêng của Flask-Security để tạo người dùng giả mạo với các vai trò khác nhau.

Mã có vấn đề:

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 

Đây là trường hợp thử nghiệm của tôi:

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 '[email protected]' #self.user.email 
     password = password or 'password' 
     data = { 
      'email': email, 
      'password': password, 
      'remember': 'y' 
      } 
     return self._post('/login', data=data) 
+0

bạn đã liệt kê bài kiểm tra vấn đề, nhưng không liệt kê bài kiểm tra làm việc. Không thể dễ dàng tìm thấy nó ở đây. https://github.com/mattupstate/flask-security – nycynik

1

Tôi đã có một vấn đề với đăng nhập/đăng xuất trên thử nghiệm với Flask-An ninh (có sử dụng Flask- Đăng nhập) ứng dụng cũng có. Tôi giải quyết vấn đề này bằng cách chế nhạo hàm flask_login._get_user và đặt app.login_manager._login_disabled thành True.

quản lý

Bối cảnh mà chế nhạo người dùng:

class LoginLogoutMixin(object): 
    @contextmanager 
    def login(self, user): 
     mock_get_user = patch('flask_login._get_user', Mock(return_value=user)) 
     self.app.login_manager._login_disabled = True 
     mock_get_user.start() 
     yield 
     mock_get_user.stop() 
     self.app.login_manager._login_disabled = False 

Và một ví dụ về nó sử dụng:

class ProtectedViewTestCase(LoginLogoutMixin, TestCase): 

    def setUp(self): 
     super(ProtectedViewTestCase, self).setUp() 
     # create user here 

    def test_protected_view(self): 
     with self.login(self.user): 
      rv = self.client.get(url_for('protected_view')) 
      self.assert200(rv) 
Các vấn đề liên quan