/** * Card Storage integration tests * * NOTE: These tests require the card storage feature to be enabled in the iyzico merchant panel. * If the feature is not enabled, tests will be skipped automatically. */ import { describe, it, expect } from 'vitest'; import { createTestClient, assertSuccessResponse } from '../setup'; import { testCardCreateRequest } from '../fixtures/card'; import { IyzicoResponseError } from '../../src/errors'; import type { ErrorResponse } from '../../src/types'; describe('Card Storage Integration Tests', () => { const client = createTestClient(); // Flag to track if card storage feature is available let cardStorageFeatureAvailable = true; let cardUserKey: string | undefined; let cardToken: string | undefined; // Helper to skip test if card storage feature is not available const skipIfUnavailable = () => { if (!cardStorageFeatureAvailable) { console.log('Skipping: Card storage feature not enabled in merchant panel'); return true; } return false; }; it('should create a card for a new user', async () => { const request = { ...testCardCreateRequest, conversationId: `test-card-create-${Date.now()}`, externalId: `external-${Date.now()}`, }; try { const response = await client.cardStorage.createCard(request); assertSuccessResponse(response); expect(response.cardUserKey).toBeTruthy(); expect(response.cardToken).toBeTruthy(); expect(response.lastFourDigits).toBeTruthy(); cardUserKey = response.cardUserKey; cardToken = response.cardToken; } catch (error) { // Check if card storage feature is not enabled if (error instanceof IyzicoResponseError) { const errorCode = error.errorResponse?.errorCode; const errorMessage = error.errorResponse?.errorMessage || ''; // Error code 100001 = system error, or specific message for card storage not enabled if (errorCode === '100001' || errorMessage.includes('Kart saklama özelliği tanımlı değil')) { cardStorageFeatureAvailable = false; console.log('Card storage feature not enabled in merchant panel. Skipping card storage tests.'); return; // Skip this test gracefully } } throw error; } }); it('should list cards for a user', async () => { if (skipIfUnavailable()) return; if (!cardUserKey) { // Create a card first if we don't have one const createResponse = await client.cardStorage.createCard({ ...testCardCreateRequest, conversationId: `test-list-${Date.now()}`, externalId: `external-list-${Date.now()}`, }); cardUserKey = createResponse.cardUserKey; } const response = await client.cardStorage.listCards({ cardUserKey: cardUserKey!, locale: 'tr', conversationId: `test-list-${Date.now()}`, }); assertSuccessResponse(response); expect(response.cardUserKey).toBe(cardUserKey); expect(response.cardDetails).toBeTruthy(); }); it('should delete a card', async () => { if (skipIfUnavailable()) return; if (!cardUserKey || !cardToken) { // Create a card first if we don't have one const createResponse = await client.cardStorage.createCard({ ...testCardCreateRequest, conversationId: `test-delete-${Date.now()}`, externalId: `external-delete-${Date.now()}`, }); cardUserKey = createResponse.cardUserKey; cardToken = createResponse.cardToken; } const response = await client.cardStorage.deleteCard({ cardUserKey: cardUserKey!, cardToken: cardToken!, locale: 'tr', conversationId: `test-delete-${Date.now()}`, }); assertSuccessResponse(response); }); describe('Edge Cases - Invalid Fields', () => { it('should handle missing card data', async () => { if (skipIfUnavailable()) return; try { const response = await client.cardStorage.createCard({ locale: 'tr', conversationId: `test-missing-card-${Date.now()}`, email: 'email@email.com', externalId: `external-${Date.now()}`, card: undefined as any, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } }); it('should handle missing email', async () => { if (skipIfUnavailable()) return; try { const response = await client.cardStorage.createCard({ locale: 'tr', conversationId: `test-missing-email-${Date.now()}`, email: undefined as any, externalId: `external-${Date.now()}`, card: testCardCreateRequest.card, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } }); it('should handle invalid email format', async () => { if (skipIfUnavailable()) return; try { const response = await client.cardStorage.createCard({ locale: 'tr', conversationId: `test-invalid-email-${Date.now()}`, email: 'invalid-email-format', externalId: `external-${Date.now()}`, card: testCardCreateRequest.card, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } }); it('should handle missing externalId', async () => { if (skipIfUnavailable()) return; try { const response = await client.cardStorage.createCard({ locale: 'tr', conversationId: `test-missing-externalid-${Date.now()}`, email: 'email@email.com', externalId: undefined as any, card: testCardCreateRequest.card, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } }); it('should handle invalid card number', async () => { if (skipIfUnavailable()) return; try { const response = await client.cardStorage.createCard({ locale: 'tr', conversationId: `test-invalid-card-number-${Date.now()}`, email: 'email@email.com', externalId: `external-${Date.now()}`, card: { ...testCardCreateRequest.card, cardNumber: '1234', }, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } }); it('should handle invalid expiry month', async () => { if (skipIfUnavailable()) return; try { const response = await client.cardStorage.createCard({ locale: 'tr', conversationId: `test-invalid-expmonth-${Date.now()}`, email: 'email@email.com', externalId: `external-${Date.now()}`, card: { ...testCardCreateRequest.card, expireMonth: '13', }, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } }); it('should handle invalid expiry year (past year)', async () => { if (skipIfUnavailable()) return; const pastYear = new Date().getFullYear() - 1; try { const response = await client.cardStorage.createCard({ locale: 'tr', conversationId: `test-invalid-expyear-${Date.now()}`, email: 'email@email.com', externalId: `external-${Date.now()}`, card: { ...testCardCreateRequest.card, expireYear: String(pastYear), }, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } }); it('should handle invalid cardUserKey for listCards', async () => { if (skipIfUnavailable()) return; try { const response = await client.cardStorage.listCards({ cardUserKey: 'invalid-user-key-99999', locale: 'tr', conversationId: `test-invalid-userkey-${Date.now()}`, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } }); it('should handle empty cardUserKey for listCards', async () => { if (skipIfUnavailable()) return; try { const response = await client.cardStorage.listCards({ cardUserKey: '', locale: 'tr', conversationId: `test-empty-userkey-${Date.now()}`, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } }); it('should handle invalid cardToken for deleteCard', async () => { if (skipIfUnavailable()) return; // First create a card to get a valid cardUserKey const createResponse = await client.cardStorage.createCard({ ...testCardCreateRequest, conversationId: `test-delete-invalid-token-${Date.now()}`, externalId: `external-${Date.now()}`, }); assertSuccessResponse(createResponse); if (createResponse.cardUserKey) { try { const response = await client.cardStorage.deleteCard({ cardUserKey: createResponse.cardUserKey, cardToken: 'invalid-card-token-99999', locale: 'tr', conversationId: `test-delete-invalid-token-${Date.now()}`, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } } }); it('should handle empty cardToken for deleteCard', async () => { if (skipIfUnavailable()) return; // First create a card to get a valid cardUserKey const createResponse = await client.cardStorage.createCard({ ...testCardCreateRequest, conversationId: `test-delete-empty-token-${Date.now()}`, externalId: `external-${Date.now()}`, }); assertSuccessResponse(createResponse); if (createResponse.cardUserKey) { try { const response = await client.cardStorage.deleteCard({ cardUserKey: createResponse.cardUserKey, cardToken: '', locale: 'tr', conversationId: `test-delete-empty-token-${Date.now()}`, }); expect(response).toBeDefined(); expect(response.status).toBeDefined(); if (response.status === 'failure') { const errorResponse = response as unknown as ErrorResponse; expect(errorResponse.errorCode || errorResponse.errorMessage).toBeTruthy(); } } catch (error: any) { expect(error).toBeDefined(); expect(error).toBeInstanceOf(Error); } } }); }); });