"""Behavioral coverage for the CS Major autochess 0.6.6 flow.""" from __future__ import annotations import json import tempfile import unittest from pathlib import Path from test_jwebot_edge import MODULE, config from jwebot_official_extensions import cs_autochess as AUTOCHESS class Release064AutochessTests(unittest.TestCase): def setUp(self): self.temp = tempfile.TemporaryDirectory() self.engine = MODULE.EdgeApplication(config(Path(self.temp.name))) self.counter = 0 def tearDown(self): self.engine.close() self.temp.cleanup() def command(self, question, *, sender="Alice", event_id=None): self.counter += 1 response = self.engine.accept( { "event_id": event_id or f"autochess-{self.counter}", "group_fingerprint": "group-a", "sender": sender, "text": "@JWeBot " + question, "mention_bot": True, "confidence": 1.0, "sender_confidence": 1.0, "body_confidence": 1.0, } ) self.assertEqual(response["status"], "reply") return list(response.get("texts") or [response["text"]]) def state(self): row = self.engine.ledger.connection.execute( """ SELECT state_json FROM autochess_runs WHERE group_fingerprint = 'group-a' ORDER BY season_number DESC LIMIT 1 """ ).fetchone() self.assertIsNotNone(row) return json.loads(row[0]) def start_two_human_two_ai(self): self.command("/自走棋开始") self.command("/自走棋报名", sender="Bob") self.command("/自走棋加AI战队") return self.command("/自走棋开赛") def finish_draft(self): self.command("/选1") self.command("/选1", sender="Bob") self.command("/选1", sender="Bob") self.command("/选1") self.command("/选1") return self.command("/选1", sender="Bob") def ready_all(self): state = self.state() replies = [] for key in list(state.get("ready_keys") or []): replies.extend( self.command( "/结束回合", sender=state["players"][key]["display_name"], ) ) return replies def test_static_pool_parser_and_coach_pool(self): self.assertEqual(len(AUTOCHESS.PLAYER_POOL), 60) self.assertEqual(len({card["id"] for card in AUTOCHESS.PLAYER_POOL}), 60) self.assertEqual(len(AUTOCHESS.COACH_POOL), 10) self.assertEqual( len({coach["id"] for coach in AUTOCHESS.COACH_POOL}), 10, ) self.assertEqual( AUTOCHESS.parse_autochess_action("/自走棋开始"), ("create", ""), ) self.assertEqual( AUTOCHESS.parse_autochess_action("/选6"), ("buy", "6"), ) self.assertEqual( AUTOCHESS.parse_autochess_action("/战术残局"), ("tactic", "残局"), ) def test_launch_starts_multimessage_coach_draft_not_full_rosters(self): response = self.start_two_human_two_ai() state = self.state() self.assertGreaterEqual(len(response), 5) self.assertIn("第一轮选秀", "\n".join(response)) self.assertIn("1. zonic", "\n".join(response)) self.assertEqual(state["phase"], "draft_coach_1") self.assertEqual(state["ai_test_variant"], "two_plus_two") self.assertEqual( state["seed_order"][2:], [AUTOCHESS.AI_PERSON_KEY, AUTOCHESS.AI_SECOND_PERSON_KEY], ) for player in state["players"].values(): self.assertEqual(player["board"], []) self.assertEqual(player["coach_id"], "") def test_three_round_draft_training_and_group_intro(self): self.start_two_human_two_ai() final_draft = self.finish_draft() state = self.state() self.assertIn("三轮选秀结束", "\n".join(final_draft)) self.assertEqual(state["phase"], "lineup_prep") for player in state["players"].values(): self.assertEqual(len(player["board"]), 5) self.assertEqual(len(player["bench"]), 3) self.assertTrue(player["coach_id"]) self.command("/结束回合") training = self.command("/结束回合", sender="Bob") self.assertIn("Team Falcons", "\n".join(training)) self.assertIn("Natus Vincere", "\n".join(training)) self.assertEqual(self.state()["phase"], "training_manage") self.command("/结束回合") group = self.command("/结束回合", sender="Bob") self.assertIn("正赛小组赛", "\n".join(group)) state = self.state() self.assertEqual(state["phase"], "group_ready") self.assertEqual(len(state["group_matches"]), 6) def test_full_tournament_completes_and_only_active_playoff_players_ready(self): self.start_two_human_two_ai() self.finish_draft() seen_playoff_prompt = False for _ in range(80): state = self.state() if state["status"] == "completed": break ready_keys = list(state.get("ready_keys") or []) self.assertTrue(ready_keys, state["phase"]) if state["phase"] in {"semifinal_ready", "final_ready"}: pair = set(state["current_match"]["pair"]) self.assertEqual(set(ready_keys), pair & set(AUTOCHESS._human_keys(state))) seen_playoff_prompt = True self.ready_all() else: self.fail("tournament did not complete") state = self.state() self.assertTrue(seen_playoff_prompt) self.assertEqual(state["status"], "completed") self.assertEqual(state["phase"], "completed") self.assertTrue(state["champion_key"]) def test_multimessage_response_replays_identically(self): self.command("/自走棋开始") self.command("/自走棋报名", sender="Bob") self.command("/自走棋加AI战队") first = self.command("/自走棋开赛", event_id="same-launch") replay = self.command("/自走棋开赛", event_id="same-launch") self.assertEqual(first, replay) self.assertGreater(len(first), 1) if __name__ == "__main__": unittest.main()