Fix test issues

This commit is contained in:
Chris Veleris 2025-06-17 11:24:31 +03:00
parent fd1da2de43
commit f088fc9839
9 changed files with 144 additions and 35 deletions

View file

@ -9,7 +9,7 @@ const session = require('express-session');
const SequelizeStore = require('connect-session-sequelize')(session.Store);
const { sequelize } = require('./models');
const { initializeTelegramPolling } = require('./services/telegramInitializer');
const TaskScheduler = require('./services/taskScheduler');
const taskScheduler = require('./services/taskScheduler');
const app = express();
@ -143,8 +143,7 @@ async function startServer() {
await initializeTelegramPolling();
// Initialize task scheduler
const scheduler = TaskScheduler.getInstance();
await scheduler.initialize();
await taskScheduler.initialize();
const server = app.listen(PORT, '0.0.0.0', () => {
console.log(`Server running on port ${PORT}`);

View file

@ -41,7 +41,7 @@ router.post('/login', async (req, res) => {
return res.status(401).json({ errors: ['Invalid credentials'] });
}
const isValidPassword = await user.checkPassword(password);
const isValidPassword = await User.checkPassword(password, user.password_digest);
if (!isValidPassword) {
return res.status(401).json({ errors: ['Invalid credentials'] });
}

View file

@ -1,6 +1,6 @@
const express = require('express');
const { User } = require('../models');
const TelegramPoller = require('../services/telegramPoller');
const telegramPoller = require('../services/telegramPoller');
const router = express.Router();
// POST /api/telegram/start-polling
@ -15,14 +15,13 @@ router.post('/telegram/start-polling', async (req, res) => {
return res.status(400).json({ error: 'Telegram bot token not set.' });
}
const poller = TelegramPoller.getInstance();
const success = await poller.addUser(user);
const success = await telegramPoller.addUser(user);
if (success) {
res.json({
success: true,
message: 'Telegram polling started',
status: poller.getStatus()
status: telegramPoller.getStatus()
});
} else {
res.status(500).json({ error: 'Failed to start Telegram polling.' });
@ -40,13 +39,12 @@ router.post('/telegram/stop-polling', async (req, res) => {
return res.status(401).json({ error: 'Authentication required' });
}
const poller = TelegramPoller.getInstance();
const success = poller.removeUser(req.session.userId);
const success = telegramPoller.removeUser(req.session.userId);
res.json({
success: true,
message: 'Telegram polling stopped',
status: poller.getStatus()
status: telegramPoller.getStatus()
});
} catch (error) {
console.error('Error stopping Telegram polling:', error);
@ -61,11 +59,9 @@ router.get('/telegram/polling-status', async (req, res) => {
return res.status(401).json({ error: 'Authentication required' });
}
const poller = TelegramPoller.getInstance();
res.json({
success: true,
status: poller.getStatus()
status: telegramPoller.getStatus()
});
} catch (error) {
console.error('Error getting Telegram polling status:', error);

View file

@ -1,6 +1,6 @@
const express = require('express');
const { User } = require('../models');
const TaskSummaryService = require('../services/taskSummaryService');
const taskSummaryService = require('../services/taskSummaryService');
const router = express.Router();
const VALID_FREQUENCIES = ['daily', 'weekdays', 'weekly', '1h', '2h', '4h', '8h', '12h'];
@ -159,7 +159,7 @@ router.post('/profile/task-summary/send-now', async (req, res) => {
}
// Send the task summary
const success = await TaskSummaryService.sendSummaryToUser(user.id);
const success = await taskSummaryService.sendSummaryToUser(user.id);
if (success) {
res.json({

View file

@ -34,7 +34,7 @@ const parseYamlContent = (content) => {
// validate quotes data structure
const validateQuotesData = (data) =>
data && data.quotes && Array.isArray(data.quotes);
!!(data && data.quotes && Array.isArray(data.quotes));
// extract quotes from data
const extractQuotes = (data) => {

View file

@ -1,4 +1,4 @@
const TelegramPoller = require('./telegramPoller');
const telegramPoller = require('./telegramPoller');
const { User } = require('../models');
async function initializeTelegramPolling() {
@ -9,8 +9,7 @@ async function initializeTelegramPolling() {
console.log('Initializing Telegram polling for configured users...');
try {
// Get singleton instance of the poller
const poller = TelegramPoller.getInstance();
// Use functional telegram poller
// Find users with configured Telegram tokens
const usersWithTelegram = await User.findAll({
@ -27,7 +26,7 @@ async function initializeTelegramPolling() {
// Add each user to the polling list
for (const user of usersWithTelegram) {
console.log(`Starting Telegram polling for user ${user.id}`);
await poller.addUser(user);
await telegramPoller.addUser(user);
}
console.log('Telegram polling initialized successfully');

View file

@ -95,30 +95,30 @@ describe('Task Model', () => {
it('should return correct priority name', async () => {
task.priority = Task.PRIORITY.LOW;
expect(task.getPriorityName()).toBe('low');
expect(Task.getPriorityName(task.priority)).toBe('low');
task.priority = Task.PRIORITY.MEDIUM;
expect(task.getPriorityName()).toBe('medium');
expect(Task.getPriorityName(task.priority)).toBe('medium');
task.priority = Task.PRIORITY.HIGH;
expect(task.getPriorityName()).toBe('high');
expect(Task.getPriorityName(task.priority)).toBe('high');
});
it('should return correct status name', async () => {
task.status = Task.STATUS.NOT_STARTED;
expect(task.getStatusName()).toBe('not_started');
expect(Task.getStatusName(task.status)).toBe('not_started');
task.status = Task.STATUS.IN_PROGRESS;
expect(task.getStatusName()).toBe('in_progress');
expect(Task.getStatusName(task.status)).toBe('in_progress');
task.status = Task.STATUS.DONE;
expect(task.getStatusName()).toBe('done');
expect(Task.getStatusName(task.status)).toBe('done');
task.status = Task.STATUS.ARCHIVED;
expect(task.getStatusName()).toBe('archived');
expect(Task.getStatusName(task.status)).toBe('archived');
task.status = Task.STATUS.WAITING;
expect(task.getStatusName()).toBe('waiting');
expect(Task.getStatusName(task.status)).toBe('waiting');
});
});

View file

@ -85,23 +85,25 @@ describe('User Model', () => {
});
it('should check password correctly', async () => {
const isValid = await user.checkPassword('password123');
const isValid = await User.checkPassword('password123', user.password_digest);
expect(isValid).toBe(true);
const isInvalid = await user.checkPassword('wrongpassword');
const isInvalid = await User.checkPassword('wrongpassword', user.password_digest);
expect(isInvalid).toBe(false);
});
it('should set new password using setPassword method', async () => {
const oldPasswordDigest = user.password_digest;
await user.setPassword('newpassword');
const newPasswordDigest = await User.hashPassword('newpassword');
user.password_digest = newPasswordDigest;
await user.save();
expect(user.password_digest).not.toBe(oldPasswordDigest);
const isValidNew = await user.checkPassword('newpassword');
const isValidNew = await User.checkPassword('newpassword', user.password_digest);
expect(isValidNew).toBe(true);
const isValidOld = await user.checkPassword('password123');
const isValidOld = await User.checkPassword('password123', user.password_digest);
expect(isValidOld).toBe(false);
});
@ -112,7 +114,7 @@ describe('User Model', () => {
expect(user.password_digest).not.toBe(oldPasswordDigest);
const isValidNew = await user.checkPassword('newpassword');
const isValidNew = await User.checkPassword('newpassword', user.password_digest);
expect(isValidNew).toBe(true);
});
});

View file

@ -0,0 +1,113 @@
const taskScheduler = require('../../../services/taskScheduler');
const telegramPoller = require('../../../services/telegramPoller');
const quotesService = require('../../../services/quotesService');
const taskSummaryService = require('../../../services/taskSummaryService');
describe('Functional Services', () => {
describe('TaskScheduler', () => {
it('should export functional interface', () => {
expect(typeof taskScheduler.initialize).toBe('function');
expect(typeof taskScheduler.stop).toBe('function');
expect(typeof taskScheduler.restart).toBe('function');
expect(typeof taskScheduler.getStatus).toBe('function');
});
it('should have pure helper functions for testing', () => {
expect(typeof taskScheduler._createSchedulerState).toBe('function');
expect(typeof taskScheduler._shouldDisableScheduler).toBe('function');
expect(typeof taskScheduler._getCronExpression).toBe('function');
});
it('should return proper cron expressions', () => {
expect(taskScheduler._getCronExpression('daily')).toBe('0 7 * * *');
expect(taskScheduler._getCronExpression('weekly')).toBe('0 7 * * 1');
expect(taskScheduler._getCronExpression('1h')).toBe('0 * * * *');
});
});
describe('TelegramPoller', () => {
it('should export functional interface', () => {
expect(typeof telegramPoller.addUser).toBe('function');
expect(typeof telegramPoller.removeUser).toBe('function');
expect(typeof telegramPoller.getStatus).toBe('function');
expect(typeof telegramPoller.sendTelegramMessage).toBe('function');
});
it('should have pure helper functions for testing', () => {
expect(typeof telegramPoller._userExistsInList).toBe('function');
expect(typeof telegramPoller._addUserToList).toBe('function');
expect(typeof telegramPoller._removeUserFromList).toBe('function');
expect(typeof telegramPoller._createMessageParams).toBe('function');
});
it('should handle user list operations functionally', () => {
const users = [{ id: 1 }, { id: 2 }];
const newUser = { id: 3 };
expect(telegramPoller._userExistsInList(users, 1)).toBe(true);
expect(telegramPoller._userExistsInList(users, 3)).toBe(false);
const updatedUsers = telegramPoller._addUserToList(users, newUser);
expect(updatedUsers).toHaveLength(3);
expect(users).toHaveLength(2); // Original array unchanged
const filteredUsers = telegramPoller._removeUserFromList(updatedUsers, 2);
expect(filteredUsers).toHaveLength(2);
expect(filteredUsers.find(u => u.id === 2)).toBeUndefined();
});
});
describe('QuotesService', () => {
it('should export functional interface', () => {
expect(typeof quotesService.getRandomQuote).toBe('function');
expect(typeof quotesService.getAllQuotes).toBe('function');
expect(typeof quotesService.getQuotesCount).toBe('function');
expect(typeof quotesService.reloadQuotes).toBe('function');
});
it('should have pure helper functions for testing', () => {
expect(typeof quotesService._createDefaultQuotes).toBe('function');
expect(typeof quotesService._getRandomIndex).toBe('function');
expect(typeof quotesService._validateQuotesData).toBe('function');
});
it('should validate quotes data structure correctly', () => {
const validData = { quotes: ['quote1', 'quote2'] };
const invalidData1 = { quotes: 'not-array' };
const invalidData2 = { notQuotes: ['quote1'] };
const invalidData3 = null;
expect(quotesService._validateQuotesData(validData)).toBe(true);
expect(quotesService._validateQuotesData(invalidData1)).toBe(false);
expect(quotesService._validateQuotesData(invalidData2)).toBe(false);
expect(quotesService._validateQuotesData(invalidData3)).toBe(false);
});
});
describe('TaskSummaryService', () => {
it('should export functional interface', () => {
expect(typeof taskSummaryService.generateSummaryForUser).toBe('function');
expect(typeof taskSummaryService.sendSummaryToUser).toBe('function');
expect(typeof taskSummaryService.calculateNextRunTime).toBe('function');
});
it('should have pure helper functions for testing', () => {
expect(typeof taskSummaryService._escapeMarkdown).toBe('function');
expect(typeof taskSummaryService._getPriorityEmoji).toBe('function');
expect(typeof taskSummaryService._buildTaskSection).toBe('function');
});
it('should escape markdown correctly', () => {
const text = 'Task with *bold* and _italic_ text';
const escaped = taskSummaryService._escapeMarkdown(text);
expect(escaped).toBe('Task with \\*bold\\* and \\_italic\\_ text');
});
it('should return correct priority emojis', () => {
expect(taskSummaryService._getPriorityEmoji(0)).toBe('🟢'); // low
expect(taskSummaryService._getPriorityEmoji(1)).toBe('🟠'); // medium
expect(taskSummaryService._getPriorityEmoji(2)).toBe('🔴'); // high
expect(taskSummaryService._getPriorityEmoji(99)).toBe('⚪'); // unknown
});
});
});