78 lines
2.5 KiB
TypeScript
78 lines
2.5 KiB
TypeScript
import { INestApplication } from '@nestjs/common';
|
|
import { Test } from '@nestjs/testing';
|
|
import request from 'supertest';
|
|
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
import { DataSource } from 'typeorm';
|
|
import { Channel } from './entities/channel.entity';
|
|
|
|
process.env.DB_HOST = '127.0.0.1';
|
|
process.env.DB_PORT = '3308';
|
|
process.env.DB_USER = 'fabric';
|
|
process.env.DB_PASSWORD = 'fabric';
|
|
process.env.DB_NAME = 'fabric_guild';
|
|
process.env.DB_SYNC = 'false';
|
|
process.env.FABRIC_API_KEY = 'test-api-key';
|
|
|
|
describe('guild integration (mysql + api)', () => {
|
|
let app: INestApplication;
|
|
let dataSource: DataSource;
|
|
|
|
beforeAll(async () => {
|
|
const { AppModule } = await import('./app.module');
|
|
const moduleRef = await Test.createTestingModule({
|
|
imports: [AppModule],
|
|
}).compile();
|
|
|
|
app = moduleRef.createNestApplication();
|
|
app.setGlobalPrefix('api');
|
|
await app.init();
|
|
dataSource = app.get(DataSource);
|
|
await dataSource.dropDatabase();
|
|
await dataSource.synchronize();
|
|
}, 30000);
|
|
|
|
afterAll(async () => {
|
|
if (app) await app.close();
|
|
});
|
|
|
|
it('GET /api/healthz returns db ready', async () => {
|
|
const res = await request(app.getHttpServer()).get('/api/healthz');
|
|
expect(res.status).toBe(200);
|
|
expect(res.body.ok).toBe(true);
|
|
expect(res.body.service).toBe('guild');
|
|
});
|
|
|
|
it('protects non-health endpoints by x-api-key', async () => {
|
|
const res = await request(app.getHttpServer()).get('/api/channels/non-exist/messages');
|
|
expect(res.status).toBe(401);
|
|
});
|
|
|
|
it('supports concurrent message writes with continuous seq', async () => {
|
|
const channelRepo = dataSource.getRepository(Channel);
|
|
const channel = await channelRepo.save(
|
|
channelRepo.create({
|
|
guildId: 'test-guild',
|
|
name: `concurrency-${Date.now()}`,
|
|
kind: 'text',
|
|
isPrivate: false,
|
|
lastSeq: 0,
|
|
}),
|
|
);
|
|
|
|
const concurrent = 10;
|
|
const tasks = Array.from({ length: concurrent }, (_, i) =>
|
|
request(app.getHttpServer())
|
|
.post(`/api/channels/${channel.id}/messages`)
|
|
.set('x-api-key', 'test-api-key')
|
|
.send({ content: `hello-${i + 1}`, authorUserId: 'u1' }),
|
|
);
|
|
|
|
const responses = await Promise.all(tasks);
|
|
const seqs = responses.map((r) => r.body.seq).sort((a, b) => a - b);
|
|
|
|
expect(responses.every((r) => r.status === 201)).toBe(true);
|
|
expect(new Set(seqs).size).toBe(concurrent);
|
|
expect(seqs).toEqual(Array.from({ length: concurrent }, (_, i) => i + 1));
|
|
});
|
|
});
|