test(guild): add concurrent message write verification and fix duplicate messageId index

This commit is contained in:
nav
2026-05-12 12:51:00 +00:00
parent 71ac0f91c6
commit 86ec39f7d2
2 changed files with 34 additions and 1 deletions

View File

@@ -9,7 +9,6 @@ export class Message {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Index()
@Column({ type: 'varchar', length: 80, unique: true })
messageId!: string;

View File

@@ -2,6 +2,8 @@ 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';
@@ -13,6 +15,7 @@ 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');
@@ -23,6 +26,9 @@ describe('guild integration (mysql + api)', () => {
app = moduleRef.createNestApplication();
app.setGlobalPrefix('api');
await app.init();
dataSource = app.get(DataSource);
await dataSource.dropDatabase();
await dataSource.synchronize();
}, 30000);
afterAll(async () => {
@@ -40,4 +46,32 @@ describe('guild integration (mysql + api)', () => {
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));
});
});