简体   繁体   中英

flask_login - current_user

I am using the flask_login extension in my flask app to login users. As you must be knowing, this extension has a variable that stores a current_user . The code is working perfectly, except when it comes to testing it.

When I am testing the code (using unittest ), I register a "test user" and log it in. But the current_user variable does not keep the user that logged in.

Here is my app code; the part that adds in a category ( current_user gets set when a user logs in) :

def post(self):
    # Get the access token from the header
    auth_header = request.headers.get('Authorization')
    access_token = auth_header.split(" ")[1]

    if access_token:
        # Attempt to decode the token and get the User ID
        user_id = User.decode_token(access_token)
        if not isinstance(user_id, str):
            # Go ahead and handle the request, the user is authenticated
            data = request.get_json()
            if data['name']:
                category = Category(name = data['name'], user_id = user_id)

                db.session.add(category)
                db.session.commit()

                response = {'id' : category.id,
                    'category_name' : category.name,
                    'created_by' : current_user.first_name
                }

                return response

        else:
            # user is not legit, so the payload is an error message
            message = user_id
            response = {
                'message': message
            }
            return response

Here is my code that tests the app:

import unittest
import os
import json
import app
from app import create_app, db


class CategoryTestCase(unittest.TestCase):
    """This class represents the Category test case"""

    def setUp(self):
        """setup test variables"""
        self.app = create_app(config_name="testing")
        self.client = self.app.test_client
        self.category_data = {'name' : 'Yummy'}

        # binds the app with the current context
        with self.app.app_context():
            #create all tables
            db.session.close()
            db.drop_all()
            db.create_all()

    def register_user(self, first_name='Tester', last_name='Api', username='apitester', email='tester@api.com', password='abc'):
        """This helper method helps register a test user"""
        user_data = {
            'first_name' : first_name,
            'last_name' : last_name,
            'username' : username,
            'email' : email,
            'password' : password
        }

        return self.client().post('/api/v1.0/register', data=json.dumps(user_data), content_type='application/json')

    def login_user(self, email='tester@api.com', password='abc'):
        """this helper method helps log in a test user"""
        user_data = {
            'email' : email,
            'password' : password
        }

        return self.client().post('/api/v1.0/login', data=json.dumps(user_data), content_type='application/json')

    def test_category_creation(self):
        """Test that the Api can create a category"""
        self.register_user()
        login_result = self.login_user()

        token = json.loads(login_result.data)
        token = token['access_token']

        # Create a category by going to that link
        response = self.client().post('/api/v1.0/category', headers=dict(Authorization="Bearer " + token), data=json.dumps(self.category_data), content_type='application/json')
        self.assertEquals(response.status_code, 201)

You need to use the same context which you used for logging in. So this is what you need to add in your code:

with self.client() as c:

Then use the c to make get, post, or any other request you want. Here is a complete example:

import unittest
from app import create_app

class CategoryTestCase(unittest.TestCase):
    """This class represents the Category test case"""

    def setUp(self):
        """setup test variables"""
        self.app = create_app(config_name="testing")
        self.client = self.app.test_client

        self.category_data = {'name' : 'Yummy'}

    def test_category_creation(self):
        """Test that the user can create a category"""
        with self.client() as c:
            # use the c to make get, post or any other requests
            login_response = c.post("""login the user""")

            # Create a category by going to that link using the same context i.e c
            response = c.post('/api/v1.0/category', self.category_data)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM