def setUp(self):
     self.game = Game()
     self.character = Character('Alice')
     self.other_character = Character('Bob')
     self.game.add_character(self.character)
     self.game.add_character(self.other_character)
     self.game.setup_game(self.settings)
class CharacterSerialisationTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.settings = config.get_settings(SETTINGS_LOCATION, refresh=True)

    def setUp(self):
        random.seed(42)
        self.game = Game()
        self.character = Character('Alice')
        self.game.add_character(self.character)
        self.game.setup_game(self.settings)
        self.character.set_location('London')
        self.character.action_count = 4
        self.character.hand = [
            PlayerCard('London', 'Blue'),
            PlayerCard('New York', 'Yellow')
        ]

    def test_character_to_dict(self):
        output = BaseFormatter.character_to_dict(self.character)
        self.assertEqual('Alice', output['name'])
        self.assertEqual(4, output['action_count'])
        self.assertEqual(2, len(output['hand']))
        self.assertEqual('London', output['hand'][0]['name'])
        self.assertEqual('London', output['location'])
Example #3
0
 def setUp(self):
     random.seed(42)
     self.character1 = Character('Evie')
     self.character2 = Character('Amelia')
     self.pg = Game()
     self.pg.add_character(self.character1)
     self.pg.add_character(self.character2)
     self.pg.setup_game(self.settings)
 def setUp(self):
     random.seed(42)
     self.game = Game()
     self.character = Character('Alice')
     self.game.add_character(self.character)
     self.game.setup_game(self.settings)
     self.character.set_location('London')
     self.character.action_count = 4
     self.character.hand = [
         PlayerCard('London', 'Blue'),
         PlayerCard('New York', 'Yellow')
     ]
    def setUp(self):
        random.seed(42)
        self.character1 = Character('Evie')
        self.character2 = Character('Amelia')
        self.pg = Game()
        self.pg.add_character(self.character1)
        self.pg.add_character(self.character2)
        self.pg.setup_game(self.settings)
        self.pg.start_game()

        top_player_card = self.pg.player_deck.take_top_card()
        top_infect_card = self.pg.infect_deck.take_top_card()
        self.pg.player_deck.discard.append(top_player_card)
        self.pg.infect_deck.discard.append(top_infect_card)
        self.pg.active_character = 'Evie'
class GameStateSerialisationCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.settings = config.get_settings(SETTINGS_LOCATION, refresh=True)

    def setUp(self):
        random.seed(42)
        self.character1 = Character('Evie')
        self.character2 = Character('Amelia')
        self.pg = Game()
        self.pg.add_character(self.character1)
        self.pg.add_character(self.character2)
        self.pg.setup_game(self.settings)
        self.pg.start_game()

        top_player_card = self.pg.player_deck.take_top_card()
        top_infect_card = self.pg.infect_deck.take_top_card()
        self.pg.player_deck.discard.append(top_player_card)
        self.pg.infect_deck.discard.append(top_infect_card)
        self.pg.active_character = 'Evie'

    def test_game_to_dict(self):
        output = BaseFormatter.game_to_dict(self.pg)
        self.assertEqual(2, len(output['characters']))
        self.assertEqual('Evie', output['characters'][0]['name'])
        self.assertEqual('Amelia', output['characters'][1]['name'])
        # other subdicts are tested for character_to_dict()

        self.assertEqual(1, len(output['player_deck_discard']))
        self.assertEqual(10, len(output['infect_deck_discard']))  # 9 start + 1
        self.assertEqual('Plymouth', output['player_deck_discard'][0]['name'])
        self.assertEqual('Tula', output['infect_deck_discard'][9]['name'])

        self.assertEqual(4, len(output['diseases']))
        self.assertEqual('Blue', output['diseases']['Blue']['colour'])
        # other subdicts are tested for disease_to_dict()

        self.assertEqual(40, len(output['cities']))
        self.assertTrue(output['cities']['London']['has_lab'])
        self.assertFalse(output['cities']['Moscow']['has_lab'])
        self.assertEqual('London', output['cities']['London']['name'])
        # other subdicts are tested for city_to_dict()

        self.assertEqual(2, output['infection_rate'])
        self.assertEqual(0, output['epidemic_count'])
        self.assertEqual('Evie', output['active_character'])
class CharacterTestCase(TestCase):
    @classmethod
    def setUpClass(cls):
        # without this method the production config is cached
        cls.settings = config.get_settings(SETTINGS_LOCATION, refresh=True)

    def setUp(self):
        self.game = Game()
        self.character = Character('Alice')
        self.other_character = Character('Bob')
        self.game.add_character(self.character)
        self.game.add_character(self.other_character)
        self.game.setup_game(self.settings)

    def test_init(self):
        character = Character('Bob')
        self.assertEqual('Bob', character.name)
        self.assertIsNone(character.location)
        self.assertEqual([], character.hand)
        self.assertEqual(0, character.action_count)

    def test_get_card(self):
        self.character.hand = [
            PlayerCard('London', 'Blue'),
            PlayerCard('New York', 'Yellow')
        ]

        card = self.character.get_card('London')
        self.assertIs(self.character.hand[0], card)

        with self.assertRaises(ValueError):
            self.character.get_card('Moscow')

    def test_add_card(self):
        top_player_card = self.game.player_deck.take_top_card()
        self.character.add_card(top_player_card)
        self.assertEqual(1, len(self.character.hand))
        self.assertTrue(self.character.hand_contains('London'))

    def test_hand_contains(self):
        self.character.hand = [
            PlayerCard('London', 'Blue'),
            PlayerCard('New York', 'Yellow')
        ]

        self.assertTrue(self.character.hand_contains('New York'))
        self.assertFalse(self.character.hand_contains('Oxford'))

    def test_discard_card(self):
        self.game.draw_card(self.character)
        card = self.character.hand[0]

        success = self.character.discard_card(card.name)
        self.assertTrue(success)
        self.assertIn(card, self.game.player_deck.discard)
        self.assertNotIn(card, self.character.hand)

        self.assertFalse(self.character.discard_card('Moscow'))

    def test_set_location(self):
        city = self.game.city_map['London']
        self.character.set_location('London')
        self.assertIs(city, self.character.location)

    def test_check_charter_flight(self):
        self.character.set_location('London')
        self.assertFalse(self.character.check_charter_flight('London'))

        self.character.action_count = 1
        self.assertFalse(self.character.check_charter_flight('London'))

        self.character.hand = [
            PlayerCard('London', 'Blue'),
            PlayerCard('Moscow', 'Black')
        ]
        self.assertTrue(self.character.check_charter_flight('London'))
        self.assertFalse(self.character.check_charter_flight('Moscow'))

        self.character.action_count = 0
        self.assertFalse(self.character.check_charter_flight('London'))

        self.character.action_count = 1
        self.character.set_location('Moscow')
        self.assertFalse(self.character.check_charter_flight('London'))

    def test_charter_flight(self):
        self.character.set_location('London')
        self.character.action_count = 4
        self.game.draw_card(self.character)
        card = self.character.hand[0]

        success = self.character.charter_flight(card.name, 'New York')
        self.assertTrue(success)
        self.assertIn(card, self.game.player_deck.discard)
        self.assertNotIn(card, self.character.hand)
        self.assertEqual('New York', self.character.location.name)
        self.assertEqual(3, self.character.action_count)

        success = self.character.charter_flight('New York', 'Brighton')
        self.assertFalse(success)
        self.assertEqual(1, len(self.game.player_deck.discard))
        self.assertIn(card, self.game.player_deck.discard)
        self.assertEqual(3, self.character.action_count)
        self.assertEqual('New York', self.character.location.name)

    def test_check_direct_flight(self):
        self.character.set_location('London')
        self.character.hand = [PlayerCard('Moscow', 'Black')]
        self.character.action_count = 4

        self.assertFalse(self.character.check_direct_flight(
            'London', 'Bejing'))
        self.assertTrue(self.character.check_direct_flight('London', 'Moscow'))
        self.assertFalse(
            self.character.check_direct_flight('New York', 'Moscow'))

        self.character.action_count = 0
        self.assertFalse(self.character.check_direct_flight(
            'London', 'Moscow'))

    def test_direct_flight(self):
        self.character.set_location('Moscow')
        self.character.action_count = 4
        self.game.draw_card(self.character)
        card = self.character.hand[0]

        success = self.character.direct_flight('Moscow', card.name)
        self.assertTrue(success)
        self.assertIn(card, self.game.player_deck.discard)
        self.assertNotIn(card, self.character.hand)
        self.assertEqual(card.name, self.character.location.name)
        self.assertEqual(3, self.character.action_count)

        success = self.character.direct_flight('London', 'Brighton')
        self.assertFalse(success)
        self.assertEqual(1, len(self.game.player_deck.discard))
        self.assertIn(card, self.game.player_deck.discard)
        self.assertEqual(3, self.character.action_count)
        self.assertEqual(card.name, self.character.location.name)

    def test_check_cure_disease(self):
        for i in range(9):
            self.game.draw_card(self.character)
        location = self.game.city_map['London']
        self.character.set_location('London')

        card_names = [
            'Oxford', 'Cambridge', 'Brighton', 'Southampton', 'Bristol'
        ]
        self.assertFalse(self.character.check_cure_disease(*card_names))

        location.has_lab = True
        self.assertFalse(self.character.check_cure_disease(*card_names))

        self.character.action_count = 4
        self.assertTrue(self.character.check_cure_disease(*card_names))

        card_names[3] = 'Moscow'
        self.assertFalse(self.character.check_cure_disease(*card_names))

        card_names[3] = 'Oxford'
        self.assertFalse(self.character.check_cure_disease(*card_names))

    def test_cure_disease(self):
        for i in range(9):
            self.game.draw_card(self.character)
        location = self.game.city_map['London']
        self.character.set_location('London')

        self.game.diseases['Blue'].cured = False
        location.has_lab = True
        self.character.action_count = 4
        card_names = [
            'Cambridge', 'Liverpool', 'Brighton', 'Southampton', 'Manchester'
        ]

        success = self.character.cure_disease(*card_names)
        self.assertTrue(success)
        self.assertTrue(self.game.diseases['Blue'].cured)
        self.assertEqual(3, self.character.action_count)
        for card_name in card_names:
            with self.subTest(card_name=card_name):
                self.assertFalse(self.character.hand_contains(card_name))
                self.assertTrue(
                    any(card.name == card_name
                        for card in self.game.player_deck.discard))

        self.assertFalse(self.character.cure_disease(*card_names))
        self.assertEqual(3, self.character.action_count)

    def test_game_won(self):
        for i in range(9):
            self.game.draw_card(self.character)
        location = self.game.city_map['London']
        self.character.set_location('London')

        self.game.diseases['Blue'].cured = False
        self.game.diseases['Black'].cured = True
        self.game.diseases['Red'].cured = True
        self.game.diseases['Yellow'].cured = True
        location.has_lab = True
        self.character.action_count = 4
        card_names = [
            'Cambridge', 'Liverpool', 'Brighton', 'Southampton', 'Manchester'
        ]

        with self.assertRaises(GameCrisisException):
            success = self.character.cure_disease(*card_names)

    def test_check_share_knowledge(self):
        self.character.hand = [
            PlayerCard('London', 'Blue'),
            PlayerCard('Moscow', 'Black')
        ]

        self.character.set_location('London')
        self.other_character.set_location('London')
        self.assertFalse(
            self.character.check_share_knowledge('London',
                                                 self.other_character))

        self.character.action_count = 4
        self.assertTrue(
            self.character.check_share_knowledge('London',
                                                 self.other_character))
        self.assertFalse(
            self.character.check_share_knowledge('Moscow',
                                                 self.other_character))

        self.assertFalse(
            self.character.check_share_knowledge('London', self.character))

        self.other_character.hand.append(self.character.hand.pop(0))
        self.assertTrue(
            self.character.check_share_knowledge('London',
                                                 self.other_character))

        self.other_character.set_location('New York')
        self.assertFalse(
            self.character.check_share_knowledge('London',
                                                 self.other_character))

        self.character.set_location('New York')
        self.assertFalse(
            self.character.check_share_knowledge('New York',
                                                 self.other_character))

    def test_share_knowledge(self):
        shared_card = PlayerCard('London', 'Blue')
        unshared_card = PlayerCard('Moscow', 'Black')
        self.character.hand = [shared_card, unshared_card]

        self.character.set_location('London')
        self.other_character.set_location('London')
        self.character.action_count = 4

        success = self.character.share_knowledge('London',
                                                 self.other_character)
        self.assertTrue(success)
        self.assertNotIn(shared_card, self.character.hand)
        self.assertIn(shared_card, self.other_character.hand)
        self.assertEqual(3, self.character.action_count)

        success = self.character.share_knowledge('London',
                                                 self.other_character)
        self.assertTrue(success)
        self.assertNotIn(shared_card, self.other_character.hand)
        self.assertIn(shared_card, self.character.hand)
        self.assertEqual(2, self.character.action_count)

        success = self.character.share_knowledge('Moscow',
                                                 self.other_character)
        self.assertFalse(success)
        self.assertNotIn(unshared_card, self.other_character.hand)
        self.assertIn(unshared_card, self.character.hand)
        self.assertEqual(2, self.character.action_count)

    def test_check_treat_disease(self):
        self.game.infect_city('London', 'Blue')
        self.game.infect_city('London', 'Blue')

        self.character.set_location('London')
        self.assertFalse(self.character.check_treat_disease('Blue'))

        self.character.action_count = 4
        self.assertTrue(self.character.check_treat_disease('Blue'))
        self.assertFalse(self.character.check_treat_disease('Red'))

    def test_treat_disease_no_cure(self):
        location = self.game.city_map['London']
        self.character.set_location('London')
        self.character.action_count = 4
        location.infection_levels['Blue'] = 3
        initial_resistance = self.game.diseases['Blue'].public_health

        success = self.character.treat_disease('Blue')
        self.assertTrue(success)
        self.assertEqual(2, location.infection_levels['Blue'])
        self.assertEqual(initial_resistance + 1,
                         self.game.diseases['Blue'].public_health)
        self.assertEqual(3, self.character.action_count)

        initial_resistance = self.game.diseases['Red'].public_health
        success = self.character.treat_disease('Red')
        self.assertFalse(success)
        self.assertEqual(2, location.infection_levels['Blue'])
        self.assertEqual(initial_resistance,
                         self.game.diseases['Red'].public_health)
        self.assertEqual(3, self.character.action_count)

        self.character.action_count = 0
        success = self.character.treat_disease('Blue')
        self.assertFalse(success)
        self.assertEqual(2, location.infection_levels['Blue'])

    def test_treat_disease_cure(self):
        self.game.diseases['Blue'].cured = True
        location = self.game.city_map['London']
        self.character.set_location('London')
        self.character.action_count = 4
        location.infection_levels['Blue'] = 3

        success = self.character.treat_disease('Blue')
        self.assertTrue(success)
        self.assertEqual(0, location.infection_levels['Blue'])
        self.assertEqual(3, self.character.action_count)

        location.infection_levels['Blue'] = 3
        success = self.character.treat_disease('Red')
        self.assertFalse(success)
        self.assertEqual(3, location.infection_levels['Blue'])
        self.assertEqual(3, self.character.action_count)

        self.character.action_count = 0
        success = self.character.treat_disease('Blue')
        self.assertFalse(success)
        self.assertEqual(3, location.infection_levels['Blue'])

    def test_check_shuttle_flight(self):
        self.character.set_location('London')
        self.character.action_count = 4

        location = self.game.city_map['London']
        destination = self.game.city_map['Tula']
        location.has_lab = True
        destination.has_lab = True
        self.assertTrue(self.character.check_shuttle_flight('London', 'Tula'))
        self.assertFalse(self.character.check_shuttle_flight('London', 'Tver'))

        destination.has_lab = False
        self.assertFalse(self.character.check_shuttle_flight('London', 'Tula'))

        destination.has_lab = True
        self.character.set_location('New York')
        self.assertFalse(self.character.check_shuttle_flight('London', 'Tula'))

        self.character.set_location('London')
        self.character.action_count = 0
        self.assertFalse(self.character.check_shuttle_flight('London', 'Tula'))

    def test_shuttle_flight(self):
        location = self.game.city_map['London']
        destination = self.game.city_map['Tula']
        location.has_lab = True
        destination.has_lab = True
        self.character.set_location('London')
        self.character.action_count = 4

        success = self.character.shuttle_flight('London', 'Tula')
        self.assertTrue(success)
        self.assertEqual(3, self.character.action_count)
        self.assertEqual('Tula', self.character.location.name)

        success = self.character.shuttle_flight('Tula', 'Moscow')
        self.assertFalse(success)
        self.assertEqual(3, self.character.action_count)
        self.assertEqual('Tula', self.character.location.name)

    def test_check_build_lab(self):
        location = self.game.city_map['London']
        location.has_lab = False

        self.character.set_location('London')
        self.character.action_count = 4

        self.character.hand = [
            PlayerCard('London', 'Blue'),
            PlayerCard('Moscow', 'Black')
        ]

        self.assertTrue(self.character.check_build_lab())

        self.character.action_count = 0
        self.assertFalse(self.character.check_build_lab())

        self.character.action_count = 4
        location.has_lab = True
        self.assertFalse(self.character.check_build_lab())

        location.has_lab = False
        self.character.hand = []
        self.assertFalse(self.character.check_build_lab())

    def test_build_lab(self):
        location = self.game.city_map['London']
        location.has_lab = False
        card = PlayerCard('London', 'Blue')
        self.character.hand.append(card)
        self.character.set_location('London')
        self.character.action_count = 4

        success = self.character.build_lab()
        self.assertTrue(success)
        self.assertEqual(3, self.character.action_count)
        self.assertTrue(location.has_lab)
        self.assertNotIn(card, self.character.hand)
        self.assertIn(card, self.game.player_deck.discard)

        location = self.game.city_map['Moscow']
        lab_status = location.has_lab
        card = PlayerCard('Moscow', 'Black')
        self.character.hand.append(card)
        self.character.set_location('Moscow')
        self.character.action_count = 0

        success = self.character.build_lab()
        self.assertFalse(success)
        self.assertIn(card, self.character.hand)
        self.assertNotIn(card, self.game.player_deck.discard)
        self.assertEqual(0, self.character.action_count)
        self.assertEqual(lab_status, location.has_lab)

    def test_check_standard_move(self):
        self.character.set_location('London')
        self.character.action_count = 4

        self.assertTrue(
            self.character.check_standard_move('London', 'Brighton'))
        self.assertFalse(
            self.character.check_standard_move('Brighton', 'London'))
        self.assertFalse(self.character.check_standard_move('London', 'Tula'))

        self.character.action_count = 0
        self.assertFalse(
            self.character.check_standard_move('London', 'Brighton'))

    def test_standard_move(self):
        self.character.set_location('London')
        self.character.action_count = 4

        success = self.character.standard_move('London', 'Brighton')
        self.assertTrue(success)
        self.assertEqual(3, self.character.action_count)
        self.assertEqual('Brighton', self.character.location.name)

        success = self.character.standard_move('New York', 'London')
        self.assertFalse(success)
        self.assertEqual(3, self.character.action_count)
        self.assertEqual('Brighton', self.character.location.name)

        success = self.character.standard_move('Brighton', 'New York')
        self.assertFalse(success)
        self.assertEqual(3, self.character.action_count)
        self.assertEqual('Brighton', self.character.location.name)

        self.character.action_count = 0
        success = self.character.standard_move('Brighton', 'London')
        self.assertFalse(success)
        self.assertEqual('Brighton', self.character.location.name)
Example #8
0
 def setUp(self):
     self.pg = Game()
     self.pg.settings = self.settings
Example #9
0
class GameSetupTestCase(TestCase):
    @classmethod
    def setUpClass(cls):
        cls.settings = config.get_settings(SETTINGS_LOCATION, refresh=True)

    def setUp(self):
        self.pg = Game()
        self.pg.settings = self.settings

    def test_add_character(self):
        characters = [Character('Evie'), Character('Amelia')]

        for character in characters:
            self.pg.add_character(character)

            with self.subTest(character=character):
                self.assertIs(self.pg, character.game)
                self.assertIn(character, self.pg.characters)
                self.assertEqual(character.name, self.pg.characters[-1].name)

    def test_get_infection_rate(self):
        self.pg.get_infection_rate()
        self.assertEqual(2, self.pg.infection_rate)

    def test_get_new_city_map(self):
        self.pg.get_new_city_map()

        self.assertEqual(40, len(self.pg.city_map))
        self.assertIn('London', self.pg.city_map)

        city = self.pg.city_map['London']
        self.assertEqual('London', city.name)
        self.assertEqual('Blue', city.colour)
        self.assertEqual('Yellow', self.pg.city_map['Washington'].colour)

        self.assertEqual(6, len(city.connected_cities))
        self.assertIn(self.pg.city_map['Washington'], city.connected_cities)
        self.assertNotIn(self.pg.city_map['Liverpool'], city.connected_cities)

    def test_create_cities(self):
        self.pg.create_cities()

        self.assertEqual(40, len(self.pg.city_map))
        self.assertIn('London', self.pg.city_map)

        city = self.pg.city_map['London']
        self.assertEqual('London', city.name)
        self.assertEqual('Blue', city.colour)
        self.assertEqual('Yellow', self.pg.city_map['Washington'].colour)

    def test_connect_cities(self):
        self.pg.create_cities()
        self.pg.connect_cities()
        city = self.pg.city_map['London']

        self.assertEqual(6, len(city.connected_cities))
        self.assertIn(self.pg.city_map['Washington'], city.connected_cities)
        self.assertNotIn(self.pg.city_map['Liverpool'], city.connected_cities)

    def test_get_new_decks(self):
        self.pg.player_deck = PlayerDeck()
        self.pg.infect_deck = InfectDeck()

        self.pg.get_new_city_map()
        self.pg.get_new_decks()

        deck = self.pg.player_deck
        self.assertEqual('London', deck.cards[0].name)
        self.assertEqual('Black', deck.cards[29].colour)

        deck = self.pg.infect_deck
        self.assertEqual('London', deck.cards[0].name)
        self.assertEqual('Black', deck.cards[29].colour)

    def test_get_new_diseases(self):
        self.pg.get_new_diseases()

        self.assertEqual('Red', self.pg.diseases['Red'].colour)
        self.assertEqual(30, self.pg.diseases['Blue'].public_health)

    def test_set_starting_epidemics(self):
        self.pg.set_starting_epidemics()
        self.assertEqual(4, self.pg.starting_epidemics)

    def test_setup_game(self):
        del self.pg.settings

        characters = [Character('Evie'), Character('Amelia')]
        for character in characters:
            self.pg.add_character(character)

        self.pg.setup_game(self.settings)

        self.assertEqual(self.pg.settings, self.settings)

        self.assertEqual(0, self.pg.epidemic_count)
        self.assertEqual(0, self.pg.outbreak_count)
        self.assertFalse(self.pg.game_won)
        self.assertFalse(self.pg.game_over)

        self.assertEqual(2, self.pg.infection_rate)

        self.assertIn('New York', self.pg.city_map)
        self.newyork = self.pg.city_map['New York']
        self.assertEqual('New York', self.newyork.name)
        self.assertEqual('Yellow', self.newyork.colour)
        self.assertEqual(3, len(self.newyork.connected_cities))
        for colour in ('Blue', 'Red', 'Yellow', 'Black'):
            self.assertIn(colour, self.newyork.infection_levels)

        top_player_card = self.pg.player_deck.take_top_card()
        top_infect_card = self.pg.infect_deck.take_top_card()
        self.assertEqual('London', top_player_card.name)
        self.assertEqual('London', top_infect_card.name)

        self.assertEqual('Red', self.pg.diseases['Red'].colour)
        self.assertEqual(30, self.pg.diseases['Black'].public_health)

        self.assertEqual(4, self.pg.starting_epidemics)
Example #10
0
class GameTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.settings = config.get_settings(SETTINGS_LOCATION, refresh=True)

    def setUp(self):
        random.seed(42)
        self.character1 = Character('Evie')
        self.character2 = Character('Amelia')
        self.pg = Game()
        self.pg.add_character(self.character1)
        self.pg.add_character(self.character2)
        self.pg.setup_game(self.settings)

    def test_all_one_colour(self):
        card_names = [
            'London', 'Oxford', 'Cambridge', 'Brighton', 'Southampton'
        ]
        self.assertTrue(self.pg.all_one_colour(card_names))

        card_names[3] = 'Moscow'
        self.assertFalse(self.pg.all_one_colour(card_names))

    def test_all_diseases_cured(self):
        self.assertFalse(self.pg.all_diseases_cured())

        self.pg.diseases['Yellow'].cured = True
        self.assertFalse(self.pg.all_diseases_cured())

        self.pg.diseases['Blue'].cured = True
        self.pg.diseases['Black'].cured = True
        self.assertFalse(self.pg.all_diseases_cured())

        self.pg.diseases['Red'].cured = True
        self.assertTrue(self.pg.all_diseases_cured())

    def test_add_epidemics(self):
        self.pg.add_epidemics()
        num_epidemics = len({
            card
            for card in self.pg.player_deck.cards if card.name == 'Epidemic'
        })
        self.assertTrue(self.pg.starting_epidemics, num_epidemics)

    def test_infect_city(self):
        self.pg.infect_city('London', 'Blue')
        self.assertEqual(1,
                         self.pg.city_map['London'].infection_levels['Blue'])

        self.pg.diseases['Blue'].public_health = 0
        with self.assertRaises(GameCrisisException):
            self.pg.infect_city('London', 'Blue')

    def test_infect_city_phase(self):
        self.pg.infect_city_phase()
        self.assertEqual(1,
                         self.pg.city_map['London'].infection_levels['Blue'])
        self.assertEqual(1,
                         self.pg.city_map['Oxford'].infection_levels['Blue'])
        self.assertEqual(2, len(self.pg.infect_deck.discard))
        self.assertEqual('London', self.pg.infect_deck.discard[0].name)
        self.assertEqual(28, self.pg.diseases['Blue'].public_health)

        self.pg.infect_city('London', 'Blue')
        self.assertEqual(0, len(self.pg.outbreak_stack))

    def test_infect_city_phase_ouitbreak_stack(self):
        """Tests that the outbreak stack is cleaned after each drawn card.
        This reflects in how many cities are infected and how much.
        """
        london = self.pg.city_map['London']
        oxford = self.pg.city_map['Oxford']
        london.infection_levels['Blue'] = 3
        oxford.infection_levels['Blue'] = 3

        self.pg.infect_city_phase()
        self.assertEqual(6, self.pg.outbreak_count)
        self.assertEqual(10, self.pg.diseases['Blue'].public_health)
        self.assertEqual(2,
                         self.pg.city_map['Bristol'].infection_levels['Blue'])
        self.assertEqual(
            3, self.pg.city_map['Cambridge'].infection_levels['Blue'])

    def test_epidemic_phase(self):
        self.pg.epidemic_phase()
        self.assertEqual(
            3, self.pg.city_map['Belgorod'].infection_levels['Black'])
        top_infect_card = self.pg.infect_deck.take_top_card()
        self.assertEqual('Belgorod', top_infect_card.name)
        self.assertEqual('Black', top_infect_card.colour)
        self.assertEqual(1, self.pg.epidemic_count)
        self.assertEqual(0, len(self.pg.infect_deck.discard))

    def test_outbreak_trigger(self):
        for i in range(4):
            self.pg.infect_city('London', 'Blue')
        self.assertEqual(3,
                         self.pg.city_map['London'].infection_levels['Blue'])
        self.assertEqual(1,
                         self.pg.city_map['Oxford'].infection_levels['Blue'])
        self.assertEqual(
            1, self.pg.city_map['Cambridge'].infection_levels['Blue'])
        self.assertEqual(1,
                         self.pg.city_map['Brighton'].infection_levels['Blue'])
        self.assertEqual(
            1, self.pg.city_map['Washington'].infection_levels['Blue'])
        self.assertEqual(1,
                         self.pg.city_map['Bejing'].infection_levels['Blue'])
        self.assertEqual(1,
                         self.pg.city_map['Moscow'].infection_levels['Blue'])
        self.assertEqual(1, self.pg.outbreak_count)

    def test_outbreak(self):
        self.pg.outbreak('London', 'Blue')
        self.assertEqual(1,
                         self.pg.city_map['Oxford'].infection_levels['Blue'])
        self.assertEqual(
            1, self.pg.city_map['Cambridge'].infection_levels['Blue'])
        self.assertEqual(1,
                         self.pg.city_map['Brighton'].infection_levels['Blue'])
        self.assertEqual(
            1, self.pg.city_map['Washington'].infection_levels['Blue'])
        self.assertEqual(1,
                         self.pg.city_map['Bejing'].infection_levels['Blue'])
        self.assertEqual(1,
                         self.pg.city_map['Moscow'].infection_levels['Blue'])

        self.pg.outbreak_count = 7
        self.pg.outbreak_stack.clear()
        with self.assertRaises(GameCrisisException):
            self.pg.outbreak('London', 'Blue')

    def test_shuffle(self):
        self.assertEqual('London', self.pg.player_deck.take_top_card().name)
        self.pg.player_deck.shuffle()
        self.assertNotEqual('Oxford', self.pg.player_deck.take_top_card().name)

        self.assertEqual('London', self.pg.infect_deck.take_top_card().name)
        self.pg.infect_deck.shuffle()
        self.assertNotEqual('Oxford', self.pg.infect_deck.take_top_card().name)

    def test_start_game(self):
        self.pg.start_game()
        self.top_player_card = self.pg.player_deck.take_top_card()
        self.top_infect_card = self.pg.infect_deck.take_top_card()
        self.assertEqual(9, len(self.pg.infect_deck.discard))
        self.assertEqual(0, len(self.pg.player_deck.discard))
        self.assertEqual(3,
                         self.pg.city_map['Brighton'].infection_levels['Blue'])
        self.assertEqual(
            1, self.pg.city_map['Detroit'].infection_levels['Yellow'])
        self.assertEqual(
            2, self.pg.city_map['Smolensk'].infection_levels['Black'])
        self.assertEqual(4, len(self.character1.hand))
        self.assertEqual(4, len(self.character2.hand))
        self.assertNotEqual('London', self.top_player_card.name)
        self.assertNotEqual('London', self.top_infect_card.name)
        self.assertEqual('London', self.pg.characters[0].location.name)
        self.assertEqual('London', self.pg.characters[1].location.name)
        self.assertTrue(self.pg.city_map['London'].has_lab)

        for i in range(10):
            self.pg.draw_card(self.character1)
        self.assertEqual(1, self.pg.epidemic_count)

    def test_initial_infect_phase(self):
        self.pg.initial_infect_phase()
        self.assertEqual(3,
                         self.pg.city_map['London'].infection_levels['Blue'])
        self.assertEqual(3,
                         self.pg.city_map['Oxford'].infection_levels['Blue'])
        self.assertEqual(
            3, self.pg.city_map['Cambridge'].infection_levels['Blue'])
        self.assertEqual(2,
                         self.pg.city_map['Brighton'].infection_levels['Blue'])
        self.assertEqual(
            2, self.pg.city_map['Southampton'].infection_levels['Blue'])
        self.assertEqual(2,
                         self.pg.city_map['Bristol'].infection_levels['Blue'])
        self.assertEqual(1,
                         self.pg.city_map['Plymouth'].infection_levels['Blue'])
        self.assertEqual(
            1, self.pg.city_map['Liverpool'].infection_levels['Blue'])
        self.assertEqual(
            1, self.pg.city_map['Manchester'].infection_levels['Blue'])
        self.assertEqual(9, len(self.pg.infect_deck.discard))
        self.assertEqual(12, self.pg.diseases['Blue'].public_health)

    def test_draw_initial_hands(self):
        test_cards = self.pg.player_deck.cards[:8]
        self.pg.draw_initial_hands()

        for i, character in enumerate(self.pg.characters):
            with self.subTest(i=i, character=character):
                self.assertEqual(4, len(character.hand))
                self.assertEqual(test_cards[i * 4 + 3].name,
                                 character.hand[3].name)

    def test_draw_card(self):
        self.pg.draw_card(self.character1)
        self.assertEqual('London', self.character1.hand[0].name)

        self.pg.player_deck.cards = []
        with self.assertRaises(GameCrisisException):
            self.pg.draw_card(self.character1)

    def test_get_new_disease(self):
        self.assertFalse(self.pg.diseases['Blue'].cured)
        self.assertFalse(self.pg.diseases['Red'].cured)
        self.pg.diseases['Blue'].cured = True
        self.assertTrue(self.pg.diseases['Blue'].cured)