def setUp(self, mock_sql) -> None:
        self.mock_sql = mock_sql
        self.db = Database(db_location="test_database")

        self.game_values = 'Test game', '2', '5', '01:30', '30:00', 'queue'
        (self.game_name, self.min_players, self.max_players, self.round_time, self.game_time,
         self.game_type) = self.game_values
    def test_delete_game_by_name(self):
        Database.delete_game_by_name = MagicMock(
            return_value=self.test_game.get_parameters())

        self.dao.delete_game_by_name(self.test_game.game_name)

        Database.delete_game_by_name(self.test_game.game_name)
    def test_sqlite3_connect_with_side_affect(self):
        self._setup_mock_sqlite3_connect()

        db = Database(db_location='good_connection_string')
        self.assertTrue(db.connection)
        sqlite3.connect.assert_called_with('good_connection_string')

        db = Database(db_location='bad_connection_string')
        self.assertFalse(db.connection)
        sqlite3.connect.assert_called_with('bad_connection_string')
    def test_sqlite3_connect_fail(self):
        sqlite3.connect = MagicMock(return_value='connection failed')
        Database.get_cursor = MagicMock()

        db = Database(db_location="test_database")

        sqlite3.connect.assert_called_with('test_database')
        self.assertEqual(db.connection, 'connection failed')
    def create_db_schema():
        """
        Calls Database method to create 'games' table.

        :return:
        """

        with Database() as db:
            db.create_db_schema()
    def delete_game_by_name(game_name):
        """
        Pass delete game request to Database.delete_game_by_name()

        :param game_name: name of a game to delete.
        :return:
        """
        with Database() as db:
            db.delete_game_by_name(game_name)
    def update_game(game: Game):
        """
        Maps Game model to values and passes them to Database.update_game() method.

        :param game: game to update to database.
        :return:
        """

        (game_name, min_players, max_players, round_time, game_time,
         game_type) = game.get_parameters()

        with Database() as db:
            db.update_game(game_name=game_name,
                           min_players=min_players,
                           max_players=max_players,
                           round_time=round_time,
                           game_time=game_time,
                           game_type=game_type)
    def get_all_games():
        """
        Gets tuples of parameters from Database.get_all_games() and maps them to Game models.

        :return: all games stored in database, mapped to Game objects.
        """

        with Database() as db:
            games_tuples = db.get_all_games()

        games = []

        for game_tuple in games_tuples:
            game_name, min_players, max_players, round_time, game_time, game_type = game_tuple

            games.append(
                Game(game_name, min_players, max_players, round_time,
                     game_time, game_type))

        return games
    def get_game_by_name(game_namee):
        """
        Gets tuple of parameters from Database.get_game_by_name() and maps them to Game model.

        :param game_namee: name of the searching game.
        :return: found game as Game object.
        """

        try:
            with Database() as db:
                game_values = db.get_game_by_name(game_namee)

        except GameNotExistException as game_not_exist:
            raise GameNotExistException from game_not_exist

        game_name, min_players, max_players, round_time, game_time, game_type = game_values

        game = Game(game_name, min_players, max_players, round_time, game_time,
                    game_type)

        return game
    def add_game(game: Game):
        """
        Maps Game model to values and passes them to Database.add_game() method.

        :param game: game to add to database.
        :return:
        """

        (game_name, min_players, max_players, round_time, game_time,
         game_type) = game.get_parameters()

        try:
            with Database() as db:
                db.add_game(game_name=game_name,
                            min_players=min_players,
                            max_players=max_players,
                            round_time=round_time,
                            game_time=game_time,
                            game_type=game_type)
        except GameAlreadyExistsException as game_exists:
            raise GameAlreadyExistsException from game_exists
class DatabaseTest(unittest.TestCase):

    @patch('sqlite3.connect')
    def setUp(self, mock_sql) -> None:
        self.mock_sql = mock_sql
        self.db = Database(db_location="test_database")

        self.game_values = 'Test game', '2', '5', '01:30', '30:00', 'queue'
        (self.game_name, self.min_players, self.max_players, self.round_time, self.game_time,
         self.game_type) = self.game_values

    def test_sqlite3_connect_success(self):
        sqlite3.connect = MagicMock(return_value='connection succeeded')
        Database.get_cursor = MagicMock()

        db = Database(db_location="test_database")

        sqlite3.connect.assert_called_with('test_database')
        self.assertEqual(db.connection, 'connection succeeded')

    def test_sqlite3_connect_fail(self):
        sqlite3.connect = MagicMock(return_value='connection failed')
        Database.get_cursor = MagicMock()

        db = Database(db_location="test_database")

        sqlite3.connect.assert_called_with('test_database')
        self.assertEqual(db.connection, 'connection failed')

    def test_sqlite3_connect_with_side_affect(self):
        self._setup_mock_sqlite3_connect()

        db = Database(db_location='good_connection_string')
        self.assertTrue(db.connection)
        sqlite3.connect.assert_called_with('good_connection_string')

        db = Database(db_location='bad_connection_string')
        self.assertFalse(db.connection)
        sqlite3.connect.assert_called_with('bad_connection_string')

    @staticmethod
    def _setup_mock_sqlite3_connect():
        values = {'good_connection_string': True,
                  'bad_connection_string': False}

        def side_effect(arg):
            return values[arg]

        sqlite3.connect = Mock(side_effect=side_effect)

    def test_create_db_schema(self):
        self.db.connection.executescript = MagicMock()

        self.db.create_db_schema()

        with open(app_set.bgt_model_path) as bgt_model:
            self.db.connection.executescript.assert_called_once_with(bgt_model.read())

    def test_add_game(self):
        self.db.cursor.execute = MagicMock()

        self.db.add_game(game_name=self.game_name, min_players=self.min_players,
                         max_players=self.max_players, round_time=self.round_time,
                         game_time=self.game_time, game_type=self.game_type)

        self.db.cursor.execute.assert_called_once_with(q.ADD_GAME,
                                                       {'game_name': self.game_name,
                                                        'min_players': self.min_players,
                                                        'max_players': self.max_players,
                                                        'round_time': self.round_time,
                                                        'game_time': self.game_time,
                                                        'game_type': self.game_type}
                                                       )

    def test_get_game_by_name(self):
        self.db.cursor.execute = MagicMock()
        self.db.cursor.fetchone = MagicMock(return_value=self.game_values)

        game = self.db.get_game_by_name(self.game_name)

        self.db.cursor.execute.assert_called_once_with(q.GET_GAME_BY_NAME,
                                                       {'game_name': self.game_name})

        assert len(game) == 6

    def test_get_game_by_name_game_not_exist(self):
        self.db.cursor.execute = MagicMock(return_value=None)
        self.db.cursor.fetchone = MagicMock(return_value=None)

        with self.assertRaises(Exception):
            self.db.get_game_by_name(self.game_name)

        self.db.cursor.execute.assert_called_once_with(q.GET_GAME_BY_NAME,
                                                       {'game_name': self.game_name})

    def test_get_all_games(self):
        self.db.cursor.execute = MagicMock()
        self.db.cursor.fetchall = MagicMock(return_value=[self.game_values, self.game_values])

        self.db.get_all_games()

        self.db.cursor.execute.assert_called_once_with(q.GET_ALL_GAMES)

    def test_update_game(self):
        self.db.cursor.execute = MagicMock()

        self.db.update_game(game_name=self.game_name, min_players=self.min_players,
                            max_players=self.max_players, round_time=self.round_time,
                            game_time=self.game_time, game_type=self.game_type)

        self.db.cursor.execute.assert_called_once_with(q.UPDATE_GAME,
                                                       {'game_name': self.game_name,
                                                        'min_players': self.min_players,
                                                        'max_players': self.max_players,
                                                        'round_time': self.round_time,
                                                        'game_time': self.game_time,
                                                        'game_type': self.game_type}
                                                       )

    def test_delete_game_by_name(self):
        self.db.cursor.execute = MagicMock()

        self.db.delete_game_by_name(self.game_name)

        self.db.cursor.execute.assert_called_once_with(q.DELETE_GAME,
                                                       {'game_name': self.game_name})