188 lines
6.3 KiB
Python
188 lines
6.3 KiB
Python
"""Behavioral coverage for beta 1.0.5 primogem economy."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import tempfile
|
|
import unittest
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from unittest import mock
|
|
|
|
from test_jwebot_edge import MODULE, config
|
|
|
|
|
|
class Release105PrimogemTests(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
|
|
row = {
|
|
"question": question,
|
|
"sender": sender,
|
|
"group_fingerprint": "group-a",
|
|
"event_id": event_id or f"primogem-{self.counter}",
|
|
}
|
|
return self.engine.local.handle(row, {})
|
|
|
|
def state(self, sender="Alice"):
|
|
key = self.engine.ledger.resolve_person("group-a", sender)["person_key"]
|
|
row = self.engine.ledger.connection.execute(
|
|
"""
|
|
SELECT state_json FROM player_accounts
|
|
WHERE group_fingerprint = ? AND person_key = ?
|
|
""",
|
|
("group-a", key),
|
|
).fetchone()
|
|
self.assertIsNotNone(row)
|
|
return json.loads(row[0])
|
|
|
|
@staticmethod
|
|
def blackjack_deck(*prefix):
|
|
used = set(prefix)
|
|
return list(prefix) + [card for card in range(52) if card not in used]
|
|
|
|
def test_natural_blackjack_grants_primogem_and_wish_can_award_scan_ticket(self):
|
|
deck = self.blackjack_deck(0, 12, 1, 2)
|
|
|
|
def shuffle(cards):
|
|
cards[:] = deck
|
|
|
|
with mock.patch.object(self.engine.local.players.rng, "shuffle", shuffle):
|
|
result = self.command("/21点 开始 10")
|
|
|
|
self.assertIn("+1 原石", result)
|
|
self.assertEqual(self.state()["primogems"], 1)
|
|
|
|
with mock.patch.object(
|
|
self.engine.local.players.rng,
|
|
"randrange",
|
|
side_effect=[0, 0],
|
|
):
|
|
wish = self.command("/原石祈愿")
|
|
|
|
self.assertIn("抽到 20 摩拉", wish)
|
|
self.assertIn("扫码概率券 1 张", wish)
|
|
state = self.state()
|
|
self.assertEqual(state["primogems"], 0)
|
|
self.assertEqual(state["scan_boost_tickets"], 1)
|
|
|
|
def test_extreme_blackjack_hit_from_20_to_21_grants_two_primogems(self):
|
|
prefix = [9, 12, 1, 2]
|
|
deck = self.blackjack_deck(*prefix, 0)
|
|
deck = deck[:4] + [card for card in deck[4:] if card != 0] + [0]
|
|
|
|
def shuffle(cards):
|
|
cards[:] = deck
|
|
|
|
with mock.patch.object(self.engine.local.players.rng, "shuffle", shuffle):
|
|
self.command("/21点 开始 10")
|
|
self.command("/21点 要牌")
|
|
result = self.command("/21点 停牌")
|
|
|
|
self.assertIn("21点极限挑战", result)
|
|
self.assertIn("+2 原石", result)
|
|
self.assertEqual(self.state()["primogems"], 2)
|
|
|
|
def test_lottery_two_consecutive_personal_draws_with_five_total_hits(self):
|
|
self.command("/彩票开始")
|
|
self.command("/彩票34710")
|
|
with mock.patch.object(
|
|
self.engine.local.players.rng,
|
|
"sample",
|
|
return_value=[3, 7, 9],
|
|
):
|
|
self.command("/彩票开奖")
|
|
|
|
self.command("/彩票开始", event_id="lottery-start-two")
|
|
self.command("/彩票34710", event_id="lottery-entry-two")
|
|
with mock.patch.object(
|
|
self.engine.local.players.rng,
|
|
"sample",
|
|
return_value=[3, 4, 7],
|
|
):
|
|
result = self.command("/彩票开奖", event_id="lottery-draw-two")
|
|
|
|
self.assertIn("彩票三中挑战", result)
|
|
self.assertEqual(self.state()["primogems"], 2)
|
|
|
|
def test_scan_boost_and_taffy_say_spend_primogem_resources(self):
|
|
self.command("/原石")
|
|
account = self.state()
|
|
account["primogems"] = 2
|
|
self.engine.ledger._save_player_account(
|
|
"group-a",
|
|
self.engine.ledger.resolve_person("group-a", "Alice")["person_key"],
|
|
account,
|
|
MODULE.utc_now(),
|
|
)
|
|
self.engine.ledger.connection.commit()
|
|
|
|
boost = self.command("/扫码加权 Bob")
|
|
self.assertIn("已给 bob 增加整点扫码权重", boost)
|
|
boost_targets = self.engine.ledger.active_scan_boost_targets("group-a")
|
|
bob_key = self.engine.ledger.resolve_person("group-a", "Bob")["person_key"]
|
|
self.assertIn(bob_key, boost_targets)
|
|
ranking = self.command("/扫码榜", event_id="scan-ranking-after-boost")
|
|
self.assertIn("下一小时扫码权重:", ranking)
|
|
self.assertIn("bob 5", ranking)
|
|
|
|
speech = self.command("/Taffy发话 今天也要加班吗")
|
|
self.assertEqual(speech, "Taffy:今天也要加班吗喵")
|
|
state = self.state()
|
|
self.assertEqual(state["primogems"], 0)
|
|
self.assertEqual(state["taffy_say_credits"], 1)
|
|
|
|
def test_scheduled_taffy_speech_uses_clock_delivery_queue(self):
|
|
self.command("/原石")
|
|
account = self.state()
|
|
account["primogems"] = 1
|
|
person_key = self.engine.ledger.resolve_person("group-a", "Alice")["person_key"]
|
|
self.engine.ledger._save_player_account(
|
|
"group-a",
|
|
person_key,
|
|
account,
|
|
MODULE.utc_now(),
|
|
)
|
|
self.engine.ledger.connection.commit()
|
|
scheduled_at = datetime(
|
|
2026,
|
|
10,
|
|
16,
|
|
8,
|
|
0,
|
|
tzinfo=MODULE.BEIJING_TIMEZONE,
|
|
)
|
|
|
|
response = self.engine.ledger.player_taffy_say(
|
|
"group-a",
|
|
"Alice",
|
|
"scheduled-taffy",
|
|
"taffy_say:test",
|
|
"准点提醒",
|
|
scheduled_at.timestamp(),
|
|
lambda data: self.engine.local.players.render_taffy_say(data, "alice"),
|
|
)
|
|
self.assertIn("已安排Taffy", response)
|
|
|
|
delivered = []
|
|
self.engine.deliver = lambda row: delivered.append(row["result_text"])
|
|
self.assertTrue(
|
|
self.engine.process_clock_once(
|
|
now=scheduled_at,
|
|
group_fingerprint="group-a",
|
|
)
|
|
)
|
|
self.assertEqual(delivered, ["Taffy:准点提醒"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|