Initial commit: Telegram Management System
Some checks failed
Deploy / deploy (push) Has been cancelled
Some checks failed
Deploy / deploy (push) Has been cancelled
Full-stack web application for Telegram management - Frontend: Vue 3 + Vben Admin - Backend: NestJS - Features: User management, group broadcast, statistics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
254
marketing-agent/tests/integration/api/auth.test.js
Normal file
254
marketing-agent/tests/integration/api/auth.test.js
Normal file
@@ -0,0 +1,254 @@
|
||||
import request from 'supertest';
|
||||
import app from '../../../services/api-gateway/src/app.js';
|
||||
import { connectDatabase, closeDatabase, clearDatabase } from '../../helpers/database.js';
|
||||
import { createUser } from '../../helpers/factories.js';
|
||||
import bcrypt from 'bcryptjs';
|
||||
|
||||
describe('Auth API Integration Tests', () => {
|
||||
beforeAll(async () => {
|
||||
await connectDatabase();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await clearDatabase();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await closeDatabase();
|
||||
});
|
||||
|
||||
describe('POST /api/v1/auth/login', () => {
|
||||
it('should login with valid credentials', async () => {
|
||||
// Create a user in the database
|
||||
const password = 'Test123!@#';
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
const userData = createUser({ password: hashedPassword });
|
||||
|
||||
// Save user to database (you'll need to import and use your User model)
|
||||
// const user = await User.create(userData);
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/auth/login')
|
||||
.send({
|
||||
username: userData.username,
|
||||
password: password
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body.success).toBe(true);
|
||||
expect(response.body.data).toHaveProperty('accessToken');
|
||||
expect(response.body.data).toHaveProperty('refreshToken');
|
||||
expect(response.body.data.user).toHaveProperty('id');
|
||||
expect(response.body.data.user.username).toBe(userData.username);
|
||||
});
|
||||
|
||||
it('should fail with invalid credentials', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/auth/login')
|
||||
.send({
|
||||
username: 'nonexistent',
|
||||
password: 'wrongpassword'
|
||||
});
|
||||
|
||||
expect(response.status).toBe(401);
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.error).toBe('Invalid credentials');
|
||||
});
|
||||
|
||||
it('should fail with missing credentials', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/auth/login')
|
||||
.send({
|
||||
username: 'testuser'
|
||||
// missing password
|
||||
});
|
||||
|
||||
expect(response.status).toBe(400);
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.error).toContain('required');
|
||||
});
|
||||
|
||||
it('should handle rate limiting', async () => {
|
||||
// Make multiple requests to trigger rate limit
|
||||
const requests = Array(11).fill(null).map(() =>
|
||||
request(app)
|
||||
.post('/api/v1/auth/login')
|
||||
.send({
|
||||
username: 'testuser',
|
||||
password: 'password'
|
||||
})
|
||||
);
|
||||
|
||||
const responses = await Promise.all(requests);
|
||||
const rateLimited = responses.some(res => res.status === 429);
|
||||
|
||||
expect(rateLimited).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/v1/auth/register', () => {
|
||||
it('should register new user', async () => {
|
||||
const userData = {
|
||||
username: 'newuser',
|
||||
email: 'newuser@example.com',
|
||||
password: 'SecurePass123!',
|
||||
fullName: 'New User'
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/auth/register')
|
||||
.send(userData);
|
||||
|
||||
expect(response.status).toBe(201);
|
||||
expect(response.body.success).toBe(true);
|
||||
expect(response.body.message).toBe('Registration successful');
|
||||
});
|
||||
|
||||
it('should fail with duplicate username', async () => {
|
||||
const userData = {
|
||||
username: 'existinguser',
|
||||
email: 'test@example.com',
|
||||
password: 'SecurePass123!'
|
||||
};
|
||||
|
||||
// First registration
|
||||
await request(app)
|
||||
.post('/api/v1/auth/register')
|
||||
.send(userData);
|
||||
|
||||
// Duplicate registration
|
||||
const response = await request(app)
|
||||
.post('/api/v1/auth/register')
|
||||
.send(userData);
|
||||
|
||||
expect(response.status).toBe(409);
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.error).toContain('already exists');
|
||||
});
|
||||
|
||||
it('should validate email format', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/auth/register')
|
||||
.send({
|
||||
username: 'testuser',
|
||||
email: 'invalid-email',
|
||||
password: 'SecurePass123!'
|
||||
});
|
||||
|
||||
expect(response.status).toBe(400);
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.error).toContain('email');
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/v1/auth/refresh', () => {
|
||||
let accessToken, refreshToken;
|
||||
|
||||
beforeEach(async () => {
|
||||
// Login to get tokens
|
||||
const loginResponse = await request(app)
|
||||
.post('/api/v1/auth/login')
|
||||
.send({
|
||||
username: 'admin',
|
||||
password: 'password123'
|
||||
});
|
||||
|
||||
accessToken = loginResponse.body.data.accessToken;
|
||||
refreshToken = loginResponse.body.data.refreshToken;
|
||||
});
|
||||
|
||||
it('should refresh access token', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/auth/refresh')
|
||||
.send({
|
||||
refreshToken: refreshToken
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body.success).toBe(true);
|
||||
expect(response.body.data).toHaveProperty('accessToken');
|
||||
expect(response.body.data.accessToken).not.toBe(accessToken);
|
||||
});
|
||||
|
||||
it('should fail with invalid refresh token', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/auth/refresh')
|
||||
.send({
|
||||
refreshToken: 'invalid-refresh-token'
|
||||
});
|
||||
|
||||
expect(response.status).toBe(401);
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.error).toBe('Invalid refresh token');
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/v1/auth/me', () => {
|
||||
let accessToken;
|
||||
|
||||
beforeEach(async () => {
|
||||
// Login to get token
|
||||
const loginResponse = await request(app)
|
||||
.post('/api/v1/auth/login')
|
||||
.send({
|
||||
username: 'admin',
|
||||
password: 'password123'
|
||||
});
|
||||
|
||||
accessToken = loginResponse.body.data.accessToken;
|
||||
});
|
||||
|
||||
it('should get current user info', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/v1/auth/me')
|
||||
.set('Authorization', `Bearer ${accessToken}`);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body.success).toBe(true);
|
||||
expect(response.body.data).toHaveProperty('id');
|
||||
expect(response.body.data).toHaveProperty('role');
|
||||
});
|
||||
|
||||
it('should fail without token', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/v1/auth/me');
|
||||
|
||||
expect(response.status).toBe(401);
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.error).toBe('No token provided');
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/v1/auth/logout', () => {
|
||||
let accessToken;
|
||||
|
||||
beforeEach(async () => {
|
||||
// Login to get token
|
||||
const loginResponse = await request(app)
|
||||
.post('/api/v1/auth/login')
|
||||
.send({
|
||||
username: 'admin',
|
||||
password: 'password123'
|
||||
});
|
||||
|
||||
accessToken = loginResponse.body.data.accessToken;
|
||||
});
|
||||
|
||||
it('should logout successfully', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/auth/logout')
|
||||
.set('Authorization', `Bearer ${accessToken}`);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body.success).toBe(true);
|
||||
expect(response.body.message).toBe('Logged out successfully');
|
||||
|
||||
// Verify token is blacklisted
|
||||
const meResponse = await request(app)
|
||||
.get('/api/v1/auth/me')
|
||||
.set('Authorization', `Bearer ${accessToken}`);
|
||||
|
||||
expect(meResponse.status).toBe(401);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user