Set up continuous P2P VES/USDT market history data collection, normalization, validation, and date-partitioned Parquet storage.
97 lines
3.6 KiB
Python
97 lines
3.6 KiB
Python
import unittest
|
|
from datetime import datetime, timezone
|
|
|
|
import os
|
|
import sys
|
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from validator import validate_row, validate_snapshot
|
|
|
|
class TestValidator(unittest.TestCase):
|
|
def setUp(self):
|
|
self.config = {
|
|
"validation": {
|
|
"price_min": 1.0,
|
|
"price_max": 500.0,
|
|
"reject_zero_finish_rate": True,
|
|
"reject_zero_surplus": True
|
|
}
|
|
}
|
|
|
|
self.valid_row = {
|
|
"adv_no": "12345",
|
|
"price": 58.50,
|
|
"surplus_amount": 100.0,
|
|
"month_finish_rate": 0.95,
|
|
"month_order_count": 100,
|
|
"payment_methods": ["BANESCO"],
|
|
"ad_created_at": datetime.now(timezone.utc)
|
|
}
|
|
|
|
def test_validate_row_valid(self):
|
|
seen = set()
|
|
self.assertTrue(validate_row(self.valid_row, self.config, seen))
|
|
self.assertIn("12345", seen)
|
|
|
|
def test_validate_row_duplicate(self):
|
|
seen = {"12345"}
|
|
self.assertFalse(validate_row(self.valid_row, self.config, seen))
|
|
|
|
def test_validate_row_invalid_price(self):
|
|
seen = set()
|
|
|
|
# Price <= 0
|
|
row_bad_price = self.valid_row.copy()
|
|
row_bad_price["price"] = -1.0
|
|
self.assertFalse(validate_row(row_bad_price, self.config, seen))
|
|
|
|
# Price > max
|
|
row_high_price = self.valid_row.copy()
|
|
row_high_price["price"] = 1000.0
|
|
self.assertFalse(validate_row(row_high_price, self.config, seen))
|
|
|
|
def test_validate_row_zero_surplus(self):
|
|
seen = set()
|
|
row_zero_surplus = self.valid_row.copy()
|
|
row_zero_surplus["surplus_amount"] = 0.0
|
|
self.assertFalse(validate_row(row_zero_surplus, self.config, seen))
|
|
|
|
def test_validate_row_suspicious_finish(self):
|
|
seen = set()
|
|
row_suspicious = self.valid_row.copy()
|
|
row_suspicious["month_finish_rate"] = 0.0
|
|
row_suspicious["month_order_count"] = 5
|
|
self.assertFalse(validate_row(row_suspicious, self.config, seen))
|
|
|
|
def test_validate_snapshot_empty(self):
|
|
with self.assertRaises(ValueError):
|
|
validate_snapshot([], datetime.now(timezone.utc))
|
|
|
|
def test_validate_snapshot_calculations(self):
|
|
fetched_at = datetime.now(timezone.utc)
|
|
ads = [
|
|
# BUY ads
|
|
{"trade_type": "BUY", "price": 58.00, "payment_methods": ["BANESCO"], "ad_created_at": fetched_at},
|
|
{"trade_type": "BUY", "price": 59.00, "payment_methods": ["PAGO_MOVIL"], "ad_created_at": fetched_at},
|
|
# SELL ads
|
|
{"trade_type": "SELL", "price": 61.00, "payment_methods": ["MERCANTIL"], "ad_created_at": fetched_at},
|
|
{"trade_type": "SELL", "price": 62.00, "payment_methods": ["BANESCO"], "ad_created_at": fetched_at},
|
|
]
|
|
|
|
summary = validate_snapshot(ads, fetched_at)
|
|
|
|
self.assertEqual(summary["buy_count"], 2)
|
|
self.assertEqual(summary["sell_count"], 2)
|
|
self.assertEqual(summary["buy_min"], 58.00)
|
|
self.assertEqual(summary["buy_max"], 59.00)
|
|
self.assertEqual(summary["sell_min"], 61.00)
|
|
self.assertEqual(summary["sell_max"], 62.00)
|
|
self.assertEqual(summary["buy_median"], 58.50)
|
|
self.assertEqual(summary["sell_median"], 61.50)
|
|
|
|
# spread = sell_min - buy_max = 61.00 - 59.00 = 2.00
|
|
self.assertEqual(summary["spread"], 2.00)
|
|
self.assertEqual(set(summary["methods"]), {"BANESCO", "PAGO_MOVIL", "MERCANTIL"})
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|