# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse
# SPDX-License-Identifier: GPL-3.0-or-later

import os
import unittest

from ..bootstrap import Bootstrap
from ..display.display import Display
from ..display.display_manager import DisplayManager
from ..entities.friendly import Merchant, Sunflower
from ..entities.items import Bomb, Heart, Sword, Explosion
from ..entities.player import Player
from ..enums import DisplayActions
from ..game import Game, KeyValues, GameMode
from ..interfaces import Map
from ..menus import MainMenuValues
from ..resources import ResourceManager
from ..settings import Settings
from ..translations import gettext as _, Translator


class TestGame(unittest.TestCase):
    def setUp(self) -> None:
        """
        Setup game.
        """
        self.game = Game()
        self.game.new_game()
        self.game.map = Map.load(
            ResourceManager.get_asset_path("example_map.txt"))
        self.game.map.add_entity(self.game.player)
        self.game.player.move(self.game.map.start_y, self.game.map.start_x)
        self.game.logs.add_message("Hello World !")
        display = DisplayManager(None, self.game)
        self.game.display_actions = display.handle_display_action

    def test_load_game(self) -> None:
        """
        Save a game and reload it.
        """
        bomb = Bomb()
        self.game.map.add_entity(bomb)
        sword = Sword()
        self.game.map.add_entity(sword)
        # Add items in the inventory to check that it is well loaded
        bomb.hold(self.game.player)
        sword.hold(self.game.player)

        # Ensure that merchants can be saved
        merchant = Merchant()
        merchant.move(3, 6)
        self.game.map.add_entity(merchant)

        old_state = self.game.save_state()

        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertEqual(self.game.main_menu.validate(), MainMenuValues.SAVE)
        self.game.handle_key_pressed(KeyValues.ENTER)  # Save game
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertEqual(self.game.main_menu.validate(), MainMenuValues.LOAD)
        self.game.handle_key_pressed(KeyValues.ENTER)  # Load game

        new_state = self.game.save_state()
        self.assertEqual(old_state, new_state)

        # Ensure that the bomb is loaded
        self.assertTrue(self.game.player.inventory)

        # Error on loading save
        with open(ResourceManager.get_config_path("save.json"), "w") as f:
            f.write("I am not a JSON file")
        self.assertIsNone(self.game.message)
        self.game.load_game()
        self.assertIsNotNone(self.game.message)
        self.game.message = None

        with open(ResourceManager.get_config_path("save.json"), "w") as f:
            f.write("{}")
        self.assertIsNone(self.game.message)
        self.game.load_game()
        self.assertIsNotNone(self.game.message)
        self.game.message = None

        # Load game with a dead player
        self.game.map.remove_entity(self.game.player)
        self.game.save_game()
        self.game.load_game()
        self.assertIsNotNone(self.game.message)

    def test_bootstrap_fail(self) -> None:
        """
        Ensure that the test can't play the game,
        because there is no associated shell.
        Yeah, that's only for coverage.
        """
        self.assertRaises(Exception, Bootstrap.run_game)
        self.assertEqual(os.getenv("TERM", "unknown"), "unknown")

    def test_key_translation(self) -> None:
        """
        Test key bindings.
        """
        self.game.settings = Settings()

        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_UP_PRIMARY, self.game.settings),
            KeyValues.UP)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_UP_SECONDARY, self.game.settings),
            KeyValues.UP)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_DOWN_PRIMARY, self.game.settings),
            KeyValues.DOWN)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_DOWN_SECONDARY, self.game.settings),
            KeyValues.DOWN)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_LEFT_PRIMARY, self.game.settings),
            KeyValues.LEFT)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_LEFT_SECONDARY, self.game.settings),
            KeyValues.LEFT)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_RIGHT_PRIMARY, self.game.settings),
            KeyValues.RIGHT)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_RIGHT_SECONDARY, self.game.settings),
            KeyValues.RIGHT)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_ENTER, self.game.settings),
            KeyValues.ENTER)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_INVENTORY, self.game.settings),
            KeyValues.INVENTORY)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_CHAT, self.game.settings),
            KeyValues.CHAT)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_USE, self.game.settings),
            KeyValues.USE)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_EQUIP, self.game.settings),
            KeyValues.EQUIP)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_DROP, self.game.settings),
            KeyValues.DROP)
        self.assertEqual(KeyValues.translate_key(
            self.game.settings.KEY_WAIT, self.game.settings),
            KeyValues.WAIT)
        self.assertEqual(KeyValues.translate_key(' ', self.game.settings),
                         KeyValues.SPACE)
        self.assertEqual(KeyValues.translate_key('plop', self.game.settings),
                         None)

    def test_key_press(self) -> None:
        """
        Press a key and see what is done.
        """
        self.assertEqual(self.game.state, GameMode.MAINMENU)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.START)
        self.game.handle_key_pressed(KeyValues.UP)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.START)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.RESUME)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.SAVE)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.LOAD)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.SETTINGS)
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.state, GameMode.SETTINGS)

        self.game.handle_key_pressed(KeyValues.SPACE)
        self.assertEqual(self.game.state, GameMode.MAINMENU)

        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.EXIT)
        self.assertRaises(SystemExit, self.game.handle_key_pressed,
                          KeyValues.ENTER)

        self.game.handle_key_pressed(KeyValues.UP)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.SETTINGS)
        self.game.handle_key_pressed(KeyValues.UP)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.LOAD)
        self.game.handle_key_pressed(KeyValues.UP)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.SAVE)
        self.game.handle_key_pressed(KeyValues.UP)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.RESUME)
        self.game.handle_key_pressed(KeyValues.UP)
        self.assertEqual(self.game.main_menu.validate(),
                         MainMenuValues.START)

        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.state, GameMode.PLAY)

        # Kill entities
        for entity in self.game.map.entities.copy():
            if not isinstance(entity, Player):
                self.game.map.remove_entity(entity)

        y, x = self.game.player.y, self.game.player.x
        self.game.handle_key_pressed(KeyValues.DOWN)
        new_y, new_x = self.game.player.y, self.game.player.x
        self.assertEqual(new_y, y + 1)
        self.assertEqual(new_x, x)

        y, x = new_y, new_x
        self.game.handle_key_pressed(KeyValues.RIGHT)
        new_y, new_x = self.game.player.y, self.game.player.x
        self.assertEqual(new_y, y)
        self.assertEqual(new_x, x + 1)

        y, x = self.game.player.y, self.game.player.x
        self.game.handle_key_pressed(KeyValues.UP)
        new_y, new_x = self.game.player.y, self.game.player.x
        self.assertEqual(new_y, y - 1)
        self.assertEqual(new_x, x)

        y, x = self.game.player.y, self.game.player.x
        self.game.handle_key_pressed(KeyValues.LEFT)
        new_y, new_x = self.game.player.y, self.game.player.x
        self.assertEqual(new_y, y)
        self.assertEqual(new_x, x - 1)

        explosion = Explosion()
        self.game.map.add_entity(explosion)
        self.assertIn(explosion, self.game.map.entities)
        self.game.handle_key_pressed(KeyValues.WAIT)
        self.assertNotIn(explosion, self.game.map.entities)

        self.game.handle_key_pressed(KeyValues.SPACE)
        self.assertEqual(self.game.state, GameMode.MAINMENU)

    def test_mouse_click(self) -> None:
        """
        Simulate mouse clicks.
        """
        self.game.state = GameMode.MAINMENU

        # Change the color of the artwork
        self.game.display_actions(DisplayActions.MOUSE, 0, 10)

        # Settings menu
        self.game.display_actions(DisplayActions.MOUSE, 25, 21)
        self.assertEqual(self.game.main_menu.position, 4)
        self.assertEqual(self.game.state, GameMode.SETTINGS)

        bomb = Bomb()
        bomb.hold(self.game.player)
        bomb2 = Bomb()
        bomb2.hold(self.game.player)

        self.game.state = GameMode.INVENTORY

        # Click nowhere
        self.game.display_actions(DisplayActions.MOUSE, 0, 0)
        self.assertEqual(self.game.state, GameMode.INVENTORY)

        # Click on the second item
        self.game.display_actions(DisplayActions.MOUSE, 8, 25)
        self.assertEqual(self.game.state, GameMode.INVENTORY)
        self.assertEqual(self.game.inventory_menu.position, 1)

    def test_new_game(self) -> None:
        """
        Ensure that the start button starts a new game.
        """
        old_map = self.game.map
        old_player = self.game.player
        self.game.handle_key_pressed(KeyValues.ENTER)  # Start new game
        new_map = self.game.map
        new_player = self.game.player
        # Ensure that
        self.assertNotEqual(old_map, new_map)
        self.assertNotEqual(old_player, new_player)

        self.game.handle_key_pressed(KeyValues.SPACE)
        old_map = new_map
        old_player = new_player
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.ENTER)  # Resume game
        new_map = self.game.map
        new_player = self.game.player
        self.assertEqual(old_map, new_map)
        self.assertEqual(old_player, new_player)

    def test_settings_menu(self) -> None:
        """
        Ensure that the settings menu is working properly.
        """
        self.game.settings = Settings()

        # Open settings menu
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.state, GameMode.SETTINGS)

        # Define the "move up" key to 'h'
        self.assertFalse(self.game.settings_menu.waiting_for_key)
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertTrue(self.game.settings_menu.waiting_for_key)
        self.game.handle_key_pressed(None, 'h')
        self.assertFalse(self.game.settings_menu.waiting_for_key)
        self.assertEqual(self.game.settings.KEY_UP_PRIMARY, 'h')

        # Navigate to "move left"
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.UP)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)

        # Define the "move up" key to 'a'
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertTrue(self.game.settings_menu.waiting_for_key)
        # Can't used a mapped key
        self.game.handle_key_pressed(None, 's')
        self.assertTrue(self.game.settings_menu.waiting_for_key)
        self.game.handle_key_pressed(None, 'a')
        self.assertFalse(self.game.settings_menu.waiting_for_key)
        self.assertEqual(self.game.settings.KEY_LEFT_PRIMARY, 'a')

        # Navigate to "texture pack"
        for ignored in range(11):
            self.game.handle_key_pressed(KeyValues.DOWN)

        # Change texture pack
        self.assertEqual(self.game.settings.TEXTURE_PACK, "ascii")
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.settings.TEXTURE_PACK, "squirrel")
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.settings.TEXTURE_PACK, "ascii")

        # Change language
        Translator.compilemessages()
        Translator.refresh_translations()
        self.game.settings.LOCALE = "en"
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.settings.LOCALE, "fr")
        self.assertEqual(_("New game"), "Nouvelle partie")
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.settings.LOCALE, "de")
        self.assertEqual(_("New game"), "Neu Spiel")
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.settings.LOCALE, "es")
        self.assertEqual(_("New game"), "Nuevo partido")
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.settings.LOCALE, "en")
        self.assertEqual(_("New game"), "New game")

        # Navigate to "back" button
        self.game.handle_key_pressed(KeyValues.DOWN)

        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertEqual(self.game.state, GameMode.MAINMENU)

    def test_logs(self) -> None:
        """
        Tests the use of logs
        """
        self.assertEqual(self.game.logs.messages, ["Hello World !"])
        self.game.logs.add_messages(["Hello", "World"])
        self.assertEqual(self.game.logs.messages, ["Hello World !",
                                                   "Hello", "World"])
        self.game.logs.clear()
        self.assertEqual(self.game.logs.messages, [])

    def test_dead_screen(self) -> None:
        """
        Kill player and render dead screen.
        """
        self.game.state = GameMode.PLAY
        # Kill player
        self.game.player.take_damage(self.game.player,
                                     self.game.player.health + 2)
        y, x = self.game.player.y, self.game.player.x
        for key in [KeyValues.UP, KeyValues.DOWN,
                    KeyValues.LEFT, KeyValues.RIGHT]:
            self.game.handle_key_pressed(key)
            new_y, new_x = self.game.player.y, self.game.player.x
            self.assertEqual(new_y, y)
            self.assertEqual(new_x, x)

    def test_not_implemented(self) -> None:
        """
        Check that some functions are not implemented, only for coverage.
        """
        self.assertRaises(NotImplementedError, Display.display, None)
        self.assertRaises(NotImplementedError, Display.update, None, self.game)

    def test_messages(self) -> None:
        """
        Display error messages.
        """
        self.game.message = "I am an error"
        self.game.display_actions(DisplayActions.UPDATE)
        self.game.display_actions(DisplayActions.REFRESH)
        self.game.handle_key_pressed(None, "random key")
        self.assertIsNone(self.game.message)

    def test_inventory_menu(self) -> None:
        """
        Open the inventory menu and interact with items.
        """
        self.game.state = GameMode.PLAY
        # Open and close the inventory
        self.game.handle_key_pressed(KeyValues.INVENTORY)
        self.assertEqual(self.game.state, GameMode.INVENTORY)
        self.game.handle_key_pressed(KeyValues.SPACE)
        self.assertEqual(self.game.state, GameMode.PLAY)

        # Add five bombs in the inventory
        for ignored in range(5):
            bomb = Bomb()
            bomb.map = self.game.map
            bomb.map.add_entity(bomb)
            bomb.hold(self.game.player)

        self.game.handle_key_pressed(KeyValues.INVENTORY)
        self.assertEqual(self.game.state, GameMode.INVENTORY)

        # Navigate in the menu
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertEqual(self.game.inventory_menu.position, 3)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.UP)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertEqual(self.game.inventory_menu.position, 4)

        # Equip key does nothing
        self.game.handle_key_pressed(KeyValues.EQUIP)

        # Drop an item
        bomb = self.game.player.inventory[-1]
        self.assertEqual(self.game.inventory_menu.validate(), bomb)
        self.assertTrue(bomb.held)
        self.assertEqual(bomb.held_by, self.game.player)
        self.game.handle_key_pressed(KeyValues.DROP)
        self.assertFalse(bomb.held)
        self.assertIsNone(bomb.held_by)
        self.assertIsNone(bomb.owner)
        self.assertFalse(bomb.exploding)
        self.assertEqual(bomb.y, self.game.player.y)
        self.assertEqual(bomb.x, self.game.player.x)

        # Use the bomb
        bomb = self.game.player.inventory[-1]
        self.assertEqual(self.game.inventory_menu.validate(), bomb)
        self.assertTrue(bomb.held)
        self.assertEqual(bomb.held_by, self.game.player)
        self.game.handle_key_pressed(KeyValues.USE)
        self.assertFalse(bomb.held)
        self.assertIsNone(bomb.held_by)
        self.assertEqual(bomb.owner, self.game.player)
        self.assertTrue(bomb.exploding)
        self.assertEqual(bomb.y, self.game.player.y)
        self.assertEqual(bomb.x, self.game.player.x)

    def test_talk_to_sunflowers(self) -> None:
        """
        Interact with sunflowers
        """
        self.game.state = GameMode.PLAY

        sunflower = Sunflower()
        sunflower.move(2, 6)
        self.game.map.add_entity(sunflower)

        # Does nothing
        self.assertIsNone(self.game.handle_friendly_entity_chat(KeyValues.UP))

        # Talk to sunflower... or not
        self.game.handle_key_pressed(KeyValues.CHAT)
        self.assertTrue(self.game.waiting_for_friendly_key)
        # Wrong key
        self.game.handle_key_pressed(KeyValues.EQUIP)
        self.assertFalse(self.game.waiting_for_friendly_key)
        self.game.handle_key_pressed(KeyValues.CHAT)
        self.assertTrue(self.game.waiting_for_friendly_key)
        self.game.handle_key_pressed(KeyValues.UP)
        self.assertFalse(self.game.waiting_for_friendly_key)
        self.assertEqual(self.game.state, GameMode.PLAY)
        self.assertFalse(len(self.game.logs.messages) > 1)

        # Talk to sunflower
        self.game.handle_key_pressed(KeyValues.CHAT)
        self.assertTrue(self.game.waiting_for_friendly_key)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertFalse(self.game.waiting_for_friendly_key)
        self.assertEqual(self.game.state, GameMode.PLAY)
        self.assertTrue(self.game.logs.messages)
        # Ensure that the message is a good message
        self.assertTrue(any(self.game.logs.messages[1].endswith(msg)
                            for msg in Sunflower().dialogue_option))

        # Test all directions to detect the friendly entity
        self.game.player.move(3, 6)
        self.game.handle_key_pressed(KeyValues.CHAT)
        self.game.handle_key_pressed(KeyValues.UP)
        self.assertEqual(len(self.game.logs.messages), 3)
        self.game.player.move(2, 7)
        self.game.handle_key_pressed(KeyValues.CHAT)
        self.game.handle_key_pressed(KeyValues.LEFT)
        self.assertEqual(len(self.game.logs.messages), 4)
        self.game.player.move(2, 5)
        self.game.handle_key_pressed(KeyValues.CHAT)
        self.game.handle_key_pressed(KeyValues.RIGHT)
        self.assertEqual(len(self.game.logs.messages), 5)

    def test_talk_to_merchant(self) -> None:
        """
        Interact with merchants
        """
        self.game.state = GameMode.PLAY

        merchant = Merchant()
        merchant.move(2, 6)
        self.game.map.add_entity(merchant)

        # Does nothing
        self.assertIsNone(self.game.handle_friendly_entity_chat(KeyValues.UP))

        # Talk to merchant
        self.game.handle_key_pressed(KeyValues.CHAT)
        self.assertTrue(self.game.waiting_for_friendly_key)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.assertFalse(self.game.waiting_for_friendly_key)
        self.assertEqual(self.game.state, GameMode.STORE)
        self.assertTrue(self.game.logs.messages)

        # Navigate in the menu
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.DOWN)
        self.game.handle_key_pressed(KeyValues.LEFT)
        self.assertFalse(self.game.is_in_store_menu)
        self.game.handle_key_pressed(KeyValues.RIGHT)
        self.assertTrue(self.game.is_in_store_menu)
        self.game.handle_key_pressed(KeyValues.UP)
        self.assertEqual(self.game.store_menu.position, 1)

        self.game.player.hazel = 0x7ffff42ff

        # The second item is not a heart
        merchant.inventory[1] = sword = Sword()
        # Buy the second item by clicking on it
        item = self.game.store_menu.validate()
        self.assertIn(item, merchant.inventory)
        self.game.display_actions(DisplayActions.MOUSE, 7, 25)
        self.assertIn(item, self.game.player.inventory)
        self.assertNotIn(item, merchant.inventory)

        # Buy a heart
        merchant.inventory[1] = Heart()
        item = self.game.store_menu.validate()
        self.assertIn(item, merchant.inventory)
        self.assertEqual(item, merchant.inventory[1])
        self.game.player.health = self.game.player.maxhealth - 1 - item.healing
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertNotIn(item, self.game.player.inventory)
        self.assertNotIn(item, merchant.inventory)
        self.assertEqual(self.game.player.health,
                         self.game.player.maxhealth - 1)

        # We don't have enough of money
        self.game.player.hazel = 0
        item = self.game.store_menu.validate()
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertNotIn(item, self.game.player.inventory)
        self.assertIn(item, merchant.inventory)
        self.assertEqual(self.game.message,
                         _("The buyer does not have enough money"))
        self.game.handle_key_pressed(KeyValues.ENTER)

        # Sell an item
        self.game.inventory_menu.position = len(self.game.player.inventory) - 1
        self.game.handle_key_pressed(KeyValues.LEFT)
        self.assertFalse(self.game.is_in_store_menu)
        self.assertIn(sword, self.game.player.inventory)
        self.assertEqual(self.game.inventory_menu.validate(), sword)
        old_player_money, old_merchant_money = self.game.player.hazel,\
            merchant.hazel
        self.game.handle_key_pressed(KeyValues.ENTER)
        self.assertNotIn(sword, self.game.player.inventory)
        self.assertIn(sword, merchant.inventory)
        self.assertEqual(self.game.player.hazel, old_player_money + sword.price)
        self.assertEqual(merchant.hazel, old_merchant_money - sword.price)

        # Exit the menu
        self.game.handle_key_pressed(KeyValues.SPACE)
        self.assertEqual(self.game.state, GameMode.PLAY)