UNPKG

mcp-banka

Version:

Model Context Protocol Server for Turkish Currency and Exchange Rate data from the Central Bank of The Republic of Turkey (TCMB) (TCMB)

315 lines (314 loc) โ€ข 14.2 kB
import { TcmbApiClient } from './api.js'; async function runTests() { console.log('๐Ÿงช Starting TCMB API Tests...'); console.log('=============================='); const api = new TcmbApiClient(); let testsPassed = 0; let testsFailed = 0; // Get real-time XML data for use in later tests let realXmlData = ''; try { realXmlData = await api.fetchData(); console.log('โ„น๏ธ Fetched real-time XML data for testing'); } catch (error) { console.error('โŒ Failed to fetch real-time XML data:', error instanceof Error ? error.message : String(error)); } // Test 1: URL Generation try { const today = new Date(); const url = api.generateUrl(today); console.log('โœ… Test 1: URL Generation:', url); // Validate URL format if (url.includes('https://www.tcmb.gov.tr/kurlar/') && url.endsWith('.xml')) { console.log(' URL validation passed'); testsPassed++; } else { throw new Error('URL format validation failed'); } } catch (error) { console.error('โŒ Test 1: URL Generation failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('------------------------------'); // Test 2: Fetch XML Data try { // We already fetched the XML data above const xmlData = realXmlData || await api.fetchData(); // Verify it's valid XML by checking for expected tags if (xmlData.includes('<Tarih_Date') && xmlData.includes('<Currency')) { console.log('โœ… Test 2: Fetch XML Data - Successfully retrieved XML data'); console.log(' XML Sample:', xmlData.substring(0, 100) + '...'); testsPassed++; } else { throw new Error('XML data does not contain expected tags'); } } catch (error) { console.error('โŒ Test 2: Fetch XML Data failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('------------------------------'); // Test 3: XML to JSON Conversion try { const jsonData = await api.fetchDataAsJson(); if (jsonData && jsonData.Tarih_Date && jsonData.Tarih_Date.Currency) { console.log('โœ… Test 3: XML to JSON Conversion - Successfully converted XML to JSON'); console.log(' Date in Response:', jsonData.Tarih_Date['@Date'] || jsonData.Tarih_Date['@Tarih']); // Check if Currency array exists and has items const currencies = Array.isArray(jsonData.Tarih_Date.Currency) ? jsonData.Tarih_Date.Currency : [jsonData.Tarih_Date.Currency]; console.log(` Number of currencies found: ${currencies.length}`); testsPassed++; } else { throw new Error('JSON data does not contain expected structure'); } } catch (error) { console.error('โŒ Test 3: XML to JSON Conversion failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('------------------------------'); // Test 4: Get Today's Exchange Rate for USD try { const { response, currencyCode } = await api.getTodayExchangeRate('USD'); const currencies = Array.isArray(response.Tarih_Date.Currency) ? response.Tarih_Date.Currency : [response.Tarih_Date.Currency]; const usdCurrency = currencies.find(c => c['@Kod'] === 'USD'); if (usdCurrency) { console.log('โœ… Test 4: Get Today USD Rate:'); console.log(` USD/TRY Forex Buying: ${usdCurrency.ForexBuying}`); console.log(` USD/TRY Forex Selling: ${usdCurrency.ForexSelling}`); testsPassed++; } else { throw new Error('USD currency data not found in response'); } } catch (error) { console.error('โŒ Test 4: Get Today USD Rate failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('------------------------------'); // Test 5: Get Exchange Rate History try { // Try getting EUR rate from a specific date (one week ago) const pastDate = new Date(); pastDate.setDate(pastDate.getDate() - 7); const dateString = pastDate.toISOString().split('T')[0]; // YYYY-MM-DD format const eurHistory = await api.getExchangeRateHistory('EUR', dateString); if (Array.isArray(eurHistory)) { console.log(`โŒ Test 5: Get EUR Rate for ${dateString} - Unexpected array returned`); testsFailed++; } else if (eurHistory.currency === 'EUR') { console.log(`โœ… Test 5: Get EUR Rate for ${dateString}:`); console.log(` Date: ${eurHistory.date}`); console.log(` EUR/TRY Forex Buying: ${eurHistory.ForexBuying}`); console.log(` EUR/TRY Forex Selling: ${eurHistory.ForexSelling}`); testsPassed++; } else { throw new Error('EUR currency data not found or in unexpected format'); } } catch (error) { console.error('โŒ Test 5: Get Exchange Rate History failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('------------------------------'); // Test 6: Error Handling - Invalid Currency Code try { const invalidResult = await api.getExchangeRateHistory('INVALID', '2023-01-01'); // Since our API returns all currencies when it can't find the specified one if (Array.isArray(invalidResult)) { console.log('โœ… Test 6: Error Handling - Invalid Currency Code - Successfully handled invalid currency'); console.log(` Returned ${invalidResult.length} currencies as fallback`); testsPassed++; } else { console.log('โ“ Test 6: Error Handling - Invalid Currency Code - Unexpected behavior, but no error thrown'); testsPassed += 0.5; } } catch (error) { console.log('โœ… Test 6: Error Handling - Invalid Currency Code - Successfully caught error:', error instanceof Error ? error.message : String(error)); testsPassed++; } console.log('------------------------------'); // Test 7: Weekend Date Adjustment try { // Create a date for the next Saturday const saturdayDate = new Date(); while (saturdayDate.getDay() !== 6) { saturdayDate.setDate(saturdayDate.getDate() + 1); } const url = api.generateUrl(saturdayDate); console.log('โœ… Test 7: Weekend Date Adjustment:'); console.log(` Saturday date: ${saturdayDate.toISOString().split('T')[0]}`); console.log(` Adjusted URL: ${url}`); // Should contain Friday's date (yesterday) const fridayDate = new Date(saturdayDate); fridayDate.setDate(fridayDate.getDate() - 1); const fridayDateString = `${String(fridayDate.getDate()).padStart(2, '0')}${String(fridayDate.getMonth() + 1).padStart(2, '0')}${fridayDate.getFullYear()}`; if (url.includes(fridayDateString)) { console.log(' Date adjustment validation passed (Friday date found in URL)'); testsPassed++; } else { throw new Error('Weekend date adjustment validation failed'); } } catch (error) { console.error('โŒ Test 7: Weekend Date Adjustment failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('------------------------------'); // NEW TEST 8: Parse today's XML with xmlToJson (test-specific) try { // Access the private xmlToJson method through a hack (for testing only) const anyApi = api; const jsonData = anyApi.xmlToJson(realXmlData); // Validate the structure if (jsonData && jsonData.Tarih_Date) { console.log('โœ… Test 8: Today\'s XML Parsing - Basic structure parsed'); // Validate currencies const currencies = Array.isArray(jsonData.Tarih_Date.Currency) ? jsonData.Tarih_Date.Currency : [jsonData.Tarih_Date.Currency]; if (currencies.length >= 1) { console.log(` Found ${currencies.length} currencies in today\'s XML`); const usdCurrency = currencies.find((c) => c['@Kod'] === 'USD'); if (usdCurrency) { console.log(` USD currency found with ForexBuying: ${usdCurrency.ForexBuying}`); testsPassed++; } else { throw new Error('USD currency not found in parsed XML'); } } else { throw new Error(`No currencies found in parsed XML`); } } else { throw new Error('Today\'s XML was not parsed correctly'); } } catch (error) { console.error('โŒ Test 8: Today\'s XML Parsing failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('------------------------------'); // NEW TEST 9: Parse today's XML and verify specific currency values try { // Access the private xmlToJson method through a hack (for testing only) const anyApi = api; const jsonData = anyApi.xmlToJson(realXmlData); // Find the EUR currency in the parsed data const currencies = Array.isArray(jsonData.Tarih_Date.Currency) ? jsonData.Tarih_Date.Currency : [jsonData.Tarih_Date.Currency]; const eurCurrency = currencies.find((c) => c['@Kod'] === 'EUR'); if (eurCurrency) { console.log('โœ… Test 9: Today\'s Currency Values - Found EUR currency'); // Verify key values are present (not specific values as they change daily) if (eurCurrency['@Kod'] === 'EUR' && eurCurrency.ForexBuying && eurCurrency.ForexSelling) { console.log(' Key EUR currency values verified:'); console.log(` - Kod: ${eurCurrency['@Kod']}`); console.log(` - ForexBuying: ${eurCurrency.ForexBuying}`); console.log(` - ForexSelling: ${eurCurrency.ForexSelling}`); testsPassed++; } else { throw new Error('Key EUR values missing from today\'s data'); } } else { throw new Error('EUR currency not found in today\'s XML parsing result'); } } catch (error) { console.error('โŒ Test 9: Today\'s Currency Values failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('------------------------------'); // NEW TEST 10: Test extractCurrencyData with today's XML try { // Access the private methods through a hack (for testing only) const anyApi = api; const jsonData = anyApi.xmlToJson(realXmlData); // Use the extractCurrencyData method to get GBP data const gbpData = anyApi.extractCurrencyData(jsonData, 'GBP'); if (gbpData && gbpData.currency === 'GBP') { console.log('โœ… Test 10: Extract Specific Currency - GBP data extracted'); // Verify GBP values are present (not specific values as they change daily) if (gbpData.ForexBuying && gbpData.ForexSelling) { console.log(' GBP values correctly extracted:'); console.log(` - ForexBuying: ${gbpData.ForexBuying}`); console.log(` - ForexSelling: ${gbpData.ForexSelling}`); if (gbpData.CrossRateOther) { console.log(` - CrossRateOther: ${gbpData.CrossRateOther}`); } testsPassed++; } else { throw new Error('GBP data missing key values'); } } else { throw new Error('Failed to extract GBP currency data'); } } catch (error) { console.error('โŒ Test 10: Extract Specific Currency failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('------------------------------'); // NEW TEST 11: Test missing currency with today's XML try { // Access the private methods through a hack (for testing only) const anyApi = api; const jsonData = anyApi.xmlToJson(realXmlData); // Try to extract a currency that doesn't exist const nonExistentCurrency = 'INVALID_CURRENCY'; const invalidData = anyApi.extractCurrencyData(jsonData, nonExistentCurrency); // Our implementation should return all currencies when the requested one isn't found if (Array.isArray(invalidData)) { console.log('โœ… Test 11: Missing Currency Handling - Correctly returned all currencies'); console.log(` Number of currencies returned: ${invalidData.length}`); testsPassed++; } else { throw new Error('Expected an array of all currencies but got a single currency object'); } } catch (error) { console.error('โŒ Test 11: Missing Currency Handling failed:', error instanceof Error ? error.message : String(error)); testsFailed++; } console.log('=============================='); // Show test results console.log(`Tests passed: ${testsPassed} | Tests failed: ${testsFailed}`); console.log(`Test success rate: ${Math.round((testsPassed / (testsPassed + testsFailed)) * 100)}%`); if (testsFailed === 0) { console.log('๐ŸŽ‰ All tests passed!'); } else { console.error(`โš ๏ธ ${testsFailed} test(s) failed!`); } } // Run all tests console.log('Running tests for TcmbApiClient...'); runTests().catch(error => { console.error('โŒ Test execution failed:', error instanceof Error ? error.message : String(error)); });