121 lines
3.8 KiB
TypeScript
121 lines
3.8 KiB
TypeScript
import type { INestApplication } from '@nestjs/common';
|
|
import { Test } from '@nestjs/testing';
|
|
import request from 'supertest';
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { MarketDetailController } from '../src/market-overview/detail/market-detail.controller';
|
|
import { MarketDetailService } from '../src/market-overview/detail/market-detail.service';
|
|
import { TDX_CLIENT_PORT } from '../src/market-overview/market-overview.service';
|
|
|
|
const indexResponse = {
|
|
ErrorId: '0',
|
|
Value: {
|
|
'000001.SH': {
|
|
Date: ['20260817', '20260818'],
|
|
Open: ['100', '102'],
|
|
High: ['103', '106'],
|
|
Low: ['99', '101'],
|
|
Close: ['102', '105'],
|
|
Amount: ['1000', '1200'],
|
|
Volume: ['100', '120'],
|
|
},
|
|
},
|
|
};
|
|
|
|
describe('市场详情 HTTP API', () => {
|
|
let app: INestApplication | undefined;
|
|
|
|
afterEach(async () => {
|
|
await app?.close();
|
|
app = undefined;
|
|
});
|
|
|
|
it('返回指数详情并隐藏 TDX 原始字段', async () => {
|
|
const client = { request: vi.fn().mockResolvedValue(indexResponse) };
|
|
const moduleRef = await Test.createTestingModule({
|
|
controllers: [MarketDetailController],
|
|
providers: [MarketDetailService, { provide: TDX_CLIENT_PORT, useValue: client }],
|
|
}).compile();
|
|
app = moduleRef.createNestApplication();
|
|
app.setGlobalPrefix('api/v1');
|
|
await app.init();
|
|
|
|
const response = await request(app.getHttpServer())
|
|
.get('/api/v1/market-overview/indices/000001.SH/detail?count=2')
|
|
.expect(200);
|
|
|
|
expect(response.body).toMatchObject({
|
|
source: 'tdx',
|
|
data: {
|
|
instrument: { code: '000001.SH', name: '上证指数', type: 'index' },
|
|
series: [{ time: '20260817' }, { time: '20260818' }],
|
|
availableViews: { kline: true, intraday: false },
|
|
},
|
|
});
|
|
expect(JSON.stringify(response.body)).not.toContain('ErrorId');
|
|
});
|
|
|
|
it('拒绝越界数量和非法代码且不调用 TDX', async () => {
|
|
const client = { request: vi.fn() };
|
|
const moduleRef = await Test.createTestingModule({
|
|
controllers: [MarketDetailController],
|
|
providers: [MarketDetailService, { provide: TDX_CLIENT_PORT, useValue: client }],
|
|
}).compile();
|
|
app = moduleRef.createNestApplication();
|
|
app.setGlobalPrefix('api/v1');
|
|
await app.init();
|
|
|
|
await request(app.getHttpServer())
|
|
.get('/api/v1/market-overview/indices/not-a-code/detail')
|
|
.expect(400);
|
|
await request(app.getHttpServer())
|
|
.get('/api/v1/market-overview/indices/000001.SH/detail?count=121')
|
|
.expect(400);
|
|
|
|
expect(client.request).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('板块详情先读目录再返回行业 K 线', async () => {
|
|
const client = {
|
|
request: vi
|
|
.fn()
|
|
.mockResolvedValueOnce({
|
|
ErrorId: '0',
|
|
Value: [{ Code: '881001.SH', Name: '行业总览' }],
|
|
})
|
|
.mockResolvedValueOnce({
|
|
ErrorId: '0',
|
|
Value: {
|
|
'881001.SH': {
|
|
Date: ['20260817', '20260818'],
|
|
Open: ['100', '102'],
|
|
High: ['103', '106'],
|
|
Low: ['99', '101'],
|
|
Close: ['102', '105'],
|
|
Amount: ['1000', '1200'],
|
|
Volume: ['100', '120'],
|
|
},
|
|
},
|
|
}),
|
|
};
|
|
const moduleRef = await Test.createTestingModule({
|
|
controllers: [MarketDetailController],
|
|
providers: [MarketDetailService, { provide: TDX_CLIENT_PORT, useValue: client }],
|
|
}).compile();
|
|
app = moduleRef.createNestApplication();
|
|
app.setGlobalPrefix('api/v1');
|
|
await app.init();
|
|
|
|
const response = await request(app.getHttpServer())
|
|
.get('/api/v1/market-overview/sectors/881001.SH/detail')
|
|
.expect(200);
|
|
|
|
expect(response.body.data.instrument).toEqual({
|
|
code: '881001.SH',
|
|
name: '行业总览',
|
|
type: 'sector',
|
|
});
|
|
expect(client.request).toHaveBeenCalledTimes(2);
|
|
});
|
|
});
|