fix(hoy): el temporizador de salida desaparece sin cole o pasada la hora

buildTimer clavaba el contador en "0 min" el resto del día (Math.max(0,..)),
incluso en días sin cole. Ahora es función pura: sin tareas de mañana o con
la hora de salida ya pasada devuelve minutos null y el kiosko no lo pinta.
Test unitario determinista de los cinco casos.
This commit is contained in:
Jaume Garriga Maestre
2026-07-12 22:12:44 +02:00
parent 0e8bfbcc9c
commit 1db262f8ea
2 changed files with 62 additions and 7 deletions

View File

@@ -76,7 +76,7 @@ public class TodayService {
events, events,
ProgressCalculator.from(tasks), ProgressCalculator.from(tasks),
new WalletInfo(child.getCoins()), new WalletInfo(child.getCoins()),
buildTimer(child)); buildTimer(child.getDepartureTime(), LocalTime.now(clock), morning.isEmpty()));
} }
private TaskView toTaskView(DailyTask t) { private TaskView toTaskView(DailyTask t) {
@@ -95,13 +95,20 @@ public class TodayService {
c.isDyslexiaFont()); c.isDyslexiaFont());
} }
/** Temporizador de salida: minutos que faltan hasta departureTime (>= 0). */ /**
private TimerInfo buildTimer(Child child) { * Temporizador de salida. Solo tiene sentido si HOY hay cole (hay tareas de
LocalTime departure = child.getDepartureTime(); * mañana) y aún no ha pasado la hora: pasado ese momento desaparece, en vez de
if (departure == null) { * quedarse clavado en "0 min" el resto del día (o en domingo). Con minutos a
* null el kiosko no lo pinta.
*/
static TimerInfo buildTimer(LocalTime departure, LocalTime now, boolean sinColeHoy) {
if (departure == null || sinColeHoy) {
return new TimerInfo(null, null); return new TimerInfo(null, null);
} }
long minutes = Duration.between(LocalTime.now(clock), departure).toMinutes(); long minutes = Duration.between(now, departure).toMinutes();
return new TimerInfo(departure.format(HHMM), (int) Math.max(0, minutes)); if (minutes < 0) {
return new TimerInfo(departure.format(HHMM), null);
}
return new TimerInfo(departure.format(HHMM), (int) minutes);
} }
} }

View File

@@ -0,0 +1,48 @@
package es.asepeyo.recordalexia.service;
import static org.assertj.core.api.Assertions.assertThat;
import es.asepeyo.recordalexia.web.dto.TodayResponse.TimerInfo;
import java.time.LocalTime;
import org.junit.jupiter.api.Test;
/**
* Reglas del temporizador "SALIMOS EN X min": solo aparece si hoy hay cole y la
* hora de salida no ha pasado; nunca se queda clavado en "0 min" el resto del día.
*/
class TodayServiceTimerTest {
private static final LocalTime SALIDA = LocalTime.of(8, 30);
@Test
void sinHoraDeSalidaNoHayTemporizador() {
TimerInfo timer = TodayService.buildTimer(null, LocalTime.of(8, 0), false);
assertThat(timer.departureTime()).isNull();
assertThat(timer.minutesUntilDeparture()).isNull();
}
@Test
void sinColeHoyNoHayTemporizador() {
TimerInfo timer = TodayService.buildTimer(SALIDA, LocalTime.of(8, 0), true);
assertThat(timer.minutesUntilDeparture()).isNull();
}
@Test
void antesDeLaHoraMuestraLosMinutosQueFaltan() {
TimerInfo timer = TodayService.buildTimer(SALIDA, LocalTime.of(8, 10), false);
assertThat(timer.departureTime()).isEqualTo("08:30");
assertThat(timer.minutesUntilDeparture()).isEqualTo(20);
}
@Test
void justoALaHoraMuestraCero() {
TimerInfo timer = TodayService.buildTimer(SALIDA, LocalTime.of(8, 30), false);
assertThat(timer.minutesUntilDeparture()).isZero();
}
@Test
void pasadaLaHoraDesaparece() {
TimerInfo timer = TodayService.buildTimer(SALIDA, LocalTime.of(10, 0), false);
assertThat(timer.minutesUntilDeparture()).isNull();
}
}