|
| 1 | +""" |
| 2 | +Basic tests for Vortex SDK Python wrapper |
| 3 | +""" |
| 4 | + |
| 5 | +import pytest |
| 6 | +from unittest.mock import Mock, patch |
| 7 | +from vortex_sdk import VortexSDK, FiatToken, EvmToken, Networks |
| 8 | +from vortex_sdk.exceptions import VortexSDKError, APIError |
| 9 | + |
| 10 | + |
| 11 | +class TestVortexSDK: |
| 12 | + """Test suite for VortexSDK class.""" |
| 13 | + |
| 14 | + @pytest.fixture |
| 15 | + def mock_sdk_path(self, tmp_path): |
| 16 | + """Create a mock SDK file.""" |
| 17 | + sdk_file = tmp_path / "index.js" |
| 18 | + sdk_file.write_text("module.exports = { VortexSdk: function() {} };") |
| 19 | + return str(sdk_file) |
| 20 | + |
| 21 | + @pytest.fixture |
| 22 | + def config(self): |
| 23 | + """Basic SDK configuration.""" |
| 24 | + return { |
| 25 | + "apiBaseUrl": "https://api-sandbox.vortexfinance.co" |
| 26 | + } |
| 27 | + |
| 28 | + def test_initialization(self, config, monkeypatch): |
| 29 | + """Test SDK initialization.""" |
| 30 | + with patch('vortex_sdk.sdk.pm') as mock_pm: |
| 31 | + # Mock the VortexSdk class |
| 32 | + mock_sdk_instance = Mock() |
| 33 | + mock_pm.eval.return_value = Mock(return_value=mock_sdk_instance) |
| 34 | + |
| 35 | + sdk = VortexSDK(config) |
| 36 | + assert sdk is not None |
| 37 | + |
| 38 | + def test_create_quote(self, config, monkeypatch): |
| 39 | + """Test quote creation.""" |
| 40 | + with patch('vortex_sdk.sdk.pm') as mock_pm: |
| 41 | + mock_sdk_instance = Mock() |
| 42 | + mock_quote = { |
| 43 | + "id": "test-quote-123", |
| 44 | + "inputAmount": "100000", |
| 45 | + "outputAmount": "1000000", |
| 46 | + "rampType": "on" |
| 47 | + } |
| 48 | + mock_sdk_instance.createQuote = Mock(return_value=mock_quote) |
| 49 | + mock_pm.eval.return_value = Mock(return_value=mock_sdk_instance) |
| 50 | + |
| 51 | + sdk = VortexSDK(config) |
| 52 | + sdk._sdk = mock_sdk_instance |
| 53 | + |
| 54 | + quote_request = { |
| 55 | + "from": "pix", |
| 56 | + "inputAmount": "100000", |
| 57 | + "inputCurrency": FiatToken.BRL, |
| 58 | + "outputCurrency": EvmToken.USDC, |
| 59 | + "rampType": "on", |
| 60 | + "to": Networks.Polygon |
| 61 | + } |
| 62 | + |
| 63 | + result = sdk.create_quote(quote_request) |
| 64 | + assert result["id"] == "test-quote-123" |
| 65 | + mock_sdk_instance.createQuote.assert_called_once_with(quote_request) |
| 66 | + |
| 67 | + def test_get_quote(self, config, monkeypatch): |
| 68 | + """Test getting an existing quote.""" |
| 69 | + with patch('vortex_sdk.sdk.pm') as mock_pm: |
| 70 | + mock_sdk_instance = Mock() |
| 71 | + mock_quote = {"id": "test-quote-123"} |
| 72 | + mock_sdk_instance.getQuote = Mock(return_value=mock_quote) |
| 73 | + mock_pm.eval.return_value = Mock(return_value=mock_sdk_instance) |
| 74 | + |
| 75 | + sdk = VortexSDK(config) |
| 76 | + sdk._sdk = mock_sdk_instance |
| 77 | + |
| 78 | + result = sdk.get_quote("test-quote-123") |
| 79 | + assert result["id"] == "test-quote-123" |
| 80 | + |
| 81 | + def test_register_ramp(self, config, monkeypatch): |
| 82 | + """Test ramp registration.""" |
| 83 | + with patch('vortex_sdk.sdk.pm') as mock_pm: |
| 84 | + mock_sdk_instance = Mock() |
| 85 | + mock_result = { |
| 86 | + "rampProcess": { |
| 87 | + "id": "ramp-123", |
| 88 | + "status": "pending" |
| 89 | + }, |
| 90 | + "unsignedTransactions": [] |
| 91 | + } |
| 92 | + mock_sdk_instance.registerRamp = Mock(return_value=mock_result) |
| 93 | + mock_pm.eval.return_value = Mock(return_value=mock_sdk_instance) |
| 94 | + |
| 95 | + sdk = VortexSDK(config) |
| 96 | + sdk._sdk = mock_sdk_instance |
| 97 | + |
| 98 | + quote = {"id": "quote-123", "rampType": "on", "from": "pix"} |
| 99 | + additional_data = { |
| 100 | + "destinationAddress": "0x123", |
| 101 | + "taxId": "123.456.789-00" |
| 102 | + } |
| 103 | + |
| 104 | + result = sdk.register_ramp(quote, additional_data) |
| 105 | + assert result["rampProcess"]["id"] == "ramp-123" |
| 106 | + |
| 107 | + def test_get_ramp_status(self, config, monkeypatch): |
| 108 | + """Test getting ramp status.""" |
| 109 | + with patch('vortex_sdk.sdk.pm') as mock_pm: |
| 110 | + mock_sdk_instance = Mock() |
| 111 | + mock_status = { |
| 112 | + "id": "ramp-123", |
| 113 | + "status": "processing", |
| 114 | + "currentPhase": "swap" |
| 115 | + } |
| 116 | + mock_sdk_instance.getRampStatus = Mock(return_value=mock_status) |
| 117 | + mock_pm.eval.return_value = Mock(return_value=mock_sdk_instance) |
| 118 | + |
| 119 | + sdk = VortexSDK(config) |
| 120 | + sdk._sdk = mock_sdk_instance |
| 121 | + |
| 122 | + result = sdk.get_ramp_status("ramp-123") |
| 123 | + assert result["status"] == "processing" |
| 124 | + |
| 125 | + def test_start_ramp(self, config, monkeypatch): |
| 126 | + """Test starting a ramp.""" |
| 127 | + with patch('vortex_sdk.sdk.pm') as mock_pm: |
| 128 | + mock_sdk_instance = Mock() |
| 129 | + mock_ramp = { |
| 130 | + "id": "ramp-123", |
| 131 | + "status": "started" |
| 132 | + } |
| 133 | + mock_sdk_instance.startRamp = Mock(return_value=mock_ramp) |
| 134 | + mock_pm.eval.return_value = Mock(return_value=mock_sdk_instance) |
| 135 | + |
| 136 | + sdk = VortexSDK(config) |
| 137 | + sdk._sdk = mock_sdk_instance |
| 138 | + |
| 139 | + result = sdk.start_ramp("ramp-123") |
| 140 | + assert result["status"] == "started" |
| 141 | + |
| 142 | + @pytest.mark.asyncio |
| 143 | + async def test_async_create_quote(self, config, monkeypatch): |
| 144 | + """Test async quote creation.""" |
| 145 | + with patch('vortex_sdk.sdk.pm') as mock_pm: |
| 146 | + mock_sdk_instance = Mock() |
| 147 | + mock_quote = {"id": "test-quote-123"} |
| 148 | + mock_sdk_instance.createQuote = Mock(return_value=mock_quote) |
| 149 | + mock_pm.eval.return_value = Mock(return_value=mock_sdk_instance) |
| 150 | + |
| 151 | + sdk = VortexSDK(config) |
| 152 | + sdk._sdk = mock_sdk_instance |
| 153 | + |
| 154 | + quote_request = { |
| 155 | + "from": "pix", |
| 156 | + "inputAmount": "100000", |
| 157 | + "inputCurrency": FiatToken.BRL, |
| 158 | + "outputCurrency": EvmToken.USDC, |
| 159 | + "rampType": "on", |
| 160 | + "to": Networks.Polygon |
| 161 | + } |
| 162 | + |
| 163 | + result = await sdk.create_quote_async(quote_request) |
| 164 | + assert result["id"] == "test-quote-123" |
| 165 | + |
| 166 | + |
| 167 | +class TestConstants: |
| 168 | + """Test type constants.""" |
| 169 | + |
| 170 | + def test_fiat_tokens(self): |
| 171 | + """Test FiatToken constants.""" |
| 172 | + assert FiatToken.BRL == "BRL" |
| 173 | + assert FiatToken.EUR == "EUR" |
| 174 | + assert FiatToken.USD == "USD" |
| 175 | + |
| 176 | + def test_evm_tokens(self): |
| 177 | + """Test EvmToken constants.""" |
| 178 | + assert EvmToken.USDC == "USDC" |
| 179 | + assert EvmToken.USDT == "USDT" |
| 180 | + |
| 181 | + def test_networks(self): |
| 182 | + """Test Networks constants.""" |
| 183 | + assert Networks.Polygon == "polygon" |
| 184 | + assert Networks.Ethereum == "ethereum" |
| 185 | + assert Networks.Moonbeam == "moonbeam" |
| 186 | + |
| 187 | + |
| 188 | +class TestExceptions: |
| 189 | + """Test custom exceptions.""" |
| 190 | + |
| 191 | + def test_vortex_sdk_error(self): |
| 192 | + """Test VortexSDKError.""" |
| 193 | + error = VortexSDKError("Test error") |
| 194 | + assert str(error) == "Test error" |
| 195 | + |
| 196 | + def test_api_error(self): |
| 197 | + """Test APIError with status code.""" |
| 198 | + error = APIError("API failed", status_code=404) |
| 199 | + assert str(error) == "API failed" |
| 200 | + assert error.status_code == 404 |
0 commit comments