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.
This commit is contained in:
142
test/auth.e2e-spec.ts
Normal file
142
test/auth.e2e-spec.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user