test(guild): add concurrent message write verification and fix duplicate messageId index
This commit is contained in:
@@ -9,7 +9,6 @@ export class Message {
|
|||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id!: string;
|
id!: string;
|
||||||
|
|
||||||
@Index()
|
|
||||||
@Column({ type: 'varchar', length: 80, unique: true })
|
@Column({ type: 'varchar', length: 80, unique: true })
|
||||||
messageId!: string;
|
messageId!: string;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { INestApplication } from '@nestjs/common';
|
|||||||
import { Test } from '@nestjs/testing';
|
import { Test } from '@nestjs/testing';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
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_HOST = '127.0.0.1';
|
||||||
process.env.DB_PORT = '3308';
|
process.env.DB_PORT = '3308';
|
||||||
@@ -13,6 +15,7 @@ process.env.FABRIC_API_KEY = 'test-api-key';
|
|||||||
|
|
||||||
describe('guild integration (mysql + api)', () => {
|
describe('guild integration (mysql + api)', () => {
|
||||||
let app: INestApplication;
|
let app: INestApplication;
|
||||||
|
let dataSource: DataSource;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const { AppModule } = await import('./app.module');
|
const { AppModule } = await import('./app.module');
|
||||||
@@ -23,6 +26,9 @@ describe('guild integration (mysql + api)', () => {
|
|||||||
app = moduleRef.createNestApplication();
|
app = moduleRef.createNestApplication();
|
||||||
app.setGlobalPrefix('api');
|
app.setGlobalPrefix('api');
|
||||||
await app.init();
|
await app.init();
|
||||||
|
dataSource = app.get(DataSource);
|
||||||
|
await dataSource.dropDatabase();
|
||||||
|
await dataSource.synchronize();
|
||||||
}, 30000);
|
}, 30000);
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
@@ -40,4 +46,32 @@ describe('guild integration (mysql + api)', () => {
|
|||||||
const res = await request(app.getHttpServer()).get('/api/channels/non-exist/messages');
|
const res = await request(app.getHttpServer()).get('/api/channels/non-exist/messages');
|
||||||
expect(res.status).toBe(401);
|
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));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user