fix(rutinas): cascade al borrar del catálogo, orden por día y test de migración real
- Changeset 004: ON DELETE CASCADE en fk_routine_assignment_task; borrar una rutina del catálogo arrastra sus asignaciones en vez de fallar (test). - El orderIndex de la asignación multi-día lo calcula el backend al final de CADA día destino (antes lo enviaba el front desde el día visible). - MigrationIT con Testcontainers: el changelog completo y el mapeo JPA se verifican contra Postgres 16 real (H2 no detecta su tipado estricto). - DataSeeder delega en InitialDatasetService: una sola fuente de verdad del dataset inicial; la demo solo añade sus extras. - Eliminado .gitkeep de changes/ (WARN de Liquibase en cada arranque).
This commit is contained in:
@@ -7,18 +7,16 @@ import es.asepeyo.recordalexia.domain.EventType;
|
||||
import es.asepeyo.recordalexia.domain.Family;
|
||||
import es.asepeyo.recordalexia.domain.MaterialItem;
|
||||
import es.asepeyo.recordalexia.domain.Reward;
|
||||
import es.asepeyo.recordalexia.domain.RoutineTask;
|
||||
import es.asepeyo.recordalexia.domain.SpecialEvent;
|
||||
import es.asepeyo.recordalexia.domain.WeeklyTemplateEntry;
|
||||
import es.asepeyo.recordalexia.repository.ActivityRepository;
|
||||
import es.asepeyo.recordalexia.repository.AfternoonRoutineRepository;
|
||||
import es.asepeyo.recordalexia.repository.ChildRepository;
|
||||
import es.asepeyo.recordalexia.repository.FamilyRepository;
|
||||
import es.asepeyo.recordalexia.repository.MaterialItemRepository;
|
||||
import es.asepeyo.recordalexia.repository.RewardRepository;
|
||||
import es.asepeyo.recordalexia.repository.RoutineTaskRepository;
|
||||
import es.asepeyo.recordalexia.repository.SpecialEventRepository;
|
||||
import es.asepeyo.recordalexia.repository.WeeklyTemplateEntryRepository;
|
||||
import es.asepeyo.recordalexia.service.InitialDatasetService;
|
||||
import java.time.Clock;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
@@ -52,29 +50,26 @@ public class DataSeeder implements ApplicationRunner {
|
||||
private final MaterialItemRepository materialRepository;
|
||||
private final ActivityRepository activityRepository;
|
||||
private final WeeklyTemplateEntryRepository templateRepository;
|
||||
private final AfternoonRoutineRepository routineRepository;
|
||||
private final RoutineTaskRepository routineTaskRepository;
|
||||
private final SpecialEventRepository eventRepository;
|
||||
private final RewardRepository rewardRepository;
|
||||
private final InitialDatasetService initialDataset;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final Clock clock;
|
||||
|
||||
public DataSeeder(FamilyRepository familyRepository, ChildRepository childRepository,
|
||||
MaterialItemRepository materialRepository, ActivityRepository activityRepository,
|
||||
WeeklyTemplateEntryRepository templateRepository,
|
||||
AfternoonRoutineRepository routineRepository,
|
||||
RoutineTaskRepository routineTaskRepository,
|
||||
SpecialEventRepository eventRepository, RewardRepository rewardRepository,
|
||||
InitialDatasetService initialDataset,
|
||||
PasswordEncoder passwordEncoder, Clock clock) {
|
||||
this.familyRepository = familyRepository;
|
||||
this.childRepository = childRepository;
|
||||
this.materialRepository = materialRepository;
|
||||
this.activityRepository = activityRepository;
|
||||
this.templateRepository = templateRepository;
|
||||
this.routineRepository = routineRepository;
|
||||
this.routineTaskRepository = routineTaskRepository;
|
||||
this.eventRepository = eventRepository;
|
||||
this.rewardRepository = rewardRepository;
|
||||
this.initialDataset = initialDataset;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.clock = clock;
|
||||
}
|
||||
@@ -89,9 +84,10 @@ public class DataSeeder implements ApplicationRunner {
|
||||
Family family = familyRepository.save(new Family(DEMO_EMAIL,
|
||||
passwordEncoder.encode(DEMO_PASSWORD), "Familia demo", passwordEncoder.encode(DEMO_PIN)));
|
||||
|
||||
var materials = seedMaterials(family);
|
||||
var activities = seedActivities(family, materials);
|
||||
var routines = seedRoutineCatalog(family);
|
||||
// Catálogo base (materiales + rutinas): la MISMA provisión que recibe cualquier
|
||||
// familia real al registrarse. La demo solo añade sus extras encima.
|
||||
initialDataset.provisionFamily(family);
|
||||
var activities = seedActivities(family);
|
||||
seedRewards(family);
|
||||
|
||||
Child nora = childRepository.save(child(family, "Nora", "🦊", "#F2A65A", 7, 42, LocalTime.of(8, 30)));
|
||||
@@ -100,7 +96,8 @@ public class DataSeeder implements ApplicationRunner {
|
||||
|
||||
for (Child c : List.of(nora, leo, mia)) {
|
||||
seedWeeklyMornings(c, activities);
|
||||
seedAfternoonRoutines(c, routines);
|
||||
// Rutinas de tarde escalonadas por edad, desde el catálogo de la familia.
|
||||
initialDataset.provisionChildRoutines(c);
|
||||
}
|
||||
|
||||
LocalDate today = LocalDate.now(clock);
|
||||
@@ -110,38 +107,40 @@ public class DataSeeder implements ApplicationRunner {
|
||||
"Ficha de mates", "Fitxa de mates", "📎", "#5B8DEF"));
|
||||
}
|
||||
|
||||
private MaterialsCatalog seedMaterials(Family family) {
|
||||
return new MaterialsCatalog(
|
||||
material(family, "Estuche", "Estoig", "✏️", "#F4C95D", "general"),
|
||||
material(family, "Libro de mates", "Llibre de mates", "📘", "#5B8DEF", "matematicas"),
|
||||
material(family, "Regla", "Regle", "📏", "#5B8DEF", "matematicas"),
|
||||
material(family, "Flauta", "Flauta", "🎵", "#A78BD0", "musica"),
|
||||
material(family, "Libreta", "Llibreta", "📓", "#A78BD0", "musica"),
|
||||
material(family, "Ropa de gimnasia", "Roba d'EF", "👕", "#7FBF6B", "gimnasia"),
|
||||
material(family, "Zapatillas", "Sabatilles", "👟", "#7FBF6B", "gimnasia"),
|
||||
material(family, "Toalla", "Tovallola", "🧖", "#5BC0BE", "gimnasia"),
|
||||
material(family, "Agua", "Aigua", "💧", "#5BC0BE", "gimnasia"),
|
||||
material(family, "Lectura", "Lectura", "📖", "#F2A65A", "lengua"),
|
||||
material(family, "Cuaderno", "Quadern", "📒", "#F2A65A", "lengua"),
|
||||
material(family, "Almuerzo", "Esmorzar", "🍎", "#EC8FA4", "general"));
|
||||
}
|
||||
|
||||
private MaterialItem material(Family family, String es, String ca, String icon, String color, String category) {
|
||||
MaterialItem m = new MaterialItem(es, ca, icon, color, category);
|
||||
m.setFamily(family);
|
||||
return materialRepository.save(m);
|
||||
}
|
||||
|
||||
private ActivitiesCatalog seedActivities(Family family, MaterialsCatalog m) {
|
||||
/**
|
||||
* Actividades de la demo. El material sale del catálogo base ya provisionado
|
||||
* (por su etiqueta ES) más tres extras que solo la demo necesita.
|
||||
*/
|
||||
private ActivitiesCatalog seedActivities(Family family) {
|
||||
List<MaterialItem> base = materialRepository.findByFamilyId(family.getId());
|
||||
MaterialItem flauta = material(family, "Flauta", "Flauta", "🎵", "#A78BD0", "musica");
|
||||
MaterialItem regla = material(family, "Regla", "Regle", "📏", "#5B8DEF", "matematicas");
|
||||
MaterialItem toalla = material(family, "Toalla", "Tovallola", "🧖", "#5BC0BE", "gimnasia");
|
||||
|
||||
Activity gimnasia = activity(family, "Gimnasia", "Gimnàstica", "🤸", "#7FBF6B",
|
||||
m.ropaGimnasia, m.zapatillas, m.toalla, m.agua);
|
||||
Activity musica = activity(family, "Música", "Música", "🎵", "#A78BD0", m.flauta, m.libreta);
|
||||
fromBase(base, "Ropa de gimnasia"), fromBase(base, "Zapatillas"), toalla,
|
||||
fromBase(base, "Botella de agua"));
|
||||
Activity musica = activity(family, "Música", "Música", "🎵", "#A78BD0",
|
||||
flauta, fromBase(base, "Libreta"));
|
||||
Activity mates = activity(family, "Matemáticas", "Matemàtiques", "📘", "#5B8DEF",
|
||||
m.libroMates, m.regla, m.estuche);
|
||||
Activity lengua = activity(family, "Lengua", "Llengua", "📖", "#F2A65A", m.lectura, m.cuaderno);
|
||||
fromBase(base, "Libro de texto"), regla, fromBase(base, "Estuche"));
|
||||
Activity lengua = activity(family, "Lengua", "Llengua", "📖", "#F2A65A",
|
||||
fromBase(base, "Lectura"), fromBase(base, "Libreta"));
|
||||
return new ActivitiesCatalog(gimnasia, musica, mates, lengua);
|
||||
}
|
||||
|
||||
/** Localiza un material del catálogo base por su etiqueta ES (clave estable del seed). */
|
||||
private MaterialItem fromBase(List<MaterialItem> base, String labelEs) {
|
||||
return base.stream().filter(m -> m.getLabelEs().equals(labelEs)).findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException("Falta el material base: " + labelEs));
|
||||
}
|
||||
|
||||
private Activity activity(Family family, String es, String ca, String icon, String color, MaterialItem... mats) {
|
||||
Activity activity = new Activity(es, ca, icon, color);
|
||||
activity.setFamily(family);
|
||||
@@ -191,45 +190,7 @@ public class DataSeeder implements ApplicationRunner {
|
||||
templateRepository.save(new WeeklyTemplateEntry(child, day, activity, 0));
|
||||
}
|
||||
|
||||
/** Catálogo de rutinas reutilizables de la familia (se definen una sola vez). */
|
||||
private RoutinesCatalog seedRoutineCatalog(Family family) {
|
||||
return new RoutinesCatalog(
|
||||
routineTask(family, "Deshacer la mochila", "Buidar la motxilla", "🎒", "#F2A65A"),
|
||||
routineTask(family, "Merendar", "Berenar", "🥪", "#F4C95D"),
|
||||
routineTask(family, "Hacer los deberes", "Fer els deures", "📝", "#5B8DEF"),
|
||||
routineTask(family, "Practicar piano", "Practicar piano", "🎹", "#A78BD0"),
|
||||
routineTask(family, "Recoger la mesa", "Parar taula", "🍽️", "#7FBF6B"));
|
||||
}
|
||||
|
||||
private RoutineTask routineTask(Family family, String es, String ca, String icon, String color) {
|
||||
RoutineTask rt = new RoutineTask(es, ca, icon, color);
|
||||
rt.setFamily(family);
|
||||
return routineTaskRepository.save(rt);
|
||||
}
|
||||
|
||||
/** Asigna las rutinas del catálogo a cada día laborable, reutilizando las mismas. */
|
||||
private void seedAfternoonRoutines(Child child, RoutinesCatalog r) {
|
||||
for (DayOfWeek day : List.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY,
|
||||
DayOfWeek.THURSDAY, DayOfWeek.FRIDAY)) {
|
||||
routineRepository.save(new AfternoonRoutine(child, day, r.mochila, 0));
|
||||
routineRepository.save(new AfternoonRoutine(child, day, r.merienda, 1));
|
||||
routineRepository.save(new AfternoonRoutine(child, day, r.deberes, 2));
|
||||
routineRepository.save(new AfternoonRoutine(child, day, r.piano, 3));
|
||||
routineRepository.save(new AfternoonRoutine(child, day, r.mesa, 4));
|
||||
}
|
||||
}
|
||||
|
||||
private record MaterialsCatalog(
|
||||
MaterialItem estuche, MaterialItem libroMates, MaterialItem regla, MaterialItem flauta,
|
||||
MaterialItem libreta, MaterialItem ropaGimnasia, MaterialItem zapatillas, MaterialItem toalla,
|
||||
MaterialItem agua, MaterialItem lectura, MaterialItem cuaderno, MaterialItem almuerzo) {
|
||||
}
|
||||
|
||||
private record ActivitiesCatalog(Activity gimnasia, Activity musica, Activity matematicas,
|
||||
Activity lengua) {
|
||||
}
|
||||
|
||||
private record RoutinesCatalog(RoutineTask mochila, RoutineTask merienda, RoutineTask deberes,
|
||||
RoutineTask piano, RoutineTask mesa) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,4 +11,7 @@ public interface AfternoonRoutineRepository extends JpaRepository<AfternoonRouti
|
||||
List<AfternoonRoutine> findByChildIdAndDayOfWeekOrderByOrderIndexAsc(Long childId, DayOfWeek dayOfWeek);
|
||||
|
||||
List<AfternoonRoutine> findByChildIdOrderByDayOfWeekAscOrderIndexAsc(Long childId);
|
||||
|
||||
/** Nº de asignaciones de un niño en un día; da el siguiente orderIndex al asignar. */
|
||||
int countByChildIdAndDayOfWeek(Long childId, DayOfWeek dayOfWeek);
|
||||
}
|
||||
|
||||
@@ -109,9 +109,12 @@ public class ParentScheduleController {
|
||||
Child child = requireChild(req.childId());
|
||||
RoutineTask task = routineTaskRepository.findByIdAndFamilyId(req.routineTaskId(), fid())
|
||||
.orElseThrow(() -> new NotFoundException("No existe la rutina con id " + req.routineTaskId()));
|
||||
int orderIndex = req.orderIndex() != null ? req.orderIndex() : 0;
|
||||
List<RoutineView> created = req.daysOfWeek().stream().map(day -> {
|
||||
AfternoonRoutine routine = new AfternoonRoutine(child, DayOfWeek.valueOf(day), task, orderIndex);
|
||||
DayOfWeek dayOfWeek = DayOfWeek.valueOf(day);
|
||||
// Sin orden explícito, la rutina se añade al final DE CADA día destino.
|
||||
int orderIndex = req.orderIndex() != null ? req.orderIndex()
|
||||
: routineRepository.countByChildIdAndDayOfWeek(child.getId(), dayOfWeek);
|
||||
AfternoonRoutine routine = new AfternoonRoutine(child, dayOfWeek, task, orderIndex);
|
||||
routine.setCoinsReward(req.coinsReward());
|
||||
return toRoutineView(routineRepository.save(routine));
|
||||
}).toList();
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# Los changesets de Liquibase de la Fase 2 (dominio) vivirán aquí.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Borrado en cascada del catálogo de rutinas.
|
||||
# Al eliminar una rutina del catálogo (routine_task) deben desaparecer sus
|
||||
# asignaciones a días (afternoon_routine): es el modelo mental del padre
|
||||
# ("quito Merendar" = desaparece de todos los días). Sin esto, el DELETE
|
||||
# fallaba con violación de FK y el panel devolvía un error 500.
|
||||
databaseChangeLog:
|
||||
- changeSet:
|
||||
id: 400-cascade-routine-assignment
|
||||
author: recordalexia
|
||||
changes:
|
||||
- dropForeignKeyConstraint:
|
||||
baseTableName: afternoon_routine
|
||||
constraintName: fk_routine_assignment_task
|
||||
- addForeignKeyConstraint:
|
||||
baseTableName: afternoon_routine
|
||||
baseColumnNames: routine_task_id
|
||||
referencedTableName: routine_task
|
||||
referencedColumnNames: id
|
||||
constraintName: fk_routine_assignment_task
|
||||
onDelete: CASCADE
|
||||
rollback:
|
||||
- dropForeignKeyConstraint:
|
||||
baseTableName: afternoon_routine
|
||||
constraintName: fk_routine_assignment_task
|
||||
- addForeignKeyConstraint:
|
||||
baseTableName: afternoon_routine
|
||||
baseColumnNames: routine_task_id
|
||||
referencedTableName: routine_task
|
||||
referencedColumnNames: id
|
||||
constraintName: fk_routine_assignment_task
|
||||
@@ -0,0 +1,45 @@
|
||||
package es.asepeyo.recordalexia;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import es.asepeyo.recordalexia.repository.AfternoonRoutineRepository;
|
||||
import es.asepeyo.recordalexia.repository.FamilyRepository;
|
||||
import es.asepeyo.recordalexia.repository.RoutineTaskRepository;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
/**
|
||||
* Verifica el changelog completo de Liquibase contra un Postgres REAL (misma
|
||||
* imagen que producción). Cubre lo que H2 no puede: tipado estricto de Postgres
|
||||
* en la migración SQL, y que el esquema resultante casa con el mapeo JPA
|
||||
* (ddl-auto=validate). Con el seeder activado comprueba además el estado final.
|
||||
*
|
||||
* Se desactiva sola si Docker no está disponible en la máquina.
|
||||
*/
|
||||
@SpringBootTest
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
@TestPropertySource(properties = "recordalexia.seed.enabled=true")
|
||||
class MigrationIT {
|
||||
|
||||
@Container
|
||||
@ServiceConnection
|
||||
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");
|
||||
|
||||
@Autowired private FamilyRepository familyRepository;
|
||||
@Autowired private RoutineTaskRepository routineTaskRepository;
|
||||
@Autowired private AfternoonRoutineRepository routineRepository;
|
||||
|
||||
@Test
|
||||
void lasMigracionesAplicanYelSeederPueblaEnPostgresReal() {
|
||||
// Si llegamos aquí, Liquibase aplicó 001-004 y Hibernate validó el esquema.
|
||||
assertThat(familyRepository.findByEmailIgnoreCase("demo@recordalexia.local")).isPresent();
|
||||
assertThat(routineTaskRepository.count()).isEqualTo(14);
|
||||
assertThat(routineRepository.count()).isEqualTo(75); // 3 niños x 5 rutinas x 5 días
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,12 @@ package es.asepeyo.recordalexia.bootstrap;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import es.asepeyo.recordalexia.repository.ActivityRepository;
|
||||
import es.asepeyo.recordalexia.repository.AfternoonRoutineRepository;
|
||||
import es.asepeyo.recordalexia.repository.ChildRepository;
|
||||
import es.asepeyo.recordalexia.repository.FamilyRepository;
|
||||
import es.asepeyo.recordalexia.repository.MaterialItemRepository;
|
||||
import es.asepeyo.recordalexia.repository.RewardRepository;
|
||||
import es.asepeyo.recordalexia.repository.RoutineTaskRepository;
|
||||
import es.asepeyo.recordalexia.repository.WeeklyTemplateEntryRepository;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -14,7 +17,8 @@ import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
/**
|
||||
* Verifica que el sembrado del prototipo (familia demo + sus datos) se ejecuta
|
||||
* correctamente. Usa una BD H2 propia y el seeder activado.
|
||||
* correctamente. La demo se apoya en la MISMA provisión inicial que una familia
|
||||
* real (InitialDatasetService) y añade encima sus extras. Usa una BD H2 propia.
|
||||
*/
|
||||
@SpringBootTest
|
||||
@TestPropertySource(properties = {
|
||||
@@ -28,6 +32,9 @@ class DataSeederIT {
|
||||
@Autowired private RewardRepository rewardRepository;
|
||||
@Autowired private ActivityRepository activityRepository;
|
||||
@Autowired private WeeklyTemplateEntryRepository templateRepository;
|
||||
@Autowired private MaterialItemRepository materialRepository;
|
||||
@Autowired private RoutineTaskRepository routineTaskRepository;
|
||||
@Autowired private AfternoonRoutineRepository routineRepository;
|
||||
|
||||
@Test
|
||||
void siembraLaFamiliaDemoConSusDatos() {
|
||||
@@ -37,4 +44,12 @@ class DataSeederIT {
|
||||
assertThat(activityRepository.count()).isEqualTo(4); // 4 actividades
|
||||
assertThat(templateRepository.count()).isEqualTo(15); // 3 niños x 5 días
|
||||
}
|
||||
|
||||
@Test
|
||||
void laDemoUsaLaProvisionInicialComun() {
|
||||
assertThat(materialRepository.count()).isEqualTo(12); // 9 base + 3 extras demo
|
||||
assertThat(routineTaskRepository.count()).isEqualTo(14); // catálogo común completo
|
||||
// 3 niños (6, 7 y 9 años) -> tramo base: 5 rutinas x 5 días laborables cada uno.
|
||||
assertThat(routineRepository.count()).isEqualTo(75);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package es.asepeyo.recordalexia.repository;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import es.asepeyo.recordalexia.domain.AfternoonRoutine;
|
||||
import es.asepeyo.recordalexia.domain.Child;
|
||||
import es.asepeyo.recordalexia.domain.Family;
|
||||
import es.asepeyo.recordalexia.domain.RoutineTask;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import java.time.DayOfWeek;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Borrar una rutina del catálogo arrastra sus asignaciones a días (ON DELETE
|
||||
* CASCADE del changeset 004). Es el modelo mental del padre: "quito Merendar"
|
||||
* significa que desaparece de todos los días, no un error 500.
|
||||
*/
|
||||
@SpringBootTest
|
||||
@Transactional
|
||||
class RoutineTaskCascadeTest {
|
||||
|
||||
@Autowired private FamilyRepository familyRepository;
|
||||
@Autowired private ChildRepository childRepository;
|
||||
@Autowired private RoutineTaskRepository routineTaskRepository;
|
||||
@Autowired private AfternoonRoutineRepository routineRepository;
|
||||
@PersistenceContext private EntityManager entityManager;
|
||||
|
||||
@Test
|
||||
void borrarRutinaDelCatalogoArrastraSusAsignaciones() {
|
||||
Family family = familyRepository.save(new Family("cascade@x.com", "h", "C", "p"));
|
||||
Child child = new Child();
|
||||
child.setFamily(family);
|
||||
child.setName("Test");
|
||||
child.setMascot("🦊");
|
||||
child.setAccentColor("#F2A65A");
|
||||
child.setAge(8);
|
||||
child = childRepository.save(child);
|
||||
|
||||
RoutineTask merendar = new RoutineTask("Merendar", "Berenar", "🥪", "#F4C95D");
|
||||
merendar.setFamily(family);
|
||||
merendar = routineTaskRepository.save(merendar);
|
||||
routineRepository.save(new AfternoonRoutine(child, DayOfWeek.MONDAY, merendar, 0));
|
||||
routineRepository.save(new AfternoonRoutine(child, DayOfWeek.TUESDAY, merendar, 0));
|
||||
routineRepository.flush();
|
||||
// Contexto limpio, como en una petición real: el cascade lo resuelve la BD,
|
||||
// no la sesión de Hibernate (que si tuviera las asignaciones cargadas se
|
||||
// quejaría de referencias a una entidad borrada).
|
||||
entityManager.clear();
|
||||
|
||||
routineTaskRepository.deleteById(merendar.getId());
|
||||
routineTaskRepository.flush();
|
||||
|
||||
assertThat(routineRepository.findByChildIdOrderByDayOfWeekAscOrderIndexAsc(child.getId()))
|
||||
.isEmpty();
|
||||
assertThat(routineTaskRepository.findById(merendar.getId())).isEmpty();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user