Files
pos-system/services/iam-service/src/__tests__/feature.e2e.ts

279 lines
7.4 KiB
TypeScript

import express from 'express';
import request from 'supertest';
import { getPrismaClient } from '../config/database.config';
import { createRouter } from '../routes';
// EN: Mock getPrismaClient to return the mocked prisma client
// VI: Mock getPrismaClient để trả về mocked prisma client
jest.mocked(getPrismaClient).mockReturnValue(prisma);
// EN: Mock external dependencies for E2E tests
// VI: Mock dependencies bên ngoài cho E2E tests
jest.mock('../config/database.config', () => ({
connectDatabase: jest.fn().mockResolvedValue(undefined),
getPrismaClient: jest.fn().mockReturnValue({
$queryRaw: jest.fn().mockResolvedValue([{ '1': 1 }]),
$disconnect: jest.fn().mockResolvedValue(undefined),
feature: {
create: jest.fn(),
findMany: jest.fn(),
findUnique: jest.fn(),
update: jest.fn(),
delete: jest.fn(),
},
}),
prisma: {
$queryRaw: jest.fn().mockResolvedValue([{ '1': 1 }]),
$disconnect: jest.fn().mockResolvedValue(undefined),
feature: {
create: jest.fn(),
findMany: jest.fn(),
findUnique: jest.fn(),
update: jest.fn(),
delete: jest.fn(),
},
},
}));
// EN: Set up mock implementations for E2E tests
// VI: Thiết lập implementations mock cho E2E tests
import { prisma } from '../config/database.config';
// EN: Use jest.mocked to properly type the mock
// VI: Sử dụng jest.mocked để type mock đúng cách
const mockPrisma = jest.mocked(prisma);
// EN: Mock successful feature creation for E2E
// VI: Mock việc tạo feature thành công cho E2E
mockPrisma.feature.create.mockResolvedValue({
id: 'e2e-test-feature-id',
name: 'test-feature',
title: 'Test Feature',
description: 'A test feature for E2E testing',
config: {},
enabled: true,
version: '1.0.0',
tags: [],
createdAt: new Date(),
updatedAt: new Date(),
});
// EN: Mock other feature operations
// VI: Mock các operations feature khác
mockPrisma.feature.findMany.mockResolvedValue([]);
mockPrisma.feature.findUnique.mockResolvedValue(null);
mockPrisma.feature.update.mockResolvedValue({
id: 'e2e-test-feature-id',
name: 'test-feature',
title: 'Updated Feature',
description: 'Updated description',
config: {},
enabled: true,
version: '1.0.0',
tags: [],
createdAt: new Date(),
updatedAt: new Date(),
});
mockPrisma.feature.delete.mockResolvedValue({
id: 'e2e-test-feature-id',
name: 'test-feature',
title: 'Test Feature',
description: 'A test feature for E2E testing',
config: {},
enabled: true,
version: '1.0.0',
tags: [],
createdAt: new Date(),
updatedAt: new Date(),
});
jest.mock('../config/redis.config', () => ({
getRedisClient: jest.fn().mockReturnValue({
call: jest.fn(),
}),
}));
jest.mock('../config/app.config', () => ({
appConfig: {
port: 3001,
nodeEnv: 'test',
corsOrigin: '*',
},
}));
jest.mock('@goodgo/logger', () => ({
logger: {
info: jest.fn(),
error: jest.fn(),
warn: jest.fn(),
debug: jest.fn(),
},
}));
jest.mock('@goodgo/auth-sdk', () => ({
verifyToken: jest.fn(),
decodeToken: jest.fn(),
createToken: jest.fn(),
extractTokenFromHeader: jest.fn(),
isTokenExpired: jest.fn(),
}));
jest.mock('@goodgo/logger', () => ({
logger: {
info: jest.fn(),
error: jest.fn(),
},
}));
jest.mock('@goodgo/tracing', () => ({
initTracing: jest.fn(),
}));
jest.mock('prom-client', () => ({
register: {
getMetricsAsJSON: jest.fn().mockReturnValue({}),
metrics: jest.fn().mockReturnValue('# Test metrics'),
},
}));
describe('Feature Endpoints E2E', () => {
let app: express.Application;
beforeAll(() => {
// EN: Set up test environment
// VI: Thiết lập môi trường test
process.env.NODE_ENV = 'test';
process.env.API_VERSION = 'v1';
app = express();
app.use(express.json());
app.use(createRouter());
});
describe('POST /api/v1/features', () => {
it('should create a feature successfully', async () => {
// EN: Arrange
// VI: Chuẩn bị
const featureData = {
name: 'test-feature',
title: 'Test Feature',
description: 'A test feature for E2E testing'
};
// EN: Act
// VI: Thực hiện
const response = await request(app)
.post('/api/v1/features')
.send(featureData)
.expect(201);
// EN: Assert
// VI: Kiểm tra
expect(response.body).toMatchObject({
success: true,
message: 'Feature created successfully / Feature đã được tạo thành công',
});
expect(response.body.timestamp).toBeDefined();
});
it('should handle minimal request body', async () => {
// EN: Arrange
// VI: Chuẩn bị
const minimalData = { name: 'minimal-feature' };
// EN: Act
// VI: Thực hiện
const response = await request(app)
.post('/api/v1/features')
.send(minimalData)
.expect(201);
// EN: Assert
// VI: Kiểm tra
expect(response.body).toMatchObject({
success: true,
data: { name: 'minimal-feature' },
message: 'Feature created successfully / Feature đã được tạo thành công',
});
});
it('should handle complex feature data', async () => {
// EN: Arrange
// VI: Chuẩn bị
const complexFeatureData = {
name: 'advanced-feature',
title: 'Advanced Feature',
description: 'Feature with metadata',
config: {
version: '1.0.0',
enabled: true,
priority: 1,
settings: {
timeout: 5000,
retries: 3
}
},
tags: ['advanced', 'test']
};
// EN: Act
// VI: Thực hiện
const response = await request(app)
.post('/api/v1/features')
.send(complexFeatureData)
.expect(201);
// EN: Assert
// VI: Kiểm tra
expect(response.body).toMatchObject({
success: true,
message: 'Feature created successfully / Feature đã được tạo thành công',
});
expect(response.body.timestamp).toBeDefined();
});
it('should handle missing content-type header', async () => {
// EN: Act - Send request without content-type
// VI: Thực hiện - Gửi request không có content-type
const response = await request(app)
.post('/api/v1/features')
.send('not json data')
.expect(201);
// EN: Assert
// VI: Kiểm tra
expect(response.body).toMatchObject({
success: true,
message: 'Feature created successfully / Feature đã được tạo thành công',
});
});
it('should handle large request payloads', async () => {
// EN: Arrange - Create large payload
// VI: Chuẩn bị - Tạo payload lớn
const largeFeatureData = {
name: 'large-feature',
title: 'Large Feature',
description: 'A'.repeat(500), // Large description
config: {
largeData: 'B'.repeat(1000), // Large config data
}
};
// EN: Act
// VI: Thực hiện
const response = await request(app)
.post('/api/v1/features')
.send(largeFeatureData)
.expect(201);
// EN: Assert
// VI: Kiểm tra
expect(response.body).toMatchObject({
success: true,
message: 'Feature created successfully / Feature đã được tạo thành công',
});
});
});
});