mirror of
https://github.com/duhanbalci/iyzico.git
synced 2026-03-03 20:29:18 +00:00
init
This commit is contained in:
310
tests/unit/http.test.ts
Normal file
310
tests/unit/http.test.ts
Normal file
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* HTTP client unit tests
|
||||
*/
|
||||
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import { makeRequest } from '../../src/http';
|
||||
import {
|
||||
IyzicoResponseError,
|
||||
IyzicoRequestError,
|
||||
IyzicoError,
|
||||
} from '../../src/errors';
|
||||
|
||||
describe('makeRequest', () => {
|
||||
const apiKey = 'test-api-key';
|
||||
const secretKey = 'test-secret-key';
|
||||
const baseUrl = 'https://api.test.com';
|
||||
|
||||
// Store original fetch to restore it later
|
||||
const originalFetch = globalThis.fetch;
|
||||
const mockFetch = vi.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
// Mock fetch before each test
|
||||
globalThis.fetch = mockFetch as any;
|
||||
mockFetch.mockClear();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Restore original fetch after each test
|
||||
globalThis.fetch = originalFetch;
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should make a successful POST request', async () => {
|
||||
const mockResponse = {
|
||||
status: 'success',
|
||||
data: 'test data',
|
||||
};
|
||||
|
||||
mockFetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: async () => mockResponse,
|
||||
});
|
||||
|
||||
const result = await makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
});
|
||||
|
||||
expect(result).toEqual(mockResponse);
|
||||
expect(mockFetch).toHaveBeenCalledTimes(1);
|
||||
const callArgs = mockFetch.mock.calls[0];
|
||||
expect(callArgs[0]).toBe('https://api.test.com/test');
|
||||
expect(callArgs[1].method).toBe('POST');
|
||||
expect(callArgs[1].headers).toHaveProperty('Authorization');
|
||||
expect(callArgs[1].headers).toHaveProperty('Content-Type', 'application/json');
|
||||
expect(callArgs[1].headers).toHaveProperty('x-iyzi-rnd');
|
||||
});
|
||||
|
||||
it('should make a successful GET request without body', async () => {
|
||||
const mockResponse = {
|
||||
status: 'success',
|
||||
data: 'test data',
|
||||
};
|
||||
|
||||
mockFetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: async () => mockResponse,
|
||||
});
|
||||
|
||||
const result = await makeRequest({
|
||||
method: 'GET',
|
||||
path: '/test',
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
});
|
||||
|
||||
expect(result).toEqual(mockResponse);
|
||||
expect(mockFetch).toHaveBeenCalledTimes(1);
|
||||
const callArgs = mockFetch.mock.calls[0];
|
||||
expect(callArgs[1].body).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should throw IyzicoResponseError for failure responses', async () => {
|
||||
const errorResponse = {
|
||||
status: 'failure',
|
||||
errorCode: 'TEST_ERROR',
|
||||
errorMessage: 'Test error message',
|
||||
};
|
||||
|
||||
mockFetch.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
json: async () => errorResponse,
|
||||
});
|
||||
|
||||
await expect(
|
||||
makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
}),
|
||||
).rejects.toThrow(IyzicoResponseError);
|
||||
});
|
||||
|
||||
it('should throw IyzicoResponseError for failure status in response', async () => {
|
||||
const errorResponse = {
|
||||
status: 'failure',
|
||||
errorCode: 'TEST_ERROR',
|
||||
errorMessage: 'Test error message',
|
||||
};
|
||||
|
||||
mockFetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: async () => errorResponse,
|
||||
});
|
||||
|
||||
await expect(
|
||||
makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
}),
|
||||
).rejects.toThrow(IyzicoResponseError);
|
||||
});
|
||||
|
||||
it('should use fallback message when errorMessage is missing', async () => {
|
||||
const errorResponse = {
|
||||
status: 'failure',
|
||||
errorCode: 'TEST_ERROR',
|
||||
// errorMessage is missing
|
||||
};
|
||||
|
||||
mockFetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: async () => errorResponse,
|
||||
});
|
||||
|
||||
await expect(
|
||||
makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
}),
|
||||
).rejects.toThrow(IyzicoResponseError);
|
||||
});
|
||||
|
||||
it('should handle network errors with fetch in message', async () => {
|
||||
const networkError = new TypeError('Failed to fetch');
|
||||
mockFetch.mockRejectedValueOnce(networkError);
|
||||
|
||||
await expect(
|
||||
makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
}),
|
||||
).rejects.toThrow(IyzicoRequestError);
|
||||
});
|
||||
|
||||
it('should rethrow IyzicoResponseError', async () => {
|
||||
const errorResponse = {
|
||||
status: 'failure',
|
||||
errorCode: 'TEST_ERROR',
|
||||
errorMessage: 'Test error',
|
||||
} as const;
|
||||
const responseError = new IyzicoResponseError('Test error', errorResponse);
|
||||
mockFetch.mockRejectedValueOnce(responseError);
|
||||
|
||||
await expect(
|
||||
makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
}),
|
||||
).rejects.toThrow(IyzicoResponseError);
|
||||
});
|
||||
|
||||
it('should rethrow IyzicoRequestError', async () => {
|
||||
const requestError = new IyzicoRequestError('Request failed');
|
||||
mockFetch.mockRejectedValueOnce(requestError);
|
||||
|
||||
await expect(
|
||||
makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
}),
|
||||
).rejects.toThrow(IyzicoRequestError);
|
||||
});
|
||||
|
||||
it('should rethrow IyzicoError', async () => {
|
||||
const iyzicoError = new IyzicoError('Iyzico error');
|
||||
mockFetch.mockRejectedValueOnce(iyzicoError);
|
||||
|
||||
await expect(
|
||||
makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
}),
|
||||
).rejects.toThrow(IyzicoError);
|
||||
});
|
||||
|
||||
it('should wrap unknown errors in IyzicoError', async () => {
|
||||
const unknownError = new Error('Unknown error');
|
||||
mockFetch.mockRejectedValueOnce(unknownError);
|
||||
|
||||
await expect(
|
||||
makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
}),
|
||||
).rejects.toThrow(IyzicoError);
|
||||
});
|
||||
|
||||
it('should wrap non-Error objects in IyzicoError', async () => {
|
||||
mockFetch.mockRejectedValueOnce('String error');
|
||||
|
||||
await expect(
|
||||
makeRequest({
|
||||
method: 'POST',
|
||||
path: '/test',
|
||||
body: { test: 'value' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
}),
|
||||
).rejects.toThrow(IyzicoError);
|
||||
});
|
||||
|
||||
it('should handle DELETE request with body', async () => {
|
||||
const mockResponse = {
|
||||
status: 'success',
|
||||
data: 'deleted',
|
||||
};
|
||||
|
||||
mockFetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: async () => mockResponse,
|
||||
});
|
||||
|
||||
const result = await makeRequest({
|
||||
method: 'DELETE',
|
||||
path: '/test',
|
||||
body: { id: '123' },
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
});
|
||||
|
||||
expect(result).toEqual(mockResponse);
|
||||
const callArgs = mockFetch.mock.calls[0];
|
||||
expect(callArgs[1].method).toBe('DELETE');
|
||||
expect(callArgs[1].body).toBe(JSON.stringify({ id: '123' }));
|
||||
});
|
||||
|
||||
it('should handle GET request with query string', async () => {
|
||||
const mockResponse = {
|
||||
status: 'success',
|
||||
data: 'test data',
|
||||
};
|
||||
|
||||
mockFetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: async () => mockResponse,
|
||||
});
|
||||
|
||||
const result = await makeRequest({
|
||||
method: 'GET',
|
||||
path: '/test?param=value',
|
||||
apiKey,
|
||||
secretKey,
|
||||
baseUrl,
|
||||
});
|
||||
|
||||
expect(result).toEqual(mockResponse);
|
||||
const callArgs = mockFetch.mock.calls[0];
|
||||
expect(callArgs[0]).toBe('https://api.test.com/test?param=value');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user