async def _assert_owned_offers( self, kernel: Kernel, web: TestClient, character: CharacterModel, count: int, names: typing.Optional[typing.List[str]] = None, ) -> None: names = names or [] # main page resp: ClientResponse = await web.post(f"/business/{character.id}") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label for i in descr.items] assert f"Voir les offres que vous proposez ({count} en cours)" in item_labels if not names: return # offers page resp: ClientResponse = await web.post( f"/business/{character.id}/offers") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label for i in descr.items] for name in names: assert next(l for l in item_labels if name in str(l))
async def test_read_offer__make_transaction__missing_all_request_or( self, worldmapc_xena_model: CharacterModel, worldmapc_arthur_model: CharacterModel, worldmapc_web_app: TestClient, worldmapc_kernel: Kernel, xena_permanent_or_offer: OfferDocument, ) -> None: xena = worldmapc_xena_model arthur = worldmapc_arthur_model kernel = worldmapc_kernel web = worldmapc_web_app offer = xena_permanent_or_offer # ensure xena have all offered items kernel.resource_lib.add_resource_to("WOOD", 0.5, character_id=xena.id) jacket = create_stuff(kernel, "LEATHER_JACKET") kernel.stuff_lib.set_carried_by(jacket.id, character_id=xena.id) resp = await web.post( f"/business/{arthur.id}/see-offer/{offer.character_id}/{offer.id}/deal" ) assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label or i.text for i in descr.items] assert "Vous ne possédez pas ce qu'il faut pour faire ce marché" in item_labels
async def test_read_offer__make_transaction__owner_missing_offer_and( self, worldmapc_xena_model: CharacterModel, worldmapc_arthur_model: CharacterModel, worldmapc_web_app: TestClient, worldmapc_kernel: Kernel, xena_permanent_and_offer: OfferDocument, ) -> None: xena = worldmapc_xena_model arthur = worldmapc_arthur_model kernel = worldmapc_kernel web = worldmapc_web_app offer = xena_permanent_and_offer # xena have just a part of offered items kernel.resource_lib.add_resource_to("WOOD", 0.5, character_id=xena.id) resp = await web.post( f"/business/{arthur.id}/see-offer/{offer.character_id}/{offer.id}/deal" ) assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label or i.text for i in descr.items] assert f"{xena.name} ne peut pas assurer cette opération" in item_labels
async def _get_card_item(self, web: TestClient, character_id: str, item_label: str) -> Part: resp = await web.post(f"/_describe/character/{character_id}/card") descr = description_serializer.load(await resp.json()) item_by_label = {i.label: i for i in descr.items if i.label} return item_by_label[item_label]
async def _create_conversation( self, web: TestClient, author: CharacterModel, with_: typing.List[CharacterModel], available: typing.List[CharacterModel], subject: str, message: str, ) -> None: resp = await web.post(f"/conversation/{author.id}/start") text = await resp.text() assert 200 == resp.status descr = description_serializer.load(await resp.json()) assert descr.items[1].is_form assert f"/conversation/{author.id}/start" == descr.items[1].form_action checkbox_names = [ i.name for i in descr.items[1].items if i.is_checkbox ] for character_available in available: assert character_available.id in checkbox_names data = {"subject": subject, "message": message} for with_character in with_: data[with_character.id] = "on" resp = await web.post(f"/conversation/{author.id}/start", json=data) text = await resp.text() assert 200 == resp.status
async def test_add_items__check_form( self, worldmapc_xena_model: CharacterModel, worldmapc_web_app: TestClient, worldmapc_kernel: Kernel, ) -> None: xena = worldmapc_xena_model kernel = worldmapc_kernel web = worldmapc_web_app assert (await web.post(f"/business/{xena.id}/offers-create?permanent=1", json={"title": "My offer"})).status == 200 resp = await web.post( f"/business/{xena.id}/offers/{1}/add-item?position=REQUEST") assert resp.status == 200 descr = description_serializer.load(await resp.json()) assert descr.items[0].is_form assert descr.items[0].items[0].name == "value" for name in [ "Bois (mètre cubes)", "Vin rouge (litres)", "Plastic bottle (unité)", "Bouclier de bois (unité)", "Hache de pierre (unité)", "Veste de cuir (unité)", "Pierre (unités)", "Corps (unité)", "Petit bois (mètre cubes)", ]: assert name in descr.items[0].items[0].choices assert descr.items[0].items[1].name == "quantity"
async def test_unit__pick_from_inventory( self, worldmapc_xena_model: CharacterModel, worldmapc_xena_haxe: StuffModel, worldmapc_xena_wood: None, worldmapc_web_app: TestClient, ) -> None: web = worldmapc_web_app xena = worldmapc_xena_model pick_url = (f"/_describe/character/{xena.id}/pick_from_inventory" f"?callback_url=to_somewhere" f"&cancel_url=or_here" f"&title=The title") resp = await web.post(pick_url) assert resp.status == 200 descr = description_serializer.load(await resp.json()) assert descr.title == "The title" assert descr.items[0].is_form assert descr.items[0].form_action == pick_url descr_links = [p.form_action for p in descr.items[0].items] stone_haxe_url = f"{pick_url}&stuff_id=STONE_HAXE" wood_url = f"{pick_url}&resource_id=WOOD" assert stone_haxe_url in descr_links assert wood_url in descr_links resp = await web.post(stone_haxe_url) assert resp.status == 200 descr = description_serializer.load(await resp.json()) assert descr.items[0].is_form assert descr.items[ 0].form_action == f"to_somewhere?&stuff_id=STONE_HAXE" assert descr.items[0].items[0].name == "stuff_quantity" assert descr.items[0].items[0].default_value == "1" assert descr.items[0].form_values_in_query resp = await web.post(wood_url) assert resp.status == 200 descr = description_serializer.load(await resp.json()) assert descr.items[0].is_form assert descr.items[0].form_action == f"to_somewhere?&resource_id=WOOD" assert descr.items[0].items[0].name == "resource_quantity" assert descr.items[0].items[0].default_value == "0.2" assert descr.items[0].form_values_in_query
async def _assert_conversations(self, web: TestClient, character: CharacterModel, count: int, resp_code: int = 200) -> None: resp = await web.post(f"/conversation/{character.id}") text = await resp.text() assert resp_code == resp.status descr = description_serializer.load(await resp.json()) assert f"/conversation/{character.id}/start" == descr.items[ 1].form_action assert 3 + count == len(descr.items)
async def _assert_edit_offer( self, kernel: Kernel, web: TestClient, character: CharacterModel, offer_id: int, request_operand_str: str = ONE_OF_THEM, request_item_names: typing.Optional[typing.List[str]] = None, request_item_names_not: typing.Optional[typing.List[str]] = None, offer_operand_str: str = ONE_OF_THEM, offer_item_names: typing.Optional[typing.List[str]] = None, offer_item_names_not: typing.Optional[typing.List[str]] = None, open_: bool = False, ) -> None: request_item_names = request_item_names or [] request_item_names_not = request_item_names_not or [] offer_item_names = offer_item_names or [] offer_item_names_not = offer_item_names_not or [] resp = await web.post(f"/business/{character.id}/offers/{offer_id}") assert 200 == resp.status descr = description_serializer.load(await resp.json()) form_item_by_name = {i.name: i for i in descr.items[0].items} form_item_labels = [i.label for i in descr.items[0].items] assert form_item_by_name[ "request_operand"].value == request_operand_str assert form_item_by_name["offer_operand"].value == offer_operand_str for request_item_name in request_item_names: assert request_item_name in form_item_labels for offer_item_name in offer_item_names: assert offer_item_name in form_item_labels for request_item_name_not in request_item_names_not: assert request_item_name_not not in form_item_labels for offer_item_name_not in offer_item_names_not: assert offer_item_name_not not in form_item_labels if not open_: assert "Activer" == descr.items[1].label else: assert "Désactiver" == descr.items[1].label
async def _assert_read_offer( self, kernel: Kernel, web: TestClient, owner: CharacterModel, character: CharacterModel, offer_id: int, request_operand_str: str = ONE_OF_THEM, have_not_item_names: typing.Optional[typing.List[str]] = None, have_item_names: typing.Optional[typing.List[str]] = None, offer_operand_str: str = ONE_OF_THEM, offer_item_names: typing.Optional[typing.List[str]] = None, owner_can_make_deal: bool = True, can_make_deal: bool = False, ) -> None: have_not_item_names = have_not_item_names or [] have_item_names = have_item_names or [] offer_item_names = offer_item_names or [] resp = await web.post( f"/business/{character.id}/see-offer/{owner.id}/{offer_id}") assert 200 == resp.status descr = description_serializer.load(await resp.json()) form_item_labels = [i.label or i.text for i in descr.items] assert f"Eléments demandé(s) ({request_operand_str})" in form_item_labels assert f"Eléments donné(s) ({offer_operand_str})" in form_item_labels for have_not_item_name in have_not_item_names: assert f"(X) {have_not_item_name}" in form_item_labels for have_item_name in have_item_names: assert f"(V) {have_item_name}" in form_item_labels for offer_item_name in offer_item_names: assert offer_item_name in form_item_labels if owner_can_make_deal: if can_make_deal: assert "Effectuer une transaction" in form_item_labels else: assert "Vous ne possédez pas de quoi faire un marché" in form_item_labels else: assert f"{owner.name} ne peut pas assurer cette opération"
async def test_unit__follow__ok__nominal_case( self, worldmapc_kernel: Kernel, worldmapc_xena_model: CharacterModel, worldmapc_arthur_model: CharacterModel, worldmapc_franck_model: CharacterModel, follow_action: FollowCharacterAction, worldmapc_web_app: TestClient, ) -> None: xena = worldmapc_xena_model arthur = worldmapc_arthur_model franck = worldmapc_franck_model web = worldmapc_web_app kernel = worldmapc_kernel follow_action.perform(arthur, xena, input_=FollowModel()) follow_action.perform(franck, xena, input_=FollowModel(discreetly=True)) resp = await web.post( f"/_describe/character/{xena.id}/move-to-zone/{1}/{2}") assert 200 == resp.status descr = description_serializer.load(await resp.json()) texts = [p.text for p in descr.items] url_by_label = {p.label: p.form_action for p in descr.items} assert "1 personnage(s) vous suivront dans ce déplacement" in texts resp = await web.post(url_by_label["Effectuer le voyage"]) assert 200 == resp.status xena_doc = kernel.character_lib.get_document(xena.id) arthur_doc = kernel.character_lib.get_document(arthur.id) franck_doc = kernel.character_lib.get_document(franck.id) assert (xena_doc.world_row_i, xena_doc.world_col_i) == (1, 2) assert (arthur_doc.world_row_i, arthur_doc.world_col_i) == (1, 2) assert (franck_doc.world_row_i, franck_doc.world_col_i) == (1, 2) assert (list(kernel.character_lib.get_last_events( arthur_doc.id, 1))[0].text == "Vous avez suivis xena") assert (list(kernel.character_lib.get_last_events( franck_doc.id, 1))[0].text == "Vous avez suivis xena")
async def _assert_conversation( self, web: TestClient, character: CharacterModel, conversation_id: int, between: typing.List[CharacterModel], message_count: int, messages: typing.List[str], ) -> None: resp = await web.post( f"/conversation/{character.id}/read/{conversation_id}") text = await resp.text() assert 200 == resp.status descr = description_serializer.load(await resp.json()) for between_character in between: assert between_character.name in descr.items[1].text assert 4 + message_count == len(descr.items) messages_ = [i.text for i in descr.items[4:]] for message in messages: assert message in messages_
async def test_create_offer__nominal_case( self, worldmapc_xena_model: CharacterModel, worldmapc_web_app: TestClient, worldmapc_kernel: Kernel, ) -> None: xena = worldmapc_xena_model kernel = worldmapc_kernel web = worldmapc_web_app await self._assert_owned_offers(kernel, web, xena, count=0) resp = await web.post(f"/business/{xena.id}/offers-create?permanent=1") assert 200 == resp.status resp = await web.post(f"/business/{xena.id}/offers-create?permanent=1", json={"title": "My offer"}) assert 200 == resp.status descr = description_serializer.load(await resp.json()) assert descr.redirect == f"/business/{xena.id}/offers/1" await self._assert_owned_offers(kernel, web, xena, count=1, names=["My offer"]) await self._assert_edit_offer( kernel, web, xena, offer_id=1, request_operand_str=ONE_OF_THEM, request_item_names=[], offer_operand_str=ONE_OF_THEM, offer_item_names=[], open_=False, )
async def _assert_messages( self, web: TestClient, character_id: str, message_count: int = 0, row_i: int = 0, col_i: int = 0, assert_messages: typing.Optional[typing.List[str]] = None, ) -> None: assert_messages = assert_messages or [] resp = await web.post( f"/zones/{row_i}/{col_i}/messages?character_id={character_id}") descr = description_serializer.load(await resp.json()) assert 3 + message_count == len(descr.items) assert descr.items[1].is_form assert (f"/zones/{row_i}/{col_i}/messages/add" f"?character_id={character_id}" == descr.items[1].form_action) assert descr.items[1].items assert "message" == descr.items[1].items[0].name messages = [item.text for item in descr.items[3:]] for assert_message in assert_messages: assert assert_message in messages
async def test_unit__propose_and_teach__ok__nominal_case( self, worldmapc_kernel: Kernel, worldmapc_xena_model: CharacterModel, worldmapc_arthur_model: CharacterModel, propose_teach_action: ProposeTeachKnowledgeAction, worldmapc_web_app: TestClient, ) -> None: kernel = worldmapc_kernel xena = worldmapc_xena_model arthur = worldmapc_arthur_model web = worldmapc_web_app assert kernel.character_lib.get_knowledge_progress( arthur.id, "blacksmith") == 0 description = propose_teach_action.perform( xena, arthur, input_=ProposeTeachKnowledgeModel(knowledge_id="blacksmith", ap=5, expire=2), ) assert description.title == "Proposition effectué" arthur = kernel.character_lib.get(arthur.id, compute_pending_actions=True) assert arthur.pending_actions == 1 resp = await web.post( f"/_describe/character/{arthur.id}/on_place_actions") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_urls = [p.form_action for p in descr.items] assert f"/_describe/character/{arthur.id}/pending_actions" in item_urls assert arthur.pending_actions == 1 resp = await web.post( f"/_describe/character/{arthur.id}/pending_actions") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_urls = [p.form_action for p in descr.items] item_labels = [p.label for p in descr.items] assert f"/_describe/character/{arthur.id}/pending_actions/1" in item_urls assert "Prendre un cours de Forgeron avec xena pendant 5 points d'actions" in item_labels resp = await web.post( f"/_describe/character/{arthur.id}/pending_actions/1") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_urls = [p.form_action for p in descr.items] assert f"/_describe/character/{arthur.id}/pending_actions/1?do=1" in item_urls resp = await web.post( f"/_describe/character/{arthur.id}/pending_actions/1?do=1") assert 200 == resp.status arthur = kernel.character_lib.get(arthur.id, compute_pending_actions=True) assert arthur.pending_actions == 0 assert (kernel.character_lib.get_knowledge_progress( arthur.id, "blacksmith") == 5 * kernel.game.config.knowledge["blacksmith"].instructor_coeff)
async def test_unit__follow__error__cannot( self, worldmapc_kernel: Kernel, worldmapc_xena_model: CharacterModel, worldmapc_arthur_model: CharacterModel, follow_action: FollowCharacterAction, worldmapc_web_app: TestClient, reason: str, ) -> None: xena = worldmapc_xena_model arthur = worldmapc_arthur_model web = worldmapc_web_app kernel = worldmapc_kernel follow_action.perform(arthur, xena, input_=FollowModel()) def _fake_weight(self, kernel): if self.id == "arthur": return -1.0 return 200.0 _fake_clutter = _fake_weight def _fake_is_exhausted(self): if self.id == "arthur": return True return False @contextlib.contextmanager def _apply_patch(): if reason == "weight": with unittest.mock.patch( "rolling.model.character.CharacterModel.get_weight_capacity", new=_fake_weight): yield elif reason == "clutter": with unittest.mock.patch( "rolling.model.character.CharacterModel.get_clutter_capacity", new=_fake_clutter): yield elif reason == "exhausted": with unittest.mock.patch( "rolling.model.character.CharacterModel.is_exhausted", new=_fake_is_exhausted): yield else: raise NotImplementedError kernel.resource_lib.add_resource_to("WOOD", 200.0, arthur.id) with _apply_patch(): resp = await web.post( f"/_describe/character/{xena.id}/move-to-zone/{1}/{2}") assert 200 == resp.status descr = description_serializer.load(await resp.json()) texts = [p.text for p in descr.items] url_by_label = {p.label: p.form_action for p in descr.items} assert ( "1 personnage(s) ne pourront pas vous suivre dans ce déplacement: arthur" in texts) resp = await web.post(url_by_label["Effectuer le voyage"]) assert 200 == resp.status xena_doc = kernel.character_lib.get_document(xena.id) arthur_doc = kernel.character_lib.get_document(arthur.id) assert (xena_doc.world_row_i, xena_doc.world_col_i) == (1, 2) assert (arthur_doc.world_row_i, arthur_doc.world_col_i) == (1, 1) assert (list(kernel.character_lib.get_last_events( arthur_doc.id, 1))[0].text == "Vous n'avez pas pu suivre xena (fatigue ou surcharge)")
async def test_read_offer__make_transaction__request_or( self, worldmapc_xena_model: CharacterModel, worldmapc_arthur_model: CharacterModel, worldmapc_web_app: TestClient, worldmapc_kernel: Kernel, xena_permanent_or_offer: OfferDocument, initial_universe_state: UniverseStateDocument, ) -> None: xena = worldmapc_xena_model arthur = worldmapc_arthur_model kernel = worldmapc_kernel web = worldmapc_web_app offer = xena_permanent_or_offer # ensure xena have one of offered items kernel.resource_lib.add_resource_to("WOOD", 0.5, character_id=xena.id) # Give all necessary to arthur kernel.resource_lib.add_resource_to("RED_WINE", 1.5, character_id=arthur.id) haxe = create_stuff(kernel, "STONE_HAXE") kernel.stuff_lib.set_carried_by(haxe.id, character_id=arthur.id) assert kernel.resource_lib.have_resource(xena.id, "WOOD", 0.5) assert not kernel.resource_lib.have_resource(xena.id, "RED_WINE", 1.5) assert not kernel.stuff_lib.have_stuff_count(xena.id, "STONE_HAXE") assert not kernel.resource_lib.have_resource(arthur.id, "WOOD", 0.5) assert kernel.resource_lib.have_resource(arthur.id, "RED_WINE", 1.5) assert kernel.stuff_lib.have_stuff_count(arthur.id, "STONE_HAXE") resp = await web.post( f"/business/{arthur.id}/see-offer/{offer.character_id}/{offer.id}/deal" ) assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label or i.text for i in descr.items] item_by_label = {i.label: i for i in descr.items} give_wine_str = "Faire ce marché et donner Vin rouge (1.5 litres)" assert give_wine_str in item_labels assert "Faire ce marché et donner Hache de pierre (1)" in item_labels give_wine_url = item_by_label[give_wine_str].form_action resp = await web.post(give_wine_url) assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label or i.text for i in descr.items] item_by_label = {i.label: i for i in descr.items} take_wood_str = "Faire ce marché et obtenir Bois (0.5 mètre cubes)" assert take_wood_str in item_labels assert "Faire ce marché et obtenir Veste de cuir (1)" not in item_labels # Give jacket to xena to permit take it jacket = create_stuff(kernel, "LEATHER_JACKET") kernel.stuff_lib.set_carried_by(jacket.id, character_id=xena.id) resp = await web.post(give_wine_url) assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label or i.text for i in descr.items] item_by_label = {i.label: i for i in descr.items} take_wood_str = "Faire ce marché et obtenir Bois (0.5 mètre cubes)" assert take_wood_str in item_labels assert "Faire ce marché et obtenir Veste de cuir (1)" in item_labels take_wood_url = item_by_label[take_wood_str].form_action resp = await web.post(take_wood_url) assert 200 == resp.status assert not kernel.resource_lib.have_resource(xena.id, "WOOD", 0.5) assert kernel.resource_lib.have_resource(xena.id, "RED_WINE", 1.5) assert not kernel.stuff_lib.have_stuff_count(xena.id, "STONE_HAXE") assert kernel.resource_lib.have_resource(arthur.id, "WOOD", 0.5) assert not kernel.resource_lib.have_resource(arthur.id, "RED_WINE", 1.5) assert kernel.stuff_lib.have_stuff_count(arthur.id, "STONE_HAXE")
async def test_read_offer__make_transaction__request_and( self, worldmapc_xena_model: CharacterModel, worldmapc_arthur_model: CharacterModel, worldmapc_web_app: TestClient, worldmapc_kernel: Kernel, xena_permanent_and_offer: OfferDocument, initial_universe_state: UniverseStateDocument, ) -> None: xena = worldmapc_xena_model arthur = worldmapc_arthur_model kernel = worldmapc_kernel web = worldmapc_web_app offer = xena_permanent_and_offer # Give all necessary to arthur kernel.resource_lib.add_resource_to("RED_WINE", 2.0, character_id=arthur.id) haxe = create_stuff(kernel, "STONE_HAXE") kernel.stuff_lib.set_carried_by(haxe.id, character_id=arthur.id) # ensure xena have all offered items kernel.resource_lib.add_resource_to("WOOD", 0.5, character_id=xena.id) jacket = create_stuff(kernel, "LEATHER_JACKET") kernel.stuff_lib.set_carried_by(jacket.id, character_id=xena.id) assert kernel.resource_lib.have_resource(xena.id, "WOOD", 0.5) assert kernel.stuff_lib.have_stuff_count(xena.id, "LEATHER_JACKET") assert not kernel.resource_lib.have_resource(xena.id, "RED_WINE", 1.5) assert not kernel.stuff_lib.have_stuff_count(xena.id, "STONE_HAXE") assert not kernel.resource_lib.have_resource(arthur.id, "WOOD", 0.5) assert not kernel.stuff_lib.have_stuff_count(arthur.id, "LEATHER_JACKET") assert kernel.resource_lib.have_resource(arthur.id, "RED_WINE", 1.5) assert kernel.stuff_lib.have_stuff_count(arthur.id, "STONE_HAXE") resp = await web.post( f"/business/{arthur.id}/see-offer/{offer.character_id}/{offer.id}/deal" ) assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label or i.text for i in descr.items] assert "Je confirme vouloir faire ce marché" in item_labels # Do the deal resp = await web.post( f"/business/{arthur.id}/see-offer/{offer.character_id}/{offer.id}/deal?confirm=1" ) assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label or i.text for i in descr.items] assert "Marché effectué" in item_labels assert not kernel.resource_lib.have_resource(xena.id, "WOOD", 0.5) assert not kernel.stuff_lib.have_stuff_count(xena.id, "LEATHER_JACKET") assert kernel.resource_lib.have_resource(xena.id, "RED_WINE", 1.5) assert kernel.stuff_lib.have_stuff_count(xena.id, "STONE_HAXE") assert kernel.resource_lib.have_resource(arthur.id, "WOOD", 0.5) assert kernel.stuff_lib.have_stuff_count(arthur.id, "LEATHER_JACKET") assert not kernel.resource_lib.have_resource(arthur.id, "RED_WINE", 1.5) assert not kernel.stuff_lib.have_stuff_count(arthur.id, "STONE_HAXE")
async def test_create_with_character_transaction( self, worldmapc_xena_model: CharacterModel, worldmapc_arthur_model: CharacterModel, worldmapc_web_app: TestClient, worldmapc_kernel: Kernel, initial_universe_state: UniverseStateDocument, ) -> None: """+ conteur main page + vue depuis target + blinker""" xena = worldmapc_xena_model arthur = worldmapc_arthur_model kernel = worldmapc_kernel web = worldmapc_web_app assert (await web.post( f"/business/{xena.id}/offers-create?with_character_id={arthur.id}", json={"title": "My offer"}, )).status == 200 assert (await web.post( f"/business/{xena.id}/offers/{1}/add-item" f"?position=REQUEST&value=Plastic bottle (unité)&quantity=1" )).status == 200 assert (await web.post( f"/business/{xena.id}/offers/{1}/add-item" f"?position=OFFER&value=Vin rouge (litres)&quantity=1.5" )).status == 200 assert ( await web.post(f"/business/{xena.id}/offers/{1}?open=1")).status == 200 await self._assert_edit_offer( kernel, web, character=xena, offer_id=1, request_operand_str=ONE_OF_THEM, offer_operand_str=ONE_OF_THEM, request_item_names=["Plastic bottle (1)"], offer_item_names=["(X) Vin rouge (1.5 litres)"], open_=True, ) await self._assert_read_offer( kernel, web, owner=xena, character=arthur, offer_id=1, request_operand_str=ONE_OF_THEM, offer_operand_str=ONE_OF_THEM, have_not_item_names=["Plastic bottle (1)"], offer_item_names=["(!) Vin rouge (1.5 litres)"], can_make_deal=False, ) # Give all necessary kernel.resource_lib.add_resource_to("RED_WINE", 1.5, character_id=xena.id) bottle = create_stuff(kernel, "PLASTIC_BOTTLE_1L") kernel.stuff_lib.set_carried_by(bottle.id, character_id=arthur.id) assert kernel.resource_lib.have_resource(xena.id, "RED_WINE", 1.5) assert not kernel.stuff_lib.have_stuff_count(xena.id, "PLASTIC_BOTTLE_1L") assert not kernel.resource_lib.have_resource(arthur.id, "RED_WINE", 1.5) assert kernel.stuff_lib.have_stuff_count(arthur.id, "PLASTIC_BOTTLE_1L") await self._assert_read_offer( kernel, web, owner=xena, character=arthur, offer_id=1, request_operand_str=ONE_OF_THEM, offer_operand_str=ONE_OF_THEM, have_item_names=["Plastic bottle (1)"], offer_item_names=["Vin rouge (1.5 litres)"], can_make_deal=True, ) # xena main page resp: ClientResponse = await web.post(f"/business/{xena.id}") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label for i in descr.items] assert "Voir les transactions en attente (1 en cours)" in item_labels # arthur main page resp: ClientResponse = await web.post(f"/business/{arthur.id}") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label for i in descr.items] assert "*Voir les transactions en attente (1 en cours)" in item_labels resp = await web.post( f"/business/{arthur.id}/see-offer/{xena.id}/{1}/deal") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label or i.text for i in descr.items] item_by_label = {i.label: i for i in descr.items} deal_str = "Faire ce marché et donner Plastic bottle (1)" assert deal_str in item_labels go_url = item_by_label[deal_str].form_action resp = await web.post(go_url) assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label or i.text for i in descr.items] item_by_label = {i.label: i for i in descr.items} deal_str = "Faire ce marché et obtenir Vin rouge (1.5 litres)" assert deal_str in item_labels go_url = item_by_label[deal_str].form_action assert (await web.post(go_url)).status == 200 assert not kernel.resource_lib.have_resource(xena.id, "RED_WINE", 1.5) assert kernel.stuff_lib.have_stuff_count(xena.id, "PLASTIC_BOTTLE_1L") assert kernel.resource_lib.have_resource(arthur.id, "RED_WINE", 1.5) assert not kernel.stuff_lib.have_stuff_count(arthur.id, "PLASTIC_BOTTLE_1L") # xena main page resp: ClientResponse = await web.post(f"/business/{xena.id}") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label for i in descr.items] assert "Voir les transactions en attente (0 en cours)" in item_labels # arthur main page resp: ClientResponse = await web.post(f"/business/{arthur.id}") assert 200 == resp.status descr = description_serializer.load(await resp.json()) item_labels = [i.label for i in descr.items] assert "Voir les transactions en attente (0 en cours)" in item_labels