feat(FEAT-MO-001): 接入TDX市场宽度板块与成交额趋势
This commit is contained in:
@@ -19,6 +19,63 @@ const indexResult = {
|
||||
),
|
||||
};
|
||||
|
||||
const breadthSnapshot = (up: string, down: string) => ({
|
||||
ErrorId: '0',
|
||||
UpHome: up,
|
||||
DownHome: down,
|
||||
ItemNum: '0',
|
||||
});
|
||||
|
||||
const sectorResult = {
|
||||
ErrorId: '0',
|
||||
Value: [
|
||||
{ Code: '881319.SH', Name: '半导体' },
|
||||
{ Code: '881355.SH', Name: '软件服务' },
|
||||
],
|
||||
};
|
||||
|
||||
const sectorKlineResult = {
|
||||
ErrorId: '0',
|
||||
Value: {
|
||||
'881319.SH': {
|
||||
Date: ['20260817', '20260818'],
|
||||
Open: ['100', '105'],
|
||||
High: ['106', '110'],
|
||||
Low: ['99', '104'],
|
||||
Close: ['100', '108'],
|
||||
Amount: ['1000', '1200'],
|
||||
Volume: ['100', '120'],
|
||||
},
|
||||
'881355.SH': {
|
||||
Date: ['20260817', '20260818'],
|
||||
Open: ['100', '98'],
|
||||
High: ['101', '99'],
|
||||
Low: ['97', '95'],
|
||||
Close: ['100', '96'],
|
||||
Amount: ['1000', '900'],
|
||||
Volume: ['100', '90'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const turnoverResult = {
|
||||
ErrorId: '0',
|
||||
Value: Object.fromEntries(
|
||||
['000001.SH', '399001.SZ', '899050.BJ'].map((code) => [
|
||||
code,
|
||||
{
|
||||
Date: ['20260817', '20260818'],
|
||||
Open: ['100', '100'],
|
||||
High: ['101', '101'],
|
||||
Low: ['99', '99'],
|
||||
Close: ['100', '100'],
|
||||
Amount: ['100000', '120000'],
|
||||
Volume: ['1000', '1100'],
|
||||
},
|
||||
]),
|
||||
),
|
||||
};
|
||||
|
||||
describe('市场概览服务', () => {
|
||||
it('读取指数并返回统一快照元数据', async () => {
|
||||
const client = { request: vi.fn().mockResolvedValue(indexResult) };
|
||||
@@ -38,14 +95,69 @@ describe('市场概览服务', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('对未验证的市场宽度能力返回不可用而不是伪造数据', async () => {
|
||||
const client = { request: vi.fn() };
|
||||
it('汇总三个市场指数的上涨和下跌家数并保留未知平盘数', async () => {
|
||||
const client = {
|
||||
request: vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce(breadthSnapshot('10', '5'))
|
||||
.mockResolvedValueOnce(breadthSnapshot('20', '15'))
|
||||
.mockResolvedValueOnce(breadthSnapshot('3', '2')),
|
||||
};
|
||||
const service = new MarketOverviewService(client);
|
||||
|
||||
const response = await service.getBreadth();
|
||||
|
||||
expect(response).toMatchObject({ source: 'tdx', status: 'unavailable', data: null });
|
||||
expect(response.warnings[0]).toContain('市场宽度');
|
||||
expect(client.request).not.toHaveBeenCalled();
|
||||
expect(response).toMatchObject({
|
||||
source: 'tdx',
|
||||
status: 'fresh',
|
||||
data: { advancing: 33, declining: 22, unchanged: null },
|
||||
});
|
||||
expect(client.request).toHaveBeenCalledWith(
|
||||
'get_market_snapshot',
|
||||
expect.objectContaining({ stock_code: '000001.SH' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('按一级行业涨跌幅排序板块并保留 TDX 代码', async () => {
|
||||
const client = {
|
||||
request: vi.fn().mockResolvedValueOnce(sectorResult).mockResolvedValueOnce(sectorKlineResult),
|
||||
};
|
||||
const service = new MarketOverviewService(client);
|
||||
|
||||
const response = await service.getSectors();
|
||||
|
||||
expect(response).toMatchObject({
|
||||
source: 'tdx',
|
||||
status: 'fresh',
|
||||
data: {
|
||||
items: [
|
||||
expect.objectContaining({ code: '881319.SH', name: '半导体', changePercent: 8 }),
|
||||
expect.objectContaining({ code: '881355.SH', name: '软件服务', changePercent: -4 }),
|
||||
],
|
||||
},
|
||||
});
|
||||
expect(client.request).toHaveBeenNthCalledWith(1, 'get_stock_list', {
|
||||
market: '16',
|
||||
list_type: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it('按交易所指数成交额计算亿元级趋势而不宣称主力净流入', async () => {
|
||||
const client = { request: vi.fn().mockResolvedValue(turnoverResult) };
|
||||
const service = new MarketOverviewService(client);
|
||||
|
||||
const response = await service.getFunds();
|
||||
|
||||
expect(response).toMatchObject({
|
||||
source: 'tdx',
|
||||
status: 'fresh',
|
||||
data: {
|
||||
currentAmount: 36,
|
||||
previousAmount: 30,
|
||||
changePercent: 20,
|
||||
unit: '亿元',
|
||||
},
|
||||
});
|
||||
expect(response.warnings).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user