@Balalay12

Flask. Почему тест не передает данные во вьюху?

Всем привет.

Пытаюсь освоить TDD. Написал небольшой тест
import unittest

from app import app, db, bcrypt
from app.models import User
from flask_testing import TestCase


class BaseTestCase(TestCase):

    def create_app(self):
        app.config['TESTING'] = True
        app.config['CSRF_ENABLED'] = False
        app.config['WTF_CSRF_ENABLED'] = False
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
        return app

    def setUp(self):
        db.create_all()
        user = User(
                username="admin",
                email="ad@min.com",
                password=bcrypt.generate_password_hash("admin")
            )
        db.session.add(user)
        db.session.commit()

    def tearDown(self):
        db.session.remove()
        db.drop_all()


class TestLoginMixin(BaseTestCase):

    def login_user(self, login, password):

        with self.app.test_request_context('/account/login/'):
            self.app.preprocess_request()
            data = {'username': login, 'password': password}
            response = self.client.post('/account/login/', data=data)

            return response


class LoginTest(TestLoginMixin):

    user = {'username': 'admin', 'password': 'admin'}

    def test_change_password(self):
        """TEST: change password"""

        self.login_user(**self.user)
        response = self.client.post('/account/change_password/', data=dict(
            old=self.user['password'],
            new='new',
            confirm='new'
        ))
        print(response.data, response.status_code)

if __name__ == '__main__':
    unittest.main()


Авторизация отрабатывает нормально, а когда отправляю данные для смены пароля ошибка
if not bcrypt.check_password_hash(current_user.password, data['old']):
TypeError: 'NoneType' object is not subscriptable

т.к. во вью ничего не пришло. Не понимаю почему тест не отправляет данные.

Код вью
class AccountView(FlaskView):

    @route('/login/', methods=['POST'])
    @check_login
    def login(self):
        form = LoginForm(data=request.get_json())
        if form.validate():
            try:
                user = User.query.filter_by(username=form.username.data).first()
            except SQLAlchemyError as e:
                # TODO: loging exeption e
                return return_response(500, jsonify(error='Произошлка ошибка во время запроса.'))
            if user is None:
                return return_response(404, jsonify(error='Пользователь не найден'))
            if bcrypt.check_password_hash(user.password, form.password.data):
                login_user(user)
                return '', 200
            return return_response(404, jsonify(error='Не правильно введен логин или пароль'))

    @login_required
    def logout(self):
        logout_user()
        return '', 200

    @login_required
    @route('/change_password/', methods=['POST'])
    def change_password(self):
        data = request.get_json()
        if not bcrypt.check_password_hash(current_user.password, data['old']):
            return return_response(404, jsonify(error='Старый пароль введен не верно'))
        if not data['new'] == data['confirm']:
            return return_response(404, jsonify(error='Новый пароль и подтверждение пароля не совпадают'))
        try:
            User.query.filter_by(id=current_user.id).update({
                'password': bcrypt.generate_password_hash(data['new'])
            })
            db.session.commit()
        except SQLAlchemyError as e:
            return return_response(500, jsonify(error='Произошла ошибка во время запроса.'))
        return '', 200
  • Вопрос задан
  • 403 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Ankou
привет.

тебе нужно, чтобы в request.get_json() был json-объект, этого можно добиться либо request.get_json(force=True), т.е. заставить любое вхлодящее сообщение воспринимать как json, либо post('/recommend/request', data=data, content_type='application/json'), т.е. передавать корректный mime type
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы