All files / notifications quiet-hours.ts

100% Statements 18/18
95.23% Branches 20/21
100% Functions 1/1
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39                  1x             10x 10x       10x 8x   7x 7x 7x 7x   4x 4x   4x 1x   4x 4x    
import type { Severity } from './notification-rules';
 
/**
 * Calculeaza cand se poate livra o notificare data fiind fereastra de liniste
 * a userului. Intoarce null cand se poate livra imediat.
 *
 * Functie pura, separata de runner, ca sa fie testabila: aritmetica de ore cu
 * fereastra care traverseaza miezul noptii e locul unde apar erorile.
 */
export function quietHoursDelay(params: {
  start: number | null;
  end: number | null;
  severity: Severity;
  criticalBypasses: boolean;
  now?: Date;
}): Date | null {
  const { start, end, severity, criticalBypasses } = params;
  const now = params.now ?? new Date();
 
  // start === end ar insemna fereastra de 24h sau de 0h -- ambiguu, deci o
  // tratam ca "fara quiet hours" in loc sa ghicim.
  if (start === null || end === null || start === end) return null;
  if (severity === 'CRITICAL' && criticalBypasses) return null;
 
  const hour = now.getUTCHours();
  const crossesMidnight = start > end;
  const inQuiet = crossesMidnight ? hour >= start || hour < end : hour >= start && hour < end;
  if (!inQuiet) return null;
 
  const deliverAt = new Date(now);
  deliverAt.setUTCMinutes(0, 0, 0);
  // Daca ora curenta e deja peste ora de sfarsit, sfarsitul ferestrei e maine.
  if (hour >= end) {
    deliverAt.setUTCDate(deliverAt.getUTCDate() + 1);
  }
  deliverAt.setUTCHours(end);
  return deliverAt;
}