package nl.agilecc.agiledancers; import static org.junit.jupiter.api.Assertions.*; import java.time.LocalDate; import java.util.*; import nl.agilecc.agiledancers.model.specifications.*; import nl.agilecc.agiledancers.service.*; import nl.agilecc.agiledancers.service.model.*; import org.junit.jupiter.api.Test; class SchoolSnapshotTest { private SchoolSnapshot complete() { return new SchoolSnapshot( 2, UUID.randomUUID(), "Studio", List.of(new Person("a", "Sam", LocalDate.of(2010, 1, 1))), List.of(new Trainer("c", "Alex")), List.of( new Group( "g", "Hiphop", DanceGroupType.REGULAR, 0, 99, List.of(DanceGroupStyle.HIPHOP), List.of("a"), "c"), new Group("h", "Jazz", DanceGroupType.REGULAR, 0, 99, List.of(), List.of("a"), "c")), List.of(new Performance( "s", "Show", List.of(new Part(LocalDate.of(2027, 1, 1), DayPartType.MORNING, List.of("g", "h"))), ShowConfiguration.defaults(1)))); } @Test void roundTripAfterRestartPreservesAllFieldsAndSharedRelationships() { var snapshot = complete(); var service = new SchoolManagementService(); var existing = service.createSchool("Other"); service.createDancer(existing.getId(), "Other dancer", LocalDate.of(2000, 1, 1)); var imported = service.importSchool(snapshot, null); assertEquals(2, imported.getDanceGroups().size()); var dancer = imported.getDancers().iterator().next(); imported.getDanceGroups() .forEach(g -> assertSame(dancer, g.getDancers().iterator().next())); assertEquals(SchoolSnapshot.of(snapshot.restore()), service.exportSchool(imported.getId())); var restarted = new SchoolManagementService(); var restored = restarted.importSchool(service.exportSchool(imported.getId()), null); assertEquals(SchoolSnapshot.of(snapshot.restore()), restarted.exportSchool(restored.getId())); // Membership removal must work after remapping hash-based sets. service.deleteDancer(imported.getId(), dancer.getId()); imported.getDanceGroups().forEach(g -> assertTrue(g.getDancers().isEmpty())); assertEquals(1, existing.getDancers().size()); var group = imported.getDanceGroups().iterator().next(); service.deleteGroup(imported.getId(), group.getId()); assertEquals( 1, imported.getShows() .iterator() .next() .getDayParts() .getFirst() .getDanceGroups() .size()); assertDoesNotThrow(() -> service.exportSchool(imported.getId()).restore()); } @Test void previewIsReadOnlyAndReplacementRemovesPreviousConfiguration() { var service = new SchoolManagementService(); var snapshot = complete(); assertNull(service.preview(snapshot).existingId()); assertTrue(service.schools().isEmpty()); var original = service.importSchool(snapshot, null); service.createDancer(original.getId(), "Extra", LocalDate.of(2000, 1, 1)); var other = service.createSchool(snapshot.name()); assertEquals(original.getId(), service.preview(snapshot).existingId()); assertThrows(ManagementException.class, () -> service.importSchool(snapshot, null)); assertEquals(2, original.getDancers().size()); var replaced = service.importSchool(snapshot, original.getId()); assertEquals(SchoolSnapshot.of(snapshot.restore()), service.exportSchool(replaced.getId())); assertSame(other, service.school(other.getId())); service.deleteSchool(replaced.getId()); assertEquals( SchoolSnapshot.of(snapshot.restore()), service.exportSchool(service.importSchool(snapshot, null).getId())); } @Test void unresolvedReferenceLeavesExistingAndOtherSchoolsIntact() { var service = new SchoolManagementService(); var valid = complete(); var original = service.importSchool(valid, null); var bad = new SchoolSnapshot( 2, valid.key(), valid.name(), List.of(), valid.coaches(), valid.groups(), valid.shows()); assertThrows(ManagementException.class, () -> service.preview(bad)); assertThrows(ManagementException.class, () -> service.importSchool(bad, original.getId())); assertEquals(SchoolSnapshot.of(valid.restore()), service.exportSchool(original.getId())); } @Test void emptySchoolRoundTrips() { var service = new SchoolManagementService(); var empty = service.createSchool("Empty"); var snapshot = service.exportSchool(empty.getId()); service.deleteSchool(empty.getId()); assertEquals( SchoolSnapshot.of(snapshot.restore()), service.exportSchool(service.importSchool(snapshot, null).getId())); } }