# Path: project/tests/base.py
# class MVCTestCase(BaseTestCase):
#     """Default base test case for every
#     <Model|View|Controller(Form)>TestCase"""
#     pass
# 
# Path: project/user/services/create_user_service.py
# class CreateUserService:
# 
#     def __init__(self, username, password, generate_api_key=True, *args, **kwargs):
#         self.username = username
#         self.password = password
#         self.generate_api_key = generate_api_key
#         self.args = args
#         self.kwargs = kwargs
# 
#     def call(self):
#         self.kwargs.update(dict(username=self.username, password=self.password))
#         user = User(**self.kwargs)
#         db.session.add(user)
#         db.session.commit()
# 
#         ResetUserPasswordService(user, self.password).call()
#         if self.generate_api_key:
#             GenerateUserApiKeyService(user).call()
# 
#         return user
# 
# Path: project/user/services/reset_user_password_service.py
# class ResetUserPasswordService:
# 
#     def __init__(self, user, new_password=b"password"):
#         self.user = user
#         self.new_password = new_password
# 
#     def call(self):
#         self.user.password = generate_password_hash(self.new_password).decode('utf-8')
#         db.session.commit()
#         return self.user.password
# 
# Path: project/user/services/delete_user_service.py
# class DeleteUserService:
# 
#     def __init__(self, user):
#         self.user = user
# 
#     def call(self):
#         db.session.delete(self.user)
#         db.session.commit()
#         return None


from mongoengine import ValidationError
from flask_bcrypt import check_password_hash
from flask_login import current_user, login_user
from project.tests.base import MVCTestCase
from project.user.services.create_user_service import CreateUserService
from project.user.services.reset_user_password_service import ResetUserPasswordService
from project.user.services.delete_user_service import DeleteUserService
import project.user.models as umodels
        self.assertEqual(repr(self.user), "<User: {}>".format(str(self.user)))

    def test_user_creation_method_and_model_fields(self):
        """
        Ensure when creating a User Object that the method used to create the user assigns all fields correctly
        """
        user = CreateUserService(username="my_username", password=b"my_password").call()
        self.assertEqual(user.username, "my_username")
        self.assertTrue(check_password_hash(user.password, "my_password"))

    def test_reset_password(self):
        """
        Ensure the reset password method is actually updating the password to the given one
        """
        self.assertTrue(check_password_hash(self.user.password, "password"))
        ResetUserPasswordService(self.user, "newpassword").call()
        self.user.save()
        self.user.reload()
        self.assertFalse(check_password_hash(self.user.password, "password"))
        self.assertTrue(check_password_hash(self.user.password, "newpassword"))

    def test_delete_user(self):
        """
        Ensure delete method is not actually deleting the editor, but only deletes it from the database if the flag
        "force" is given
        """
        self.assertEqual(1, umodels.User.objects.count())
        DeleteUserService(self.user).call()
        self.assertEqual(0, umodels.User.objects.count())
        self.assertEqual(1, umodels.User._objects.count())

# Path: project/tests/base.py
# class MVCTestCase(BaseTestCase):
#     """Default base test case for every
#     <Model|View|Controller(Form)>TestCase"""
#     pass
# 
# Path: project/user/services/create_user_service.py
# class CreateUserService:
# 
#     def __init__(self, username, password, generate_api_key=True, *args, **kwargs):
#         self.username = username
#         self.password = password
#         self.generate_api_key = generate_api_key
#         self.args = args
#         self.kwargs = kwargs
# 
#     def call(self):
#         self.kwargs.update(dict(username=self.username, password=self.password))
#         user = User(**self.kwargs)
#         db.session.add(user)
#         db.session.commit()
# 
#         ResetUserPasswordService(user, self.password).call()
#         if self.generate_api_key:
#             GenerateUserApiKeyService(user).call()
# 
#         return user
# 
# Path: project/user/services/reset_user_password_service.py
# class ResetUserPasswordService:
# 
#     def __init__(self, user, new_password=b"password"):
#         self.user = user
#         self.new_password = new_password
# 
#     def call(self):
#         self.user.password = generate_password_hash(self.new_password).decode('utf-8')
#         db.session.commit()
#         return self.user.password
# 
# Path: project/user/services/delete_user_service.py
# class DeleteUserService:
# 
#     def __init__(self, user):
#         self.user = user
# 
#     def call(self):
#         db.session.delete(self.user)
#         db.session.commit()
#         return None


# Path: project/user/tests/test_models.py
from mongoengine import ValidationError
from flask_bcrypt import check_password_hash
from flask_login import current_user, login_user
from project.tests.base import MVCTestCase
from project.user.services.create_user_service import CreateUserService
from project.user.services.reset_user_password_service import ResetUserPasswordService
from project.user.services.delete_user_service import DeleteUserService
import project.user.models as umodels

        self.assertEqual(repr(self.user), "<User: {}>".format(str(self.user)))

    def test_user_creation_method_and_model_fields(self):
        """
        Ensure when creating a User Object that the method used to create the user assigns all fields correctly
        """
        user = CreateUserService(username="my_username", password=b"my_password").call()
        self.assertEqual(user.username, "my_username")
        self.assertTrue(check_password_hash(user.password, "my_password"))

    def test_reset_password(self):
        """
        Ensure the reset password method is actually updating the password to the given one
        """
        self.assertTrue(check_password_hash(self.user.password, "password"))
        ResetUserPasswordService(self.user, "newpassword").call()
        self.user.save()
        self.user.reload()
        self.assertFalse(check_password_hash(self.user.password, "password"))
        self.assertTrue(check_password_hash(self.user.password, "newpassword"))

    def test_delete_user(self):
        """
        Ensure delete method is not actually deleting the editor, but only deletes it from the database if the flag
        "force" is given
        """
        self.assertEqual(1, umodels.User.objects.count())
        DeleteUserService(self.user).call()
        self.assertEqual(0, umodels.User.objects.count())
        self.assertEqual(1, umodels.User._objects.count())

        DeleteUserService(self.user, force=True).call()