Files
bidding_watcher/test/auth.e2e-spec.ts
dmy 810a420a46 feat(date): enhance date formatting and timezone handling
- Update formatDateTime function to handle timezone-aware date strings directly.
- Introduce utcToBeijingISOString function for consistent Beijing time formatting in ISO string.
- Modify BidsService to utilize the new utcToBeijingISOString for date conversions.
- Add unit tests for AuthGuard to validate API key authentication and access control.
- Create end-to-end tests for API key handling in various scenarios.
- Update .gitignore to exclude 'qingyun' directory.
- Add environment configuration for production settings in .env.production.
- Include Tailwind CSS setup in the uni-app version for styling.
2026-01-16 23:31:58 +08:00

143 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import request from 'supertest';
import { App } from 'supertest/types';
import { AppModule } from '../src/app.module';
describe('AuthGuard (e2e)', () => {
let app: INestApplication<App>;
const validApiKey = 'test-e2e-api-key-12345';
beforeEach(async () => {
// 设置测试环境变量
process.env.API_KEY = validApiKey;
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
afterEach(async () => {
await app.close();
// 清理环境变量
delete process.env.API_KEY;
});
describe('本地IP访问', () => {
it('应该允许本地IP访问无需API Key', () => {
return request(app.getHttpServer())
.get('/api/keywords')
.set('X-Forwarded-For', '127.0.0.1')
.expect(200);
});
it('应该允许 IPv6 本地地址访问', () => {
return request(app.getHttpServer())
.get('/api/keywords')
.set('X-Forwarded-For', '::1')
.expect(200);
});
});
describe('公网IP访问 - 已配置API_KEY', () => {
it('应该允许提供正确API Key的公网访问', () => {
return request(app.getHttpServer())
.get('/api/keywords')
.set('X-Forwarded-For', '8.8.8.8')
.set('X-API-Key', validApiKey)
.expect(200);
});
it('应该拒绝未提供API Key的公网访问', () => {
return request(app.getHttpServer())
.get('/api/keywords')
.set('X-Forwarded-For', '8.8.8.8')
.expect(401)
.expect((res) => {
expect(res.body.message).toBe('Invalid or missing API Key');
});
});
it('应该拒绝提供错误API Key的公网访问', () => {
return request(app.getHttpServer())
.get('/api/keywords')
.set('X-Forwarded-For', '8.8.8.8')
.set('X-API-Key', 'wrong-api-key')
.expect(401)
.expect((res) => {
expect(res.body.message).toBe('Invalid or missing API Key');
});
});
it('应该拒绝提供空字符串API Key的公网访问', () => {
return request(app.getHttpServer())
.get('/api/keywords')
.set('X-Forwarded-For', '8.8.8.8')
.set('X-API-Key', '')
.expect(401);
});
});
describe('公网IP访问 - 未配置API_KEY', () => {
beforeEach(async () => {
await app.close();
// 清除 API_KEY
delete process.env.API_KEY;
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('应该允许所有公网访问(开发环境)', () => {
return request(app.getHttpServer())
.get('/api/keywords')
.set('X-Forwarded-For', '8.8.8.8')
.expect(200);
});
});
describe('内网IP访问', () => {
it('应该要求内网IP提供API Key', () => {
return request(app.getHttpServer())
.get('/api/keywords')
.set('X-Forwarded-For', '192.168.1.100')
.expect(401);
});
it('应该允许提供正确API Key的内网访问', () => {
return request(app.getHttpServer())
.get('/api/keywords')
.set('X-Forwarded-For', '192.168.1.100')
.set('X-API-Key', validApiKey)
.expect(200);
});
});
describe('多个API端点', () => {
it('应该对所有API端点应用鉴权', () => {
return request(app.getHttpServer())
.get('/api/bids')
.set('X-Forwarded-For', '8.8.8.8')
.expect(401);
});
it('应该允许带正确API Key访问所有端点', () => {
return request(app.getHttpServer())
.get('/api/bids')
.set('X-Forwarded-For', '8.8.8.8')
.set('X-API-Key', validApiKey)
.expect((res) => {
// 可能返回 200 或 404但不应该是 401
expect(res.status).not.toBe(401);
});
});
});
});