"""Module to test the User Data Model"""

import unittest
from app.models import User, Database, orderCategory
from app import utilities


class UserTest(unittest.TestCase):
    """Tests for the User data model"""

    def setUp(self):
        """
        Set up variables that will be used in most tests
        """
        self.user_data = {
            'key': 1,
            'first_name': 'John',
            'last_name': 'Doe',
            'email': '<EMAIL>',
            'password': 'password',
            }
        self.user = User(**self.user_data)
        self.db = Database()
        self.category_data = {
            'name': 'cakes',
            'description': 'all orders cake!',
        }

    def test_user_can_be_created(self):
        """User can be created"""
        user = User(**self.user_data)
        self.assertIsInstance(user, User)
        self.assertRaises(TypeError, User, key=3)
        del(self.user_data['password'])
        self.assertRaises(TypeError, User, **self.user_data)
    
    def test_first_name_is_string(self):
        """The first name should be a string"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'first_name', 3)
        self.assertRaises(TypeError, User, **invalid_data)

    def test_last_name_is_string(self):
        """The last name should be a string"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'last_name', 3)
        self.assertRaises(TypeError, User, **invalid_data)

    def test_email_is_string(self):
        """The email should be a string"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'email', 3)
        self.assertRaises(TypeError, User, **invalid_data)

    def test_email_is_right_format(self):
        """The email should be in the format <EMAIL>"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'email', 'hello')
        self.assertRaises(ValueError, User, **invalid_data)

    def test_password_is_string(self):
        """The password should be a string"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'password', 3)
        self.assertRaises(TypeError, User, **invalid_data)

    def test_key_is_int(self):
        """The key should be an int"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'key', 'string_key')
        self.assertRaises(TypeError, User, **invalid_data)

    def test_user_can_be_saved(self):
        """User can be saved in Database"""
        self.assertRaises(TypeError, self.user.save,
                          'Database object expected')
        self.user.save(self.db)
        length_of_user_keys = len(self.db.user_keys)
        self.assertIn(self.user.key, self.db.user_keys)
        self.assertEqual(self.user, self.db.users[self.user.key])
        self.assertIn(self.user.email, self.db.user_email_key_map.keys())
        self.assertEqual(self.user.key, self.db.user_email_key_map[self.user.email])
        # calling save more than once does not increase size of self.db.user_keys
        self.user.save(self.db)
        self.assertEqual(len(self.db.user_keys), length_of_user_keys)

    def test_user_can_create_categories(self):
        """User can create order categories"""
        category = self.user.create_order_category(self.db, self.category_data)
        self.assertIsInstance(category, orderCategory)
        self.assertIn(category.key, self.user.order_categories)
        self.assertIn(category.key, self.db.order_category_keys)
        self.assertEqual(category, self.db.order_categories[category.key])
        self.assertIn(category.name, self.db.order_category_name_key_map.keys())
        self.assertEqual(category.key,
                          self.db.order_category_name_key_map[category.name])
        self.assertRaises(TypeError, self.user.create_order_category, 
                          'database should be a Database object', self.category_data)
        del(self.category_data['name'])
        category = self.user.create_order_category(self.db, self.category_data)
        self.assertIsNone(category)
    
    def test_user_can_get_categories(self):
        """User can get a list of their order categories"""        
        names = ('cakes', 'bread', 'juice')
        # create three categories
        created_categories = []
        key = 2
        # save user in db
        self.user.save(self.db)
        for name in names:
            new_data = utilities.replace_value_in_dict(self.category_data, 'name', name)
            new_category = orderCategory(**new_data, key=key, user=self.user.key)
            new_category.save(self.db)
            created_categories.append(new_category)
            key += 1

        categories = self.user.get_all_order_categories(self.db)
        self.assertIsInstance(categories, list)
        self.assertEqual(len(self.user.order_categories), len(categories))
        self.assertListEqual(created_categories, categories)
        self.assertRaises(TypeError, self.user.get_all_order_categories,
                          'expected Database object not string')


    def test_user_can_delete_categories(self):
        """User can delete order categories"""
        pass




if __name__ == '__main__':
    unittest.main()
"""Module to test the User Data Model"""

import unittest
from app.models import User, Database, orderCategory
from app import utilities


class UserTest(unittest.TestCase):
    """Tests for the User data model"""

    def setUp(self):
        """
        Set up variables that will be used in most tests
        """
        self.user_data = {
            'key': 1,
            'first_name': 'John',
            'last_name': 'Doe',
            'email': '<EMAIL>',
            'password': 'password',
            }
        self.user = User(**self.user_data)
        self.db = Database()
        self.category_data = {
            'name': 'cakes',
            'description': 'all orders cake!',
        }

    def test_user_can_be_created(self):
        """User can be created"""
        user = User(**self.user_data)
        self.assertIsInstance(user, User)
        self.assertRaises(TypeError, User, key=3)
        del(self.user_data['password'])
        self.assertRaises(TypeError, User, **self.user_data)
    
    def test_first_name_is_string(self):
        """The first name should be a string"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'first_name', 3)
        self.assertRaises(TypeError, User, **invalid_data)

    def test_last_name_is_string(self):
        """The last name should be a string"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'last_name', 3)
        self.assertRaises(TypeError, User, **invalid_data)

    def test_email_is_string(self):
        """The email should be a string"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'email', 3)
        self.assertRaises(TypeError, User, **invalid_data)

    def test_email_is_right_format(self):
        """The email should be in the format <EMAIL>"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'email', 'hello')
        self.assertRaises(ValueError, User, **invalid_data)

    def test_password_is_string(self):
        """The password should be a string"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'password', 3)
        self.assertRaises(TypeError, User, **invalid_data)

    def test_key_is_int(self):
        """The key should be an int"""
        invalid_data = utilities.replace_value_in_dict(self.user_data, 'key', 'string_key')
        self.assertRaises(TypeError, User, **invalid_data)

    def test_user_can_be_saved(self):
        """User can be saved in Database"""
        self.assertRaises(TypeError, self.user.save,
                          'Database object expected')
        self.user.save(self.db)
        length_of_user_keys = len(self.db.user_keys)
        self.assertIn(self.user.key, self.db.user_keys)
        self.assertEqual(self.user, self.db.users[self.user.key])
        self.assertIn(self.user.email, self.db.user_email_key_map.keys())
        self.assertEqual(self.user.key, self.db.user_email_key_map[self.user.email])
        # calling save more than once does not increase size of self.db.user_keys
        self.user.save(self.db)
        self.assertEqual(len(self.db.user_keys), length_of_user_keys)

    def test_user_can_create_categories(self):
        """User can create order categories"""
        category = self.user.create_order_category(self.db, self.category_data)
        self.assertIsInstance(category, orderCategory)
        self.assertIn(category.key, self.user.order_categories)
        self.assertIn(category.key, self.db.order_category_keys)
        self.assertEqual(category, self.db.order_categories[category.key])
        self.assertIn(category.name, self.db.order_category_name_key_map.keys())
        self.assertEqual(category.key,
                          self.db.order_category_name_key_map[category.name])
        self.assertRaises(TypeError, self.user.create_order_category, 
                          'database should be a Database object', self.category_data)
        del(self.category_data['name'])
        category = self.user.create_order_category(self.db, self.category_data)
        self.assertIsNone(category)
    
    def test_user_can_get_categories(self):
        """User can get a list of their order categories"""        
        names = ('cakes', 'bread', 'juice')
        # create three categories
        created_categories = []
        key = 2
        # save user in db
        self.user.save(self.db)
        for name in names:
            new_data = utilities.replace_value_in_dict(self.category_data, 'name', name)
            new_category = orderCategory(**new_data, key=key, user=self.user.key)
            new_category.save(self.db)
            created_categories.append(new_category)
            key += 1

        categories = self.user.get_all_order_categories(self.db)
        self.assertIsInstance(categories, list)
        self.assertEqual(len(self.user.order_categories), len(categories))
        self.assertListEqual(created_categories, categories)
        self.assertRaises(TypeError, self.user.get_all_order_categories,
                          'expected Database object not string')


    def test_user_can_delete_categories(self):
        """User can delete order categories"""
        pass




if __name__ == '__main__':
    unittest.main()
Module to test the User Data Model Tests for the User data model Set up variables that will be used in most tests User can be created The first name should be a string The last name should be a string The email should be a string The email should be in the format <EMAIL> The password should be a string The key should be an int User can be saved in Database # calling save more than once does not increase size of self.db.user_keys User can create order categories User can get a list of their order categories # create three categories # save user in db User can delete order categories