78 lines
2.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
import type { INestApplication } from '@nestjs/common';
|
|
import { Test } from '@nestjs/testing';
|
|
import request from 'supertest';
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { ShortTermMarketController } from '../src/market-overview/short-term.controller';
|
|
import {
|
|
AKTOOLS_CLIENT_PORT,
|
|
ShortTermMarketService,
|
|
} from '../src/market-overview/short-term.service';
|
|
|
|
describe('短线行情 HTTP API', () => {
|
|
let app: INestApplication | undefined;
|
|
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(new Date('2026-08-24T03:00:00.000Z'));
|
|
});
|
|
|
|
afterEach(async () => {
|
|
try {
|
|
await app?.close();
|
|
} finally {
|
|
app = undefined;
|
|
vi.useRealTimers();
|
|
}
|
|
});
|
|
|
|
it('返回结构化超短情绪指标和 AKShare 来源', async () => {
|
|
const client = {
|
|
getLimitUpPool: vi.fn().mockResolvedValue([{ 代码: '000001', 连板数: 4 }]),
|
|
getBrokenBoardPool: vi.fn().mockResolvedValue([{ 代码: '000002' }]),
|
|
getPreviousLimitUpPool: vi.fn().mockResolvedValue([{ 代码: '000003', 涨跌幅: 1.5 }]),
|
|
};
|
|
const moduleRef = await Test.createTestingModule({
|
|
controllers: [ShortTermMarketController],
|
|
providers: [ShortTermMarketService, { provide: AKTOOLS_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/short-term/emotion')
|
|
.expect(200);
|
|
|
|
expect(response.body).toMatchObject({
|
|
source: 'akshare',
|
|
status: 'fresh',
|
|
tradeDate: '20260824',
|
|
data: { limitUpCount: 1, maxBoard: 4, brokenBoardCount: 1 },
|
|
});
|
|
expect(JSON.stringify(response.body)).not.toContain('127.0.0.1');
|
|
});
|
|
|
|
it('全部 AKTools 数据不可用时返回 unavailable 而不是伪造空数据', async () => {
|
|
const client = {
|
|
getLimitUpPool: vi.fn().mockRejectedValue(new Error('private detail')),
|
|
getBrokenBoardPool: vi.fn().mockRejectedValue(new Error('private detail')),
|
|
getPreviousLimitUpPool: vi.fn().mockRejectedValue(new Error('private detail')),
|
|
};
|
|
const moduleRef = await Test.createTestingModule({
|
|
controllers: [ShortTermMarketController],
|
|
providers: [ShortTermMarketService, { provide: AKTOOLS_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/short-term/conclusion')
|
|
.expect(200);
|
|
|
|
expect(response.body).toMatchObject({ source: 'akshare', status: 'unavailable', data: null });
|
|
expect(JSON.stringify(response.body)).not.toContain('private detail');
|
|
});
|
|
});
|