import { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import request from 'supertest'; import { afterAll, beforeAll, describe, expect, it } from 'vitest'; import { createHmac, randomUUID } from 'crypto'; process.env.DB_HOST = '127.0.0.1'; process.env.DB_PORT = '3307'; process.env.DB_USER = 'fabric'; process.env.DB_PASSWORD = 'fabric'; process.env.DB_NAME = 'fabric_center'; process.env.DB_SYNC = 'true'; process.env.CENTER_SHARED_SECRET = 'test-center-secret'; process.env.JWT_ACCESS_SECRET = 'test-access-secret'; process.env.JWT_REFRESH_SECRET = 'test-refresh-secret'; describe('center integration (mysql + api)', () => { let app: INestApplication; 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(); }, 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.database).toBe('ready'); }); it('POST /api/nodes/register follows center-guild contract (version + hmac)', async () => { const body = { nodeId: `guild-node-${Date.now()}`, name: 'Guild Node Contract Test', endpoint: `http://guild-${Date.now()}:7002`, }; const timestamp = new Date().toISOString(); const nonce = randomUUID(); const canonical = ['POST', '/api/nodes/register', timestamp, nonce, JSON.stringify(body)].join('\n'); const signature = createHmac('sha256', process.env.CENTER_SHARED_SECRET as string) .update(canonical) .digest('hex'); const res = await request(app.getHttpServer()) .post('/api/nodes/register') .set('x-fabric-version', '1') .set('x-fabric-timestamp', timestamp) .set('x-fabric-nonce', nonce) .set('x-fabric-signature', signature) .send(body); expect(res.status).toBe(201); expect(res.body.status).toBe('accepted'); expect(res.body.negotiatedVersion).toBe('1'); expect(res.body.node.nodeId).toBe(body.nodeId); }); });