def _build_dialogue(self, **kwargs):
        self.log.info("Building dialogue")

        dialogue_collection = UnitDialogueCollection()
        dialogue_model = UnitDialogueModel(db=self.db)
        dialogue_models = dialogue_model.get_unit_dialogue()
        unit_dialogue_map = \
            dialogue_model._get_unit_dialogue_map(dialogue_models)

        for dialogue_model in dialogue_models:
            dialogue = UnitDialogue(dialogue=dialogue_model)
            dialogue_collection.add(dialogue)

        return {
            "dialogue_collection": dialogue_collection,
            "unit_dialogue_map": unit_dialogue_map
        }
    def test_create_units(self):
        """
        The item collection is populated by models
        """
        item_collection = ItemCollection()
        effect_collection = EffectCollection()
        dialogue_collection = UnitDialogueCollection()

        """
        Prepare unit model collection
        """
        unit_models = []
        expected_units = []
        unit_items = []
        unit_effects = []
        unit_dialogue = []
        unit_items_model = UnitItems(db="quux")
        unit_effects_model = UnitEffects(db="quux")
        unit_dialogue_model = UnitDialogueModel(db="quux")

        total_units = 25
        item_types = ("rock", "paper", "scissors", "paper", "spock")
        total_items_per_unit = len(item_types)
        total_effects_per_unit = 5
        total_dialogue_per_unit = 5

        for j in range(0, total_units):
            """
            Add items for each unit
            """
            items = []
            effects = []
            dialogue = []
            unit_model = self._get_unit_model()
            unit_id = unit_model["id"]
            unit_type_id = unit_model["unit_type_id"]

            for it in item_types:
                item = self._make_item(item_type=it,
                                       unit_type_id=unit_type_id)
                items.append(item)
                item_collection.add(item)
                unit_items.append({"item_id": item.id, "unit_id": unit_id})

            unit_model["items"] = items

            """
            Base items
            """
            unit_model["base_items"] = \
                item_collection.get_base_items_by_unit_type_id(unit_type_id)

            """
            Add effects
            """
            for k in range(0, total_effects_per_unit):
                effect = self._make_effect()
                effects.append(effect)
                effect_collection.add(effect)
                unit_effects.append(
                    {"effect_id": effect.id, "unit_id": unit_id})

            unit_model["effects"] = effects

            """
            Add dialogue
            """
            for q in range(0, total_dialogue_per_unit):
                a_dialogue = self._make_dialogue()
                dialogue.append(a_dialogue)
                dialogue_collection.add(a_dialogue)
                unit_dialogue.append(
                    {"dialogue_id": a_dialogue.id, "unit_id": unit_id})

            unit_model["dialogue"] = dialogue

            """
            Add completed unit to expected
            """
            unit_models.append(unit_model)

            with LogCapture():
                logger = logging.getLogger()
                unit = Unit(unit=unit_model, log=logger)

            expected_units.append(unit)

        unit_items_map = unit_items_model._get_unit_items_map(unit_items)
        unit_effects_map = unit_effects_model._get_unit_effects_map(
            unit_effects)
        unit_dialogue_map = unit_dialogue_model._get_unit_dialogue_map(
            unit_dialogue)

        builder = UnitBuilder()
        with LogCapture():
            logger = logging.getLogger()
            actual_units = builder.build_units(unit_models=unit_models,
                                               unit_items_map=unit_items_map,
                                               item_collection=item_collection,
                                               effect_collection=effect_collection,
                                               unit_effects_map=unit_effects_map,
                                               dialogue_collection=dialogue_collection,
                                               unit_dialogue_map=unit_dialogue_map,
                                               log=logger)

        expected_unit_ids = [unit.id for e_unit in expected_units]
        actual_unit_ids = [unit.id for a_unit in actual_units]

        self.assertEqual(expected_unit_ids, actual_unit_ids)

        """
        Test that the actual units contain the expected items
        and effects
        """
        self.assertEqual(len(actual_units), len(expected_units))

        for e_unit in expected_units:
            self.assertEqual(len(e_unit.items), total_items_per_unit)
            self.assertEqual(len(e_unit.effects), total_effects_per_unit)
            self.assertEqual(len(e_unit.dialogue), total_dialogue_per_unit)

        for a_unit in actual_units:
            self.assertEqual(len(a_unit.items), total_items_per_unit)
            self.assertEqual(len(a_unit.effects), total_effects_per_unit)
            self.assertEqual(len(a_unit.dialogue), total_dialogue_per_unit)

            """
            Ensure each item either has no unit type requirement (0)
            or it matches the unit in question
            """
            for a_item in a_unit.items:
                self.assertIn(a_item.unit_type_id, (0, a_unit.unit_type_id))
    def test_build_world(self):
        """
        Utilize models to build the world.

        1. Get dungeons
        2. Get effects
        3. Get item effects
        4. Get items
        5. Get unit items
        6. Get units
        """

        """ Dungeons """
        dungeon_model = DungeonModel(db=self.db)
        dungeon_models = dungeon_model.get_dungeons()

        self.assertIsInstance(dungeon_models, list)
        self.assertTrue(dungeon_models)

        """ Effects """
        effects_model = EffectModel(db=self.db)
        effects_models = effects_model.get_effects()

        self.assertIsInstance(effects_models, list)
        self.assertTrue(effects_models)

        """ Unit effects map """
        unit_effects_model = UnitEffects(db=self.db)
        unit_effects = unit_effects_model.get_unit_effects()
        unit_effects_map = unit_effects_model._get_unit_effects_map(unit_effects)

        self.assertIsInstance(unit_effects_map, dict)
        self.assertTrue(unit_effects_map)

        """ Unit dialogue map """
        unit_dialogue_model = UnitDialogueModel(db=self.db)
        unit_dialogue = unit_dialogue_model.get_unit_dialogue()
        unit_dialogue_map = unit_dialogue_model._get_unit_dialogue_map(unit_dialogue)

        self.assertIsInstance(unit_dialogue, list)
        self.assertIsInstance(unit_dialogue_map, dict)
        self.assertTrue(unit_dialogue_map)

        """ Item effects map """
        item_effects_model = ItemEffects(db=self.db)
        item_effects = item_effects_model.get_item_effects()
        item_effects_map = item_effects_model._get_item_effects_map(item_effects)

        self.assertIsInstance(item_effects, list)
        self.assertIsInstance(item_effects_map, dict)
        self.assertTrue(item_effects_map)
        self.assertTrue(item_effects)

        """ Items """
        item_model = ItemModel(db=self.db)
        item_models = item_model.get_items()

        self.assertIsInstance(item_models, list)
        self.assertTrue(item_models)

        """ Unit items map """
        unit_items_model = UnitItems(db=self.db)
        unit_item_models = unit_items_model.get_unit_items()
        unit_items_map = unit_items_model._get_unit_items_map(unit_item_models)

        self.assertIsInstance(unit_item_models, list)
        self.assertIsInstance(unit_items_map, dict)
        self.assertTrue(unit_items_map)
        self.assertTrue(unit_item_models)

        """ Units """
        unit_model = UnitModel(db=self.db)
        unit_models = unit_model.get_units()

        self.assertIsInstance(unit_models, list)
        self.assertTrue(unit_models)

        """ Assemble collections using models """
        item_collection = ItemCollection()
        effect_collection = EffectCollection()
        dialogue_collection = UnitDialogueCollection()

        for effect_model in effects_models:
            effect = Effect(effect=effect_model)
            effect_collection.add(effect)

        self.assertTrue(effect_collection.effects)

        item_builder = ItemBuilder()
        items = item_builder.build_items(item_models=item_models,
                                         item_effects_map=item_effects_map,
                                         effect_collection=effect_collection)
        self.assertIsInstance(items, list)
        self.assertTrue(items)

        for item in items:
            item_collection.add(item)

        self.assertTrue(item_collection.items)

        for ud in unit_dialogue:
            dialogue = UnitDialogue(dialogue=ud)
            dialogue_collection.add(dialogue)

        """ Build units using assembled collections """
        unit_builder = UnitBuilder()

        with LogCapture() as l:
            logger = logging.getLogger()
            units = unit_builder.build_units(unit_models=unit_models,
                                             effect_collection=effect_collection,
                                             item_collection=item_collection,
                                             dialogue_collection=dialogue_collection,
                                             unit_items_map=unit_items_map,
                                             unit_effects_map=unit_effects_map,
                                             unit_dialogue_map=unit_dialogue_map,
                                             log=logger)

        self.assertIsInstance(units, list)
        self.assertTrue(units)

        num_players = 0

        for unit in units:
            self.assertIsInstance(unit, Unit)

            if unit.is_player:
                num_players += 1

        self.assertTrue(num_players > 0)

        """
        Populate collections
        """
        unit_collection = UnitCollection()

        for unit in units:
            unit_collection.add(unit)

        self.assertEqual(len(unit_collection.units), len(unit_models))