82 lines
2.4 KiB
TypeScript
82 lines
2.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import {
|
|
calculateTaskImplementationDuration,
|
|
formatTaskImplementationDuration,
|
|
shouldShowTaskImplementationDuration,
|
|
} from '@shared/utils/taskWorkDuration';
|
|
|
|
describe('taskWorkDuration', () => {
|
|
it('sums completed intervals and the current in-progress interval', () => {
|
|
const duration = calculateTaskImplementationDuration(
|
|
{
|
|
status: 'in_progress',
|
|
workIntervals: [
|
|
{
|
|
startedAt: '2026-05-08T10:00:00.000Z',
|
|
completedAt: '2026-05-08T10:02:30.000Z',
|
|
},
|
|
{ startedAt: '2026-05-08T10:05:00.000Z' },
|
|
],
|
|
},
|
|
Date.parse('2026-05-08T10:07:00.000Z')
|
|
);
|
|
|
|
expect(duration).toEqual({
|
|
elapsedMs: 270_000,
|
|
hasRunningInterval: true,
|
|
countedIntervalCount: 2,
|
|
});
|
|
expect(shouldShowTaskImplementationDuration(duration)).toBe(true);
|
|
});
|
|
|
|
it('does not keep an open interval running after the task leaves in progress', () => {
|
|
const duration = calculateTaskImplementationDuration(
|
|
{
|
|
status: 'completed',
|
|
workIntervals: [
|
|
{
|
|
startedAt: '2026-05-08T10:00:00.000Z',
|
|
completedAt: '2026-05-08T10:02:00.000Z',
|
|
},
|
|
{ startedAt: '2026-05-08T10:05:00.000Z' },
|
|
],
|
|
},
|
|
Date.parse('2026-05-08T10:30:00.000Z')
|
|
);
|
|
|
|
expect(duration).toEqual({
|
|
elapsedMs: 120_000,
|
|
hasRunningInterval: false,
|
|
countedIntervalCount: 1,
|
|
});
|
|
});
|
|
|
|
it('merges overlapping intervals to avoid double counting malformed data', () => {
|
|
const duration = calculateTaskImplementationDuration(
|
|
{
|
|
status: 'completed',
|
|
workIntervals: [
|
|
{
|
|
startedAt: '2026-05-08T10:00:00.000Z',
|
|
completedAt: '2026-05-08T10:10:00.000Z',
|
|
},
|
|
{
|
|
startedAt: '2026-05-08T10:05:00.000Z',
|
|
completedAt: '2026-05-08T10:12:00.000Z',
|
|
},
|
|
],
|
|
},
|
|
Date.parse('2026-05-08T10:30:00.000Z')
|
|
);
|
|
|
|
expect(duration.elapsedMs).toBe(720_000);
|
|
expect(duration.countedIntervalCount).toBe(2);
|
|
});
|
|
|
|
it('formats seconds, minutes, and hours for compact UI labels', () => {
|
|
expect(formatTaskImplementationDuration(42_900)).toBe('42s');
|
|
expect(formatTaskImplementationDuration(65_000)).toBe('1m 05s');
|
|
expect(formatTaskImplementationDuration(7_260_000)).toBe('2h 01m');
|
|
});
|
|
});
|