package nl.agilecc.agiledancers; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import io.quarkus.test.junit.QuarkusTest; import jakarta.inject.Inject; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import nl.agilecc.agiledancers.model.Coach; import nl.agilecc.agiledancers.model.DanceGroup; import nl.agilecc.agiledancers.model.DanceSchool; import nl.agilecc.agiledancers.model.Dancer; import nl.agilecc.agiledancers.model.DayPart; import nl.agilecc.agiledancers.model.Show; import nl.agilecc.agiledancers.model.specifications.DanceGroupStyle; import nl.agilecc.agiledancers.model.specifications.DayPartType; import nl.agilecc.agiledancers.rest.apimodel.GroupView; import nl.agilecc.agiledancers.rest.apimodel.SchoolView; import nl.agilecc.agiledancers.rest.apimodel.ShowView; import nl.agilecc.agiledancers.rest.mapping.DomainViewMapper; import org.junit.jupiter.api.Test; @QuarkusTest class DomainViewMapperTest { private @Inject DomainViewMapper views; public @Test void relationshipsBecomeOrderedIdsAndUnlinkedCoachesRetainNull() { final DanceSchool school = DanceSchool.builder().name("School").revision(4).build(); school.setId(7L); final Dancer first = dancer(9L); final Dancer second = dancer(3L); school.addDancer(first); school.addDancer(second); final SchoolView mapped = views.school(school); assertEquals(List.of(9L, 3L), mapped.dancerIds()); assertEquals(4, mapped.revision()); final Coach coach = Coach.builder().name("Coach").dancer(first).build(); coach.setId(2L); assertEquals(9L, views.coach(coach).dancerId()); coach.setDancer(null); assertNull(views.coach(coach).dancerId()); school.removeDancer(first); assertEquals(List.of(9L, 3L), mapped.dancerIds()); assertThrows( UnsupportedOperationException.class, () -> mapped.dancerIds().clear()); } public @Test void nestedViewsKeepAssignmentOrderAndExplicitValidationWithoutSharingCollections() { final DanceGroup first = DanceGroup.builder().category("First").build(); first.setId(8L); final DanceGroup second = DanceGroup.builder().category("Second").build(); second.setId(2L); final List assigned = new ArrayList<>(List.of(first, second)); final DayPart part = DayPart.builder() .date(LocalDate.of(2027, 1, 1)) .type(DayPartType.MORNING) .danceGroups(assigned) .build(); final List violations = new ArrayList<>(List.of("Draft validation")); final Show show = Show.builder() .name("Show") .dayParts(new ArrayList<>(List.of(part))) .appearances(Map.of()) .build(); show.setId(1L); final ShowView mapped = views.show(show, violations); assertEquals(1, mapped.preferredDayParts()); assertEquals(List.of(8L, 2L), mapped.dayParts().getFirst().danceGroupIds()); assigned.clear(); violations.clear(); show.getDayParts().clear(); assertEquals(List.of(8L, 2L), mapped.dayParts().getFirst().danceGroupIds()); assertEquals(List.of("Draft validation"), mapped.violations()); assertThrows( UnsupportedOperationException.class, () -> mapped.dayParts().getFirst().danceGroupIds().clear()); } public @Test void preferredDefaultsUseTheExistingRuleAndStylesAreSnapshotValues() { final DayPart part = DayPart.builder() .date(LocalDate.of(2027, 1, 1)) .type(DayPartType.MORNING) .danceGroups(List.of()) .build(); final Show show = Show.builder() .dayParts(List.of(part, part)) .appearances(Map.of()) .build(); show.setId(1L); assertEquals(2, views.show(show, List.of()).preferredDayParts()); show.setPreferredDayParts(1); assertEquals(1, views.show(show, List.of()).preferredDayParts()); final DanceGroup group = DanceGroup.builder().category("Group").build(); group.setId(1L); group.addStyle(DanceGroupStyle.JAZZ); final Dancer dancer = dancer(4L); group.addDancer(dancer); final GroupView mapped = views.group(group); group.replaceStyles(Set.of(DanceGroupStyle.MODERN)); group.removeDancer(dancer); assertEquals(Set.of(DanceGroupStyle.JAZZ), mapped.styles()); assertEquals(List.of(4L), mapped.dancerIds()); } private static Dancer dancer(final long id) { final Dancer dancer = Dancer.builder() .name("Dancer") .birthDate(LocalDate.of(2000, 1, 1)) .build(); dancer.setId(id); return dancer; } }