Files

279 lines
9.8 KiB
TypeScript

import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals';
import { AppDataSource } from '../../../src/Infrastructure/ormconfig';
import { ChatRepository } from '../../../src/Infrastructure/Repository/ChatRepository';
import { ChatArchiveRepository } from '../../../src/Infrastructure/Repository/ChatArchiveRepository';
import { UserRepository } from '../../../src/Infrastructure/Repository/UserRepository';
import { ChatType } from '../../../src/Domain/Chat/ChatAggregate';
import { UserState } from '../../../src/Domain/User/UserAggregate';
import { v4 as uuidv4 } from 'uuid';
describe('Chat Messaging System', () => {
let chatRepository: ChatRepository;
let chatArchiveRepository: ChatArchiveRepository;
let userRepository: UserRepository;
let testUser1: any;
let testUser2: any;
let testPremiumUser: any;
beforeAll(async () => {
if (!AppDataSource.isInitialized) {
await AppDataSource.initialize();
}
chatRepository = new ChatRepository();
chatArchiveRepository = new ChatArchiveRepository();
userRepository = new UserRepository();
});
beforeEach(async () => {
// Create test users
testUser1 = await userRepository.create({
username: `testuser1_${Date.now()}`,
email: `test1_${Date.now()}@example.com`,
password: 'hashedpassword',
fname: 'Test',
lname: 'User1',
type: 'regular',
state: UserState.VERIFIED_REGULAR
});
testUser2 = await userRepository.create({
username: `testuser2_${Date.now()}`,
email: `test2_${Date.now()}@example.com`,
password: 'hashedpassword',
fname: 'Test',
lname: 'User2',
type: 'regular',
state: UserState.VERIFIED_REGULAR
});
testPremiumUser = await userRepository.create({
username: `premiumuser_${Date.now()}`,
email: `premium_${Date.now()}@example.com`,
password: 'hashedpassword',
fname: 'Premium',
lname: 'User',
type: 'premium',
state: UserState.VERIFIED_PREMIUM
});
});
afterAll(async () => {
if (AppDataSource.isInitialized) {
await AppDataSource.destroy();
}
});
describe('Direct Chat Creation', () => {
it('should create a direct chat between two users', async () => {
const chat = await chatRepository.create({
type: ChatType.DIRECT,
users: [testUser1.id, testUser2.id],
messages: [],
lastActivity: new Date()
});
expect(chat).toBeDefined();
expect(chat.type).toBe(ChatType.DIRECT);
expect(chat.users).toEqual([testUser1.id, testUser2.id]);
expect(chat.messages).toEqual([]);
});
});
describe('Group Chat Creation', () => {
it('should create a group chat', async () => {
const chat = await chatRepository.create({
type: ChatType.GROUP,
name: 'Test Group',
createdBy: testPremiumUser.id,
users: [testPremiumUser.id, testUser1.id, testUser2.id],
messages: [],
lastActivity: new Date()
});
expect(chat).toBeDefined();
expect(chat.type).toBe(ChatType.GROUP);
expect(chat.name).toBe('Test Group');
expect(chat.createdBy).toBe(testPremiumUser.id);
expect(chat.users.length).toBe(3);
});
});
describe('Game Chat Creation', () => {
it('should create a game chat', async () => {
const gameId = uuidv4();
const chat = await chatRepository.create({
type: ChatType.GAME,
name: 'Test Game Chat',
gameId: gameId,
users: [testUser1.id, testUser2.id],
messages: [],
lastActivity: new Date()
});
expect(chat).toBeDefined();
expect(chat.type).toBe(ChatType.GAME);
expect(chat.gameId).toBe(gameId);
expect(chat.name).toBe('Test Game Chat');
});
it('should find game chat by game id', async () => {
const gameId = uuidv4();
await chatRepository.create({
type: ChatType.GAME,
name: 'Test Game Chat',
gameId: gameId,
users: [testUser1.id, testUser2.id],
messages: [],
lastActivity: new Date()
});
const foundChat = await chatRepository.findByGameId(gameId);
expect(foundChat).toBeDefined();
expect(foundChat!.gameId).toBe(gameId);
});
});
describe('Message Management', () => {
it('should add and retrieve messages', async () => {
const chat = await chatRepository.create({
type: ChatType.DIRECT,
users: [testUser1.id, testUser2.id],
messages: [],
lastActivity: new Date()
});
const message = {
id: uuidv4(),
date: new Date(),
userid: testUser1.id,
text: 'Hello, this is a test message!'
};
await chatRepository.update(chat.id, {
messages: [message],
lastActivity: new Date()
});
const updatedChat = await chatRepository.findById(chat.id);
expect(updatedChat!.messages).toHaveLength(1);
expect(updatedChat!.messages[0].text).toBe('Hello, this is a test message!');
expect(updatedChat!.messages[0].userid).toBe(testUser1.id);
});
});
describe('Chat Archiving', () => {
it('should archive a chat with messages', async () => {
const message = {
id: uuidv4(),
date: new Date(),
userid: testUser1.id,
text: 'Message to be archived'
};
const chat = await chatRepository.create({
type: ChatType.DIRECT,
users: [testUser1.id, testUser2.id],
messages: [message],
lastActivity: new Date()
});
const archive = await chatRepository.archiveChat(chat);
expect(archive).toBeDefined();
expect(archive.chatId).toBe(chat.id);
expect(archive.archivedMessages).toHaveLength(1);
expect(archive.archivedMessages[0].text).toBe('Message to be archived');
// Check that chat messages were cleared
const archivedChat = await chatRepository.findById(chat.id);
expect(archivedChat!.messages).toEqual([]);
expect(archivedChat!.archiveDate).toBeDefined();
});
it('should retrieve archived chat', async () => {
const message = {
id: uuidv4(),
date: new Date(),
userid: testUser1.id,
text: 'Archived message'
};
const chat = await chatRepository.create({
type: ChatType.DIRECT,
users: [testUser1.id, testUser2.id],
messages: [message],
lastActivity: new Date()
});
await chatRepository.archiveChat(chat);
const archive = await chatRepository.getArchivedChat(chat.id);
expect(archive).toBeDefined();
expect(archive!.archivedMessages).toHaveLength(1);
expect(archive!.archivedMessages[0].text).toBe('Archived message');
});
});
describe('Chat Queries', () => {
it('should find chats by user id', async () => {
const chat1 = await chatRepository.create({
type: ChatType.DIRECT,
users: [testUser1.id, testUser2.id],
messages: [],
lastActivity: new Date()
});
const chat2 = await chatRepository.create({
type: ChatType.GROUP,
name: 'Test Group',
createdBy: testPremiumUser.id,
users: [testPremiumUser.id, testUser1.id],
messages: [],
lastActivity: new Date()
});
const userChats = await chatRepository.findByUserId(testUser1.id);
expect(userChats.length).toBeGreaterThanOrEqual(2);
const chatIds = userChats.map(c => c.id);
expect(chatIds).toContain(chat1.id);
expect(chatIds).toContain(chat2.id);
});
it('should find active chats for user', async () => {
await chatRepository.create({
type: ChatType.DIRECT,
users: [testUser1.id, testUser2.id],
messages: [],
lastActivity: new Date()
});
const activeChats = await chatRepository.findActiveChatsForUser(testUser1.id);
expect(activeChats.length).toBeGreaterThanOrEqual(1);
// All returned chats should be active
activeChats.forEach(chat => {
expect(chat.users).toContain(testUser1.id);
});
});
it('should find inactive chats', async () => {
const oldDate = new Date(Date.now() - 2 * 60 * 60 * 1000); // 2 hours ago
await chatRepository.create({
type: ChatType.DIRECT,
users: [testUser1.id, testUser2.id],
messages: [],
lastActivity: oldDate
});
const inactiveChats = await chatRepository.findInactiveChats(60); // 60 minutes
expect(inactiveChats.length).toBeGreaterThanOrEqual(1);
});
});
});