tududi/backend/tests/integration/recurring-display-fixes.test.js
Chris 8bc951b0ff
Replace ?uid with /:uid (#482)
* Replace ?uid with /:uid

* fixup! Replace ?uid with /:uid
2025-11-04 14:29:31 +02:00

315 lines
12 KiB
JavaScript

const request = require('supertest');
const app = require('../../app');
const { Task, Project } = require('../../models');
const { createTestUser } = require('../helpers/testUtils');
describe('Recurring Task Display Fixes', () => {
let user, project, agent;
beforeEach(async () => {
user = await createTestUser({
email: 'test@example.com',
});
project = await Project.create({
name: 'Test Project',
user_id: user.id,
});
// Create authenticated agent
agent = request.agent(app);
await agent.post('/api/login').send({
email: 'test@example.com',
password: 'password123',
});
});
describe('Recurrence Type Display Names', () => {
it('should show "Daily" instead of recurring task template name', async () => {
const recurringTemplate = await Task.create({
name: 'Daily Workout Original Name',
user_id: user.id,
project_id: project.id,
recurrence_type: 'daily',
recurrence_interval: 1,
recurring_parent_id: null,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get('/api/tasks');
expect(response.status).toBe(200);
const task = response.body.tasks.find(
(t) => t.id === recurringTemplate.id
);
expect(task).toBeDefined();
expect(task.name).toBe('Daily');
expect(task.original_name).toBe('Daily Workout Original Name');
expect(task.recurrence_type).toBe('daily');
});
it('should show "Weekly" for weekly recurring tasks', async () => {
const weeklyTask = await Task.create({
name: 'Weekly Review Task',
user_id: user.id,
recurrence_type: 'weekly',
recurring_parent_id: null,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get('/api/tasks');
expect(response.status).toBe(200);
const task = response.body.tasks.find(
(t) => t.id === weeklyTask.id
);
expect(task).toBeDefined();
expect(task.name).toBe('Weekly');
expect(task.original_name).toBe('Weekly Review Task');
});
it('should show "Monthly" for monthly recurring tasks', async () => {
const monthlyTask = await Task.create({
name: 'Monthly Report',
user_id: user.id,
recurrence_type: 'monthly',
recurring_parent_id: null,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get('/api/tasks');
expect(response.status).toBe(200);
const task = response.body.tasks.find(
(t) => t.id === monthlyTask.id
);
expect(task).toBeDefined();
expect(task.name).toBe('Monthly');
expect(task.original_name).toBe('Monthly Report');
});
it('should show "Yearly" for yearly recurring tasks', async () => {
const yearlyTask = await Task.create({
name: 'Annual Tax Filing',
user_id: user.id,
recurrence_type: 'yearly',
recurring_parent_id: null,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get('/api/tasks');
expect(response.status).toBe(200);
const task = response.body.tasks.find(
(t) => t.id === yearlyTask.id
);
expect(task).toBeDefined();
expect(task.name).toBe('Yearly');
expect(task.original_name).toBe('Annual Tax Filing');
});
it('should not modify names of non-recurring tasks', async () => {
const regularTask = await Task.create({
name: 'Regular Task Name',
user_id: user.id,
recurrence_type: 'none',
recurring_parent_id: null,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get('/api/tasks');
expect(response.status).toBe(200);
const task = response.body.tasks.find(
(t) => t.id === regularTask.id
);
expect(task).toBeDefined();
expect(task.name).toBe('Regular Task Name');
expect(task.original_name).toBe('Regular Task Name');
});
it('should not modify names of recurring task instances', async () => {
const template = await Task.create({
name: 'Template Task',
user_id: user.id,
recurrence_type: 'daily',
recurring_parent_id: null,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const instance = await Task.create({
name: 'Daily Instance - Aug 23',
user_id: user.id,
recurrence_type: 'none',
recurring_parent_id: template.id,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
// Since instances are filtered out, we won't see them in the response
// But if they were included, they should keep their original name
const response = await agent.get('/api/tasks');
expect(response.status).toBe(200);
const templateTask = response.body.tasks.find(
(t) => t.id === template.id
);
const instanceTask = response.body.tasks.find(
(t) => t.id === instance.id
);
expect(templateTask).toBeDefined();
expect(templateTask.name).toBe('Daily'); // Template shows "Daily"
expect(instanceTask).toBeUndefined(); // Instance should be filtered out
});
});
describe('Past Missed Recurring Tasks Filtering', () => {
it('should hide recurring templates with past due dates', async () => {
const pastDate = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000); // 3 days ago
const futureDate = new Date(Date.now() + 3 * 24 * 60 * 60 * 1000); // 3 days from now
// Past recurring template (should be hidden)
const pastRecurring = await Task.create({
name: 'Past Daily Task',
user_id: user.id,
recurrence_type: 'daily',
recurring_parent_id: null,
due_date: pastDate,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
// Future recurring template (should be shown)
const futureRecurring = await Task.create({
name: 'Future Daily Task',
user_id: user.id,
recurrence_type: 'daily',
recurring_parent_id: null,
due_date: futureDate,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
// Past regular task (should still be shown - overdue tasks are allowed)
const pastRegular = await Task.create({
name: 'Past Regular Task',
user_id: user.id,
recurrence_type: 'none',
recurring_parent_id: null,
due_date: pastDate,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get('/api/tasks');
expect(response.status).toBe(200);
const taskIds = response.body.tasks.map((t) => t.id);
const taskNames = response.body.tasks.map((t) => t.name);
// Past recurring template should be hidden
expect(taskIds).not.toContain(pastRecurring.id);
// Future recurring template should be shown as "Daily"
expect(taskIds).toContain(futureRecurring.id);
expect(taskNames).toContain('Daily');
// Past regular task should still be shown (overdue tasks are allowed for non-recurring)
expect(taskIds).toContain(pastRegular.id);
expect(taskNames).toContain('Past Regular Task');
});
it('should show recurring templates with no due date', async () => {
const recurringNoDueDate = await Task.create({
name: 'No Due Date Recurring',
user_id: user.id,
recurrence_type: 'weekly',
recurring_parent_id: null,
due_date: null,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get('/api/tasks');
expect(response.status).toBe(200);
const taskIds = response.body.tasks.map((t) => t.id);
const taskNames = response.body.tasks.map((t) => t.name);
expect(taskIds).toContain(recurringNoDueDate.id);
expect(taskNames).toContain('Weekly');
});
it('should show recurring templates due today', async () => {
const today = new Date();
today.setHours(12, 0, 0, 0); // Set to noon today
const todayRecurring = await Task.create({
name: 'Today Recurring Task',
user_id: user.id,
recurrence_type: 'daily',
recurring_parent_id: null,
due_date: today,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get('/api/tasks');
expect(response.status).toBe(200);
const taskIds = response.body.tasks.map((t) => t.id);
const taskNames = response.body.tasks.map((t) => t.name);
expect(taskIds).toContain(todayRecurring.id);
expect(taskNames).toContain('Daily');
});
});
describe('Task By UID Endpoint', () => {
it('should return actual task name when fetching recurring task by UID', async () => {
const recurringTask = await Task.create({
name: 'My Weekly Review',
user_id: user.id,
recurrence_type: 'weekly',
recurring_parent_id: null,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get(`/api/task/${recurringTask.uid}`);
expect(response.status).toBe(200);
expect(response.body.name).toBe('My Weekly Review');
expect(response.body.original_name).toBe('My Weekly Review');
expect(response.body.recurrence_type).toBe('weekly');
});
it('should return actual task name for monthly recurring task by UID', async () => {
const monthlyTask = await Task.create({
name: 'Monthly Budget Review',
user_id: user.id,
recurrence_type: 'monthly',
recurring_parent_id: null,
status: Task.STATUS.NOT_STARTED,
priority: Task.PRIORITY.MEDIUM,
});
const response = await agent.get(`/api/task/${monthlyTask.uid}`);
expect(response.status).toBe(200);
expect(response.body.name).toBe('Monthly Budget Review');
expect(response.body.original_name).toBe('Monthly Budget Review');
expect(response.body.recurrence_type).toBe('monthly');
});
});
});