diff --git a/make_post_sell/tests/test_crypto_watcher.py b/make_post_sell/tests/test_crypto_watcher.py index ab19ce4..e8a50c4 100644 --- a/make_post_sell/tests/test_crypto_watcher.py +++ b/make_post_sell/tests/test_crypto_watcher.py @@ -2992,13 +2992,16 @@ class RefundTypeTests(unittest.TestCase): "refund_amount": Decimal("4.55"), # 4.55 DOGE refund "fee_amount": Decimal("0.45"), # 0.45 DOGE fee "reason": "Test DOGE refund", - "type": "underpayment", + "type": "Overpayment", } result = rescue.execute_refund(refund_details, doge_payment) # Verify DOGE-specific RPC was called - mock_client.sendtoaddress.assert_called_once_with("DTestAddress123", 4.55) + # mock_client.sendtoaddress.assert_called_once_with("DTestAddress123", 4.55, "Overpayment refund for doge-payment-123") + mock_client.sendtoaddress.assert_called_once_with( + "DTestAddress123", 4.55, "Overpayment refund for doge-payment-123" + ) mock_client.getbalance.assert_called_once() # Balance check # Verify successful result @@ -3141,6 +3144,100 @@ class RefundTypeTests(unittest.TestCase): self.assertFalse(result["success"]) self.assertIn("not supported for coin type", result["error"]) + def test_doge_refund_amount_precision_handling(self): + """Test DOGE refund execution rounds amounts to 8 decimal places.""" + from make_post_sell.lib.crypto_payment_rescue import PaymentRescue + + # Create DOGE payment + doge_payment = MagicMock() + doge_payment.id = "doge-precision-123" + doge_payment.coin_type = "DOGE" + doge_payment.current_confirmations = 2 + doge_payment.account_index = None + + mock_client = MagicMock() + mock_client.sendtoaddress.return_value = "doge-precision-tx-123" + mock_client.getbalance.return_value = 100.0 + + rescue = PaymentRescue(self.mock_dbsession, mock_client) + + # Test with high precision amount (10 decimal places) + refund_details = { + "payment_id": "doge-precision-123", + "refund_address": "DPrecisionTest123", + "refund_amount": Decimal("1.0385903528"), # 10 decimal places + "fee_amount": Decimal("0.1142945472"), # 10 decimal places + "reason": "Test DOGE precision", + "type": "overpayment", + } + + result = rescue.execute_refund(refund_details, doge_payment) + + # Should succeed + self.assertTrue(result["success"]) + self.assertEqual(result["tx_hash"], "doge-precision-tx-123") + + # Verify sendtoaddress was called with rounded amount (8 decimal places) + mock_client.sendtoaddress.assert_called_once_with( + "DPrecisionTest123", + 1.03859035, # Rounded to 8 decimal places + "Overpayment refund for doge-precision-123", + ) + + def test_xmr_refund_amount_precision_handling(self): + """Test XMR refund execution handles high precision amounts correctly.""" + from make_post_sell.lib.crypto_payment_rescue import PaymentRescue + + # Create XMR payment + xmr_payment = MagicMock() + xmr_payment.id = "xmr-precision-123" + xmr_payment.coin_type = "XMR" + xmr_payment.current_confirmations = 10 + xmr_payment.account_index = 2 + + mock_client = MagicMock() + mock_client._call.return_value = {"tx_hash": "xmr-precision-tx-123"} + + # Mock balance check + mock_client._call.side_effect = [ + {"unlocked_balance": 100000000000000}, # get_balance call + {"tx_hash": "xmr-precision-tx-123"}, # transfer call + ] + + rescue = PaymentRescue(self.mock_dbsession, mock_client) + + # Test with high precision amount (12 decimal places for XMR) + refund_details = { + "payment_id": "xmr-precision-123", + "refund_address": "4XMRPrecisionTest123", + "refund_amount": Decimal("0.123456789123"), # 12 decimal places + "fee_amount": Decimal("0.013717354347"), # 12 decimal places + "reason": "Test XMR precision", + "type": "overpayment", + } + + result = rescue.execute_refund(refund_details, xmr_payment) + + # Should succeed + self.assertTrue(result["success"]) + self.assertEqual(result["tx_hash"], "xmr-precision-tx-123") + + # Verify transfer was called with amount in atomic units (piconero) + # 0.123456789123 XMR * 1e12 = 123456789123 piconero + expected_atomic_amount = 123456789123 + + # Check the transfer call (second call) + transfer_call = mock_client._call.call_args_list[1] + self.assertEqual(transfer_call[0][0], "transfer") # method + transfer_params = transfer_call[0][1] # params + self.assertEqual( + transfer_params["destinations"][0]["amount"], expected_atomic_amount + ) + self.assertEqual( + transfer_params["destinations"][0]["address"], "4XMRPrecisionTest123" + ) + self.assertEqual(transfer_params["account_index"], 2) + class PaymentConfirmationOrderTests(unittest.TestCase): """Unit tests for proper order of operations in payment confirmation."""