fixed format issues
This commit is contained in:
parent
a700818a06
commit
08f713d98b
55 changed files with 5680 additions and 5533 deletions
|
|
@ -1,272 +1,290 @@
|
|||
import { describe, it, expect, mock, beforeEach, afterEach, spyOn } from 'bun:test';
|
||||
import { BaseHandler } from '../src/base/BaseHandler';
|
||||
import type { IServiceContainer, ExecutionContext } from '@stock-bot/types';
|
||||
import * as utils from '@stock-bot/utils';
|
||||
|
||||
// Mock fetch
|
||||
const mockFetch = mock();
|
||||
|
||||
class TestHandler extends BaseHandler {
|
||||
async testGet(url: string, options?: any) {
|
||||
return this.http.get(url, options);
|
||||
}
|
||||
|
||||
async testPost(url: string, data?: any, options?: any) {
|
||||
return this.http.post(url, data, options);
|
||||
}
|
||||
|
||||
async testPut(url: string, data?: any, options?: any) {
|
||||
return this.http.put(url, data, options);
|
||||
}
|
||||
|
||||
async testDelete(url: string, options?: any) {
|
||||
return this.http.delete(url, options);
|
||||
}
|
||||
}
|
||||
|
||||
describe('BaseHandler HTTP Methods', () => {
|
||||
let handler: TestHandler;
|
||||
let mockServices: IServiceContainer;
|
||||
|
||||
beforeEach(() => {
|
||||
mockServices = {
|
||||
cache: null,
|
||||
globalCache: null,
|
||||
queueManager: null,
|
||||
proxy: null,
|
||||
browser: null,
|
||||
mongodb: null,
|
||||
postgres: null,
|
||||
questdb: null,
|
||||
logger: {
|
||||
info: mock(),
|
||||
debug: mock(),
|
||||
error: mock(),
|
||||
warn: mock(),
|
||||
} as any,
|
||||
} as IServiceContainer;
|
||||
|
||||
handler = new TestHandler(mockServices, 'TestHandler');
|
||||
|
||||
// Mock utils.fetch
|
||||
spyOn(utils, 'fetch').mockImplementation(mockFetch);
|
||||
mockFetch.mockReset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// spyOn automatically restores
|
||||
});
|
||||
|
||||
describe('GET requests', () => {
|
||||
it('should make GET requests with fetch', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
json: async () => ({ data: 'test' }),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testGet('https://api.example.com/data');
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/data',
|
||||
expect.objectContaining({
|
||||
method: 'GET',
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should pass custom options to GET requests', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testGet('https://api.example.com/data', {
|
||||
headers: { 'Authorization': 'Bearer token' },
|
||||
});
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/data',
|
||||
expect.objectContaining({
|
||||
headers: { 'Authorization': 'Bearer token' },
|
||||
method: 'GET',
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST requests', () => {
|
||||
it('should make POST requests with JSON data', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
json: async () => ({ success: true }),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
const data = { name: 'test', value: 123 };
|
||||
await handler.testPost('https://api.example.com/create', data);
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/create',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should merge custom headers in POST requests', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testPost('https://api.example.com/create', { test: 'data' }, {
|
||||
headers: { 'X-Custom': 'value' },
|
||||
});
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/create',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ test: 'data' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Custom': 'value',
|
||||
},
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT requests', () => {
|
||||
it('should make PUT requests with JSON data', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
const data = { id: 1, name: 'updated' };
|
||||
await handler.testPut('https://api.example.com/update/1', data);
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/update/1',
|
||||
expect.objectContaining({
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle PUT requests with custom options', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testPut('https://api.example.com/update', { data: 'test' }, {
|
||||
headers: { 'If-Match': 'etag' },
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/update',
|
||||
expect.objectContaining({
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ data: 'test' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'If-Match': 'etag',
|
||||
},
|
||||
timeout: 5000,
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE requests', () => {
|
||||
it('should make DELETE requests', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testDelete('https://api.example.com/delete/1');
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/delete/1',
|
||||
expect.objectContaining({
|
||||
method: 'DELETE',
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should pass options to DELETE requests', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testDelete('https://api.example.com/delete/1', {
|
||||
headers: { 'Authorization': 'Bearer token' },
|
||||
});
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/delete/1',
|
||||
expect.objectContaining({
|
||||
headers: { 'Authorization': 'Bearer token' },
|
||||
method: 'DELETE',
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Error handling', () => {
|
||||
it('should propagate fetch errors', async () => {
|
||||
mockFetch.mockRejectedValue(new Error('Network error'));
|
||||
|
||||
await expect(handler.testGet('https://api.example.com/data')).rejects.toThrow('Network error');
|
||||
});
|
||||
|
||||
it('should handle non-ok responses', async () => {
|
||||
const mockResponse = {
|
||||
ok: false,
|
||||
status: 404,
|
||||
statusText: 'Not Found',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
const response = await handler.testGet('https://api.example.com/missing');
|
||||
|
||||
expect(response.ok).toBe(false);
|
||||
expect(response.status).toBe(404);
|
||||
});
|
||||
});
|
||||
});
|
||||
import { afterEach, beforeEach, describe, expect, it, mock, spyOn } from 'bun:test';
|
||||
import type { ExecutionContext, IServiceContainer } from '@stock-bot/types';
|
||||
import * as utils from '@stock-bot/utils';
|
||||
import { BaseHandler } from '../src/base/BaseHandler';
|
||||
|
||||
// Mock fetch
|
||||
const mockFetch = mock();
|
||||
|
||||
class TestHandler extends BaseHandler {
|
||||
async testGet(url: string, options?: any) {
|
||||
return this.http.get(url, options);
|
||||
}
|
||||
|
||||
async testPost(url: string, data?: any, options?: any) {
|
||||
return this.http.post(url, data, options);
|
||||
}
|
||||
|
||||
async testPut(url: string, data?: any, options?: any) {
|
||||
return this.http.put(url, data, options);
|
||||
}
|
||||
|
||||
async testDelete(url: string, options?: any) {
|
||||
return this.http.delete(url, options);
|
||||
}
|
||||
}
|
||||
|
||||
describe('BaseHandler HTTP Methods', () => {
|
||||
let handler: TestHandler;
|
||||
let mockServices: IServiceContainer;
|
||||
|
||||
beforeEach(() => {
|
||||
mockServices = {
|
||||
cache: null,
|
||||
globalCache: null,
|
||||
queueManager: null,
|
||||
proxy: null,
|
||||
browser: null,
|
||||
mongodb: null,
|
||||
postgres: null,
|
||||
questdb: null,
|
||||
logger: {
|
||||
info: mock(),
|
||||
debug: mock(),
|
||||
error: mock(),
|
||||
warn: mock(),
|
||||
} as any,
|
||||
} as IServiceContainer;
|
||||
|
||||
handler = new TestHandler(mockServices, 'TestHandler');
|
||||
|
||||
// Mock utils.fetch
|
||||
spyOn(utils, 'fetch').mockImplementation(mockFetch);
|
||||
mockFetch.mockReset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// spyOn automatically restores
|
||||
});
|
||||
|
||||
describe('GET requests', () => {
|
||||
it('should make GET requests with fetch', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
json: async () => ({ data: 'test' }),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testGet('https://api.example.com/data');
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'https://api.example.com/data',
|
||||
expect.objectContaining({
|
||||
method: 'GET',
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should pass custom options to GET requests', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testGet('https://api.example.com/data', {
|
||||
headers: { Authorization: 'Bearer token' },
|
||||
});
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'https://api.example.com/data',
|
||||
expect.objectContaining({
|
||||
headers: { Authorization: 'Bearer token' },
|
||||
method: 'GET',
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST requests', () => {
|
||||
it('should make POST requests with JSON data', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
json: async () => ({ success: true }),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
const data = { name: 'test', value: 123 };
|
||||
await handler.testPost('https://api.example.com/create', data);
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'https://api.example.com/create',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should merge custom headers in POST requests', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testPost(
|
||||
'https://api.example.com/create',
|
||||
{ test: 'data' },
|
||||
{
|
||||
headers: { 'X-Custom': 'value' },
|
||||
}
|
||||
);
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'https://api.example.com/create',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ test: 'data' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Custom': 'value',
|
||||
},
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT requests', () => {
|
||||
it('should make PUT requests with JSON data', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
const data = { id: 1, name: 'updated' };
|
||||
await handler.testPut('https://api.example.com/update/1', data);
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'https://api.example.com/update/1',
|
||||
expect.objectContaining({
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle PUT requests with custom options', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testPut(
|
||||
'https://api.example.com/update',
|
||||
{ data: 'test' },
|
||||
{
|
||||
headers: { 'If-Match': 'etag' },
|
||||
timeout: 5000,
|
||||
}
|
||||
);
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'https://api.example.com/update',
|
||||
expect.objectContaining({
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ data: 'test' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'If-Match': 'etag',
|
||||
},
|
||||
timeout: 5000,
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE requests', () => {
|
||||
it('should make DELETE requests', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testDelete('https://api.example.com/delete/1');
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'https://api.example.com/delete/1',
|
||||
expect.objectContaining({
|
||||
method: 'DELETE',
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should pass options to DELETE requests', async () => {
|
||||
const mockResponse = {
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
await handler.testDelete('https://api.example.com/delete/1', {
|
||||
headers: { Authorization: 'Bearer token' },
|
||||
});
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'https://api.example.com/delete/1',
|
||||
expect.objectContaining({
|
||||
headers: { Authorization: 'Bearer token' },
|
||||
method: 'DELETE',
|
||||
logger: expect.any(Object),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Error handling', () => {
|
||||
it('should propagate fetch errors', async () => {
|
||||
mockFetch.mockRejectedValue(new Error('Network error'));
|
||||
|
||||
await expect(handler.testGet('https://api.example.com/data')).rejects.toThrow(
|
||||
'Network error'
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle non-ok responses', async () => {
|
||||
const mockResponse = {
|
||||
ok: false,
|
||||
status: 404,
|
||||
statusText: 'Not Found',
|
||||
headers: new Headers(),
|
||||
};
|
||||
mockFetch.mockResolvedValue(mockResponse);
|
||||
|
||||
const response = await handler.testGet('https://api.example.com/missing');
|
||||
|
||||
expect(response.ok).toBe(false);
|
||||
expect(response.status).toBe(404);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue