feat: Refactor ScheduleModal to support interval scheduling with date input and deadline toggle
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 2m30s
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 2m30s
- Updated ChoreSchedule model to include anchor_date and interval_has_deadline. - Refactored interval scheduling logic in scheduleUtils to use anchor_date. - Introduced DateInputField component for selecting anchor dates in ScheduleModal. - Enhanced ScheduleModal to include a stepper for interval days and a toggle for deadline. - Updated tests for ScheduleModal and scheduleUtils to reflect new interval scheduling logic. - Added DateInputField tests to ensure proper functionality and prop handling.
This commit is contained in:
@@ -31,26 +31,35 @@ describe('toLocalISODate', () => {
|
||||
// ---------------------------------------------------------------------------
|
||||
describe('intervalHitsToday', () => {
|
||||
it('anchor day hits on itself', () => {
|
||||
// Wednesday = weekday 3
|
||||
const wednesday = new Date(2025, 0, 8) // Jan 8, 2025 is a Wednesday
|
||||
expect(intervalHitsToday(3, 2, wednesday)).toBe(true)
|
||||
expect(intervalHitsToday('2025-01-08', 2, wednesday)).toBe(true)
|
||||
})
|
||||
|
||||
it('anchor=Wednesday, interval=2, Thursday does NOT hit', () => {
|
||||
const thursday = new Date(2025, 0, 9)
|
||||
expect(intervalHitsToday(3, 2, thursday)).toBe(false)
|
||||
it('anchor=Wednesday(2025-01-08), interval=2, Thursday does NOT hit', () => {
|
||||
const thursday = new Date(2025, 0, 9) // 1 day after anchor, 1 % 2 !== 0
|
||||
expect(intervalHitsToday('2025-01-08', 2, thursday)).toBe(false)
|
||||
})
|
||||
|
||||
it('anchor=Wednesday, interval=2, Friday hits (2 days after anchor)', () => {
|
||||
const friday = new Date(2025, 0, 10)
|
||||
expect(intervalHitsToday(3, 2, friday)).toBe(true)
|
||||
it('anchor=Wednesday(2025-01-08), interval=2, Friday hits (2 days after anchor)', () => {
|
||||
const friday = new Date(2025, 0, 10) // 2 days after anchor, 2 % 2 === 0
|
||||
expect(intervalHitsToday('2025-01-08', 2, friday)).toBe(true)
|
||||
})
|
||||
|
||||
it('interval=1 hits every day', () => {
|
||||
// interval of 1 means every day; diffDays % 1 === 0 always
|
||||
// Note: interval_days=1 is disallowed in UI (min 2) but logic should still work
|
||||
const monday = new Date(2025, 0, 6)
|
||||
expect(intervalHitsToday(1, 1, monday)).toBe(true)
|
||||
const monday = new Date(2025, 0, 6) // anchor is that same Monday
|
||||
expect(intervalHitsToday('2025-01-06', 1, monday)).toBe(true)
|
||||
const tuesday = new Date(2025, 0, 7)
|
||||
expect(intervalHitsToday('2025-01-06', 1, tuesday)).toBe(true)
|
||||
})
|
||||
|
||||
it('returns false for a date before the anchor', () => {
|
||||
const beforeAnchor = new Date(2025, 0, 7) // Jan 7 is before Jan 8 anchor
|
||||
expect(intervalHitsToday('2025-01-08', 2, beforeAnchor)).toBe(false)
|
||||
})
|
||||
|
||||
it('empty anchor string treats localDate as the anchor (always hits)', () => {
|
||||
const today = new Date(2025, 0, 8)
|
||||
expect(intervalHitsToday('', 2, today)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -67,7 +76,8 @@ describe('isScheduledToday', () => {
|
||||
{ day: 3, hour: 9, minute: 30 }, // Wednesday
|
||||
],
|
||||
interval_days: 2,
|
||||
anchor_weekday: 0,
|
||||
anchor_date: '',
|
||||
interval_has_deadline: true,
|
||||
interval_hour: 0,
|
||||
interval_minute: 0,
|
||||
}
|
||||
@@ -89,7 +99,8 @@ describe('isScheduledToday', () => {
|
||||
mode: 'interval',
|
||||
day_configs: [],
|
||||
interval_days: 2,
|
||||
anchor_weekday: 3, // Wednesday
|
||||
anchor_date: '2025-01-08', // Wednesday
|
||||
interval_has_deadline: true,
|
||||
interval_hour: 8,
|
||||
interval_minute: 0,
|
||||
}
|
||||
@@ -110,7 +121,8 @@ describe('getDueTimeToday', () => {
|
||||
mode: 'days',
|
||||
day_configs: [{ day: 1, hour: 8, minute: 30 }],
|
||||
interval_days: 2,
|
||||
anchor_weekday: 0,
|
||||
anchor_date: '',
|
||||
interval_has_deadline: true,
|
||||
interval_hour: 0,
|
||||
interval_minute: 0,
|
||||
}
|
||||
@@ -132,7 +144,8 @@ describe('getDueTimeToday', () => {
|
||||
mode: 'interval',
|
||||
day_configs: [],
|
||||
interval_days: 2,
|
||||
anchor_weekday: 3,
|
||||
anchor_date: '2025-01-08',
|
||||
interval_has_deadline: true,
|
||||
interval_hour: 14,
|
||||
interval_minute: 45,
|
||||
}
|
||||
@@ -147,13 +160,31 @@ describe('getDueTimeToday', () => {
|
||||
mode: 'interval',
|
||||
day_configs: [],
|
||||
interval_days: 2,
|
||||
anchor_weekday: 3,
|
||||
anchor_date: '2025-01-08',
|
||||
interval_has_deadline: true,
|
||||
interval_hour: 14,
|
||||
interval_minute: 45,
|
||||
}
|
||||
const thursday = new Date(2025, 0, 9)
|
||||
expect(getDueTimeToday(intervalSchedule, thursday)).toBeNull()
|
||||
})
|
||||
|
||||
it('interval mode with interval_has_deadline=false returns null (Anytime)', () => {
|
||||
const intervalSchedule: ChoreSchedule = {
|
||||
child_id: 'c1',
|
||||
task_id: 't1',
|
||||
mode: 'interval',
|
||||
day_configs: [],
|
||||
interval_days: 2,
|
||||
anchor_date: '2025-01-08',
|
||||
interval_has_deadline: false,
|
||||
interval_hour: 14,
|
||||
interval_minute: 45,
|
||||
}
|
||||
const wednesday = new Date(2025, 0, 8)
|
||||
// Even on a hit day, Anytime means no deadline → null
|
||||
expect(getDueTimeToday(intervalSchedule, wednesday)).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user