negyedik gyakorlat + megoldasok

This commit is contained in:
magdo
2026-03-04 20:02:39 +01:00
parent afc3777ac9
commit 388aa908de
217 changed files with 19791 additions and 0 deletions
@@ -0,0 +1,117 @@
const LoginUserCommandHandler = require('../../../src/application/auth/commands/LoginUserCommandHandler');
const LoginUserCommand = require('../../../src/application/auth/commands/LoginUserCommand');
const bcrypt = require('bcryptjs');
const JwtService = require('../../../src/application/services/JwtService');
// Mock dependencies
jest.mock('bcryptjs');
jest.mock('../../../src/application/services/JwtService');
describe('LoginUserCommandHandler', () => {
let handler;
let mockPrisma;
let mockJwtService;
beforeEach(() => {
// Mock JwtService instance
mockJwtService = {
generateToken: jest.fn()
};
JwtService.mockImplementation(() => mockJwtService);
// Mock Prisma
mockPrisma = {
user: {
findUnique: jest.fn()
}
};
handler = new LoginUserCommandHandler(mockPrisma);
// Reset all mocks
jest.clearAllMocks();
});
describe('handle - success cases', () => {
it('should login user successfully with valid credentials', async () => {
// Arrange
const command = new LoginUserCommand('john@example.com', 'password123');
mockPrisma.user.findUnique.mockResolvedValue({
id: 1,
name: 'John Doe',
email: 'john@example.com',
password: 'hashed_password',
createdAt: new Date(),
updatedAt: new Date()
});
bcrypt.compare.mockResolvedValue(true); // Password is valid
mockJwtService.generateToken.mockReturnValue('mock_jwt_token');
// Act
const result = await handler.handle(command);
// Assert
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
where: { email: 'john@example.com' }
});
expect(bcrypt.compare).toHaveBeenCalledWith('password123', 'hashed_password');
expect(mockJwtService.generateToken).toHaveBeenCalledWith({
userId: 1,
email: 'john@example.com'
});
expect(result.user).toEqual({
id: 1,
name: 'John Doe',
email: 'john@example.com',
createdAt: expect.any(Date),
updatedAt: expect.any(Date)
});
expect(result.token).toBe('mock_jwt_token');
expect(result.user.password).toBeUndefined(); // Password should not be returned
});
});
describe('handle - validation errors', () => {
it('should throw error if email is missing', async () => {
// Arrange
const command = new LoginUserCommand('', 'password123');
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Email and password are required');
});
it('should throw error if password is missing', async () => {
// Arrange
const command = new LoginUserCommand('john@example.com', '');
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Email and password are required');
});
it('should throw error if user does not exist', async () => {
// Arrange
const command = new LoginUserCommand('nonexistent@example.com', 'password123');
mockPrisma.user.findUnique.mockResolvedValue(null);
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Invalid email or password');
});
it('should throw error if password is incorrect', async () => {
// Arrange
const command = new LoginUserCommand('john@example.com', 'wrongpassword');
mockPrisma.user.findUnique.mockResolvedValue({
id: 1,
email: 'john@example.com',
password: 'hashed_password'
});
bcrypt.compare.mockResolvedValue(false); // Password is invalid
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Invalid email or password');
});
});
});
@@ -0,0 +1,194 @@
const RegisterUserCommandHandler = require('../../../src/application/auth/commands/RegisterUserCommandHandler');
const RegisterUserCommand = require('../../../src/application/auth/commands/RegisterUserCommand');
const bcrypt = require('bcryptjs');
const JwtService = require('../../../src/application/services/JwtService');
// Mock dependencies
jest.mock('bcryptjs');
jest.mock('../../../src/application/services/JwtService');
describe('RegisterUserCommandHandler', () => {
let handler;
let mockPrisma;
let mockEmailService;
let mockJwtService;
beforeEach(() => {
// Mock JwtService instance
mockJwtService = {
generateToken: jest.fn()
};
JwtService.mockImplementation(() => mockJwtService);
// Mock Prisma
mockPrisma = {
user: {
findUnique: jest.fn(),
create: jest.fn()
}
};
// Mock EmailService
mockEmailService = {
sendWelcomeEmail: jest.fn().mockResolvedValue(true)
};
handler = new RegisterUserCommandHandler(mockPrisma, mockEmailService);
// Reset all mocks
jest.clearAllMocks();
});
describe('handle - success cases', () => {
it('should register a new user successfully', async () => {
// Arrange
const command = new RegisterUserCommand('John Doe', 'john@example.com', 'password123');
mockPrisma.user.findUnique.mockResolvedValue(null); // No existing user
bcrypt.hash.mockResolvedValue('hashed_password');
mockPrisma.user.create.mockResolvedValue({
id: 1,
name: 'John Doe',
email: 'john@example.com',
password: 'hashed_password',
createdAt: new Date(),
updatedAt: new Date()
});
mockJwtService.generateToken.mockReturnValue('mock_jwt_token');
// Act
const result = await handler.handle(command);
// Assert
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
where: { email: 'john@example.com' }
});
expect(bcrypt.hash).toHaveBeenCalledWith('password123', 10);
expect(mockPrisma.user.create).toHaveBeenCalledWith({
data: {
name: 'John Doe',
email: 'john@example.com',
password: 'hashed_password'
}
});
expect(mockJwtService.generateToken).toHaveBeenCalledWith({
userId: 1,
email: 'john@example.com'
});
expect(result.user).toEqual({
id: 1,
name: 'John Doe',
email: 'john@example.com',
createdAt: expect.any(Date),
updatedAt: expect.any(Date)
});
expect(result.token).toBe('mock_jwt_token');
expect(result.user.password).toBeUndefined(); // Password should not be returned
});
it('should send welcome email after registration', async () => {
// Arrange
const command = new RegisterUserCommand('Jane Doe', 'jane@example.com', 'password123');
mockPrisma.user.findUnique.mockResolvedValue(null);
bcrypt.hash.mockResolvedValue('hashed_password');
mockPrisma.user.create.mockResolvedValue({
id: 2,
name: 'Jane Doe',
email: 'jane@example.com',
password: 'hashed_password',
createdAt: new Date(),
updatedAt: new Date()
});
mockJwtService.generateToken.mockReturnValue('mock_jwt_token');
// Act
await handler.handle(command);
// Assert
expect(mockEmailService.sendWelcomeEmail).toHaveBeenCalledWith('jane@example.com', 'Jane Doe');
});
});
describe('handle - validation errors', () => {
it('should throw error if name is missing', async () => {
// Arrange
const command = new RegisterUserCommand('', 'john@example.com', 'password123');
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Name, email and password are required');
});
it('should throw error if email is missing', async () => {
// Arrange
const command = new RegisterUserCommand('John Doe', '', 'password123');
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Name, email and password are required');
});
it('should throw error if password is missing', async () => {
// Arrange
const command = new RegisterUserCommand('John Doe', 'john@example.com', '');
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Name, email and password are required');
});
it('should throw error if password is too short', async () => {
// Arrange
const command = new RegisterUserCommand('John Doe', 'john@example.com', '12345');
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Password must be at least 6 characters long');
});
it('should throw error if email format is invalid', async () => {
// Arrange
const command = new RegisterUserCommand('John Doe', 'invalid-email', 'password123');
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Invalid email format');
});
it('should throw error if user already exists', async () => {
// Arrange
const command = new RegisterUserCommand('John Doe', 'john@example.com', 'password123');
mockPrisma.user.findUnique.mockResolvedValue({
id: 1,
email: 'john@example.com'
});
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('User with this email already exists');
});
});
describe('handle - error handling', () => {
it('should not fail if email service throws error', async () => {
// Arrange
const command = new RegisterUserCommand('John Doe', 'john@example.com', 'password123');
mockPrisma.user.findUnique.mockResolvedValue(null);
bcrypt.hash.mockResolvedValue('hashed_password');
mockPrisma.user.create.mockResolvedValue({
id: 1,
name: 'John Doe',
email: 'john@example.com',
password: 'hashed_password',
createdAt: new Date(),
updatedAt: new Date()
});
mockJwtService.generateToken.mockReturnValue('mock_jwt_token');
mockEmailService.sendWelcomeEmail.mockRejectedValue(new Error('Email service error'));
// Act
const result = await handler.handle(command);
// Assert - should still return user and token even if email fails
expect(result.user.email).toBe('john@example.com');
expect(result.token).toBe('mock_jwt_token');
});
});
});
@@ -0,0 +1,80 @@
const UpdateUserProfileCommandHandler = require('../../../src/application/user/commands/UpdateUserProfileCommandHandler');
const UpdateUserProfileCommand = require('../../../src/application/user/commands/UpdateUserProfileCommand');
describe('UpdateUserProfileCommandHandler', () => {
let handler;
let mockPrisma;
beforeEach(() => {
// Mock Prisma
mockPrisma = {
user: {
update: jest.fn()
}
};
handler = new UpdateUserProfileCommandHandler(mockPrisma);
// Reset all mocks
jest.clearAllMocks();
});
describe('handle - success cases', () => {
it('should update user profile successfully', async () => {
// Arrange
const command = new UpdateUserProfileCommand(1, 'Jane Updated');
mockPrisma.user.update.mockResolvedValue({
id: 1,
name: 'Jane Updated',
email: 'jane@example.com',
password: 'hashed_password',
createdAt: new Date(),
updatedAt: new Date()
});
// Act
const result = await handler.handle(command);
// Assert
expect(mockPrisma.user.update).toHaveBeenCalledWith({
where: { id: 1 },
data: { name: 'Jane Updated' }
});
expect(result).toEqual({
id: 1,
name: 'Jane Updated',
email: 'jane@example.com',
createdAt: expect.any(Date),
updatedAt: expect.any(Date)
});
expect(result.password).toBeUndefined(); // Password should not be returned
});
});
describe('handle - validation errors', () => {
it('should throw error if name is missing', async () => {
// Arrange
const command = new UpdateUserProfileCommand(1, '');
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Name is required');
});
it('should throw error if name is null', async () => {
// Arrange
const command = new UpdateUserProfileCommand(1, null);
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Name is required');
});
it('should throw error if name is undefined', async () => {
// Arrange
const command = new UpdateUserProfileCommand(1, undefined);
// Act & Assert
await expect(handler.handle(command)).rejects.toThrow('Name is required');
});
});
});