"""Opportunity dataset collection tests.""" from __future__ import annotations import json import tempfile import unittest from datetime import datetime, timezone from pathlib import Path from coinhunter.services import opportunity_dataset_service class OpportunityDatasetServiceTestCase(unittest.TestCase): def test_default_plan_uses_widest_scan_reference_window(self): config = {"opportunity": {"lookback_intervals": ["1h", "4h", "1d"]}} plan = opportunity_dataset_service.build_dataset_plan( config, now=datetime(2026, 4, 21, tzinfo=timezone.utc), ) self.assertEqual(plan.kline_limit, 48) self.assertEqual(plan.reference_days, 48.0) self.assertEqual(plan.simulate_days, 7.0) self.assertEqual(plan.run_days, 7.0) self.assertEqual(plan.total_days, 62.0) def test_collect_dataset_writes_klines_and_probe_metadata(self): config = { "binance": {"spot_base_url": "https://api.binance.test"}, "market": {"default_quote": "USDT"}, "opportunity": { "lookback_intervals": ["1d"], "kline_limit": 2, "simulate_days": 1, "run_days": 1, "auto_research": True, "research_provider": "coingecko", }, } def fake_http_get(url, headers, timeout): query = opportunity_dataset_service.parse_query(url) interval_seconds = 86400 start = int(query["startTime"]) end = int(query["endTime"]) rows = [] cursor = start index = 0 while cursor <= end: close = 100 + index rows.append([cursor, close - 1, close + 1, close - 2, close, 10, cursor + interval_seconds * 1000 - 1, close * 10]) cursor += interval_seconds * 1000 index += 1 return rows def fake_http_status(url, headers, timeout): return 200, "{}" with tempfile.TemporaryDirectory() as tmpdir: output = Path(tmpdir) / "dataset.json" payload = opportunity_dataset_service.collect_opportunity_dataset( config, symbols=["BTCUSDT"], output_path=str(output), http_get=fake_http_get, http_status=fake_http_status, now=datetime(2026, 4, 21, tzinfo=timezone.utc), ) dataset = json.loads(output.read_text(encoding="utf-8")) self.assertEqual(payload["plan"]["reference_days"], 2.0) self.assertEqual(payload["plan"]["total_days"], 4.0) self.assertEqual(payload["external_history"]["status"], "available") self.assertEqual(payload["counts"]["BTCUSDT"]["1d"], 5) self.assertEqual(len(dataset["klines"]["BTCUSDT"]["1d"]), 5)