package com.trafficaudit.holiday.service;
|
|
import com.trafficaudit.holiday.HolidayConstants;
|
import com.trafficaudit.holiday.HolidayNumberUtils;
|
import com.trafficaudit.holiday.entity.HolidayCalendar;
|
import com.trafficaudit.holiday.entity.HolidayPassengerFlow;
|
import com.trafficaudit.holiday.entity.HolidayVehicleFlow;
|
import com.trafficaudit.holiday.mapper.HolidayPassengerFlowMapper;
|
import com.trafficaudit.holiday.mapper.HolidayVehicleFlowMapper;
|
import org.junit.jupiter.api.Test;
|
|
import java.lang.reflect.Field;
|
import java.math.BigDecimal;
|
import java.time.LocalDate;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.when;
|
|
/**
|
* The Excel comparison base column (C) is an operator backup value only: it must never change the
|
* national/provincial ring ratio. This locks in that behaviour.
|
*/
|
class HolidayComparisonBaseTest {
|
|
@Test
|
void ringRatioUsesPreviousDayEvenWhenComparisonBaseIsStored() throws Exception {
|
HolidayConfigService configService = mock(HolidayConfigService.class);
|
HolidayPassengerFlowMapper passengerMapper = mock(HolidayPassengerFlowMapper.class);
|
HolidayVehicleFlowMapper vehicleMapper = mock(HolidayVehicleFlowMapper.class);
|
|
when(configService.coefficientOf(2026, HolidayConstants.CATEGORY_HOLIDAY)).thenReturn(new BigDecimal("2.4"));
|
when(passengerMapper.selectList(any())).thenReturn(new ArrayList<HolidayPassengerFlow>());
|
when(vehicleMapper.selectList(any())).thenReturn(vehicleRows());
|
|
HolidayStatService service = new HolidayStatService();
|
inject(service, "configService", configService);
|
inject(service, "passengerFlowMapper", passengerMapper);
|
inject(service, "vehicleFlowMapper", vehicleMapper);
|
|
List<Map<String, Object>> rows = service.buildOverviewRows(2026, HolidayConstants.TYPE_NATIONAL_DAY, calendar());
|
|
BigDecimal ringRatio = (BigDecimal) rows.get(3).get("nationalProvincialRingRatio");
|
assertEquals(ratio(new BigDecimal("322.7695"), new BigDecimal("323.7837")), ringRatio);
|
assertNotEquals(ratio(new BigDecimal("322.7695"), new BigDecimal("320.2418")), ringRatio);
|
assertEquals(new BigDecimal("320.2418"), rows.get(2).get("comparisonBase"));
|
}
|
|
@Test
|
void exportFormulaComparesPreviousRowInsteadOfComparisonBaseColumn() {
|
assertEquals("=(D6-D5)/D5", HolidayWorkbookService.ringRatioFormula(6, 5));
|
}
|
|
private static BigDecimal ratio(BigDecimal current, BigDecimal base) {
|
return HolidayNumberUtils.normalize(HolidayNumberUtils.divide(current, base).subtract(BigDecimal.ONE));
|
}
|
|
private static List<HolidayVehicleFlow> vehicleRows() {
|
List<HolidayVehicleFlow> rows = new ArrayList<>();
|
rows.add(vehicle("2026-10-03", "323.7837", "320.2418"));
|
rows.add(vehicle("2026-10-04", "322.7695", null));
|
return rows;
|
}
|
|
private static HolidayVehicleFlow vehicle(String date, String value, String base) {
|
HolidayVehicleFlow row = new HolidayVehicleFlow();
|
row.setYear(2026);
|
row.setFlowDate(LocalDate.parse(date));
|
row.setRoadCategory(HolidayConstants.ROAD_NATIONAL_PROVINCIAL);
|
row.setVehicleType(HolidayConstants.VEHICLE_MEDIUM_SMALL_PASSENGER);
|
row.setVehicleCount(new BigDecimal(value));
|
row.setComparisonBase(base == null ? null : new BigDecimal(base));
|
return row;
|
}
|
|
private static List<HolidayCalendar> calendar() {
|
List<HolidayCalendar> days = new ArrayList<>();
|
for (int i = 1; i <= 4; i++) {
|
HolidayCalendar day = new HolidayCalendar();
|
day.setYear(2026);
|
day.setHolidayType(HolidayConstants.TYPE_NATIONAL_DAY);
|
day.setDayIndex(i);
|
day.setHolidayDate(LocalDate.of(2026, 10, i));
|
days.add(day);
|
}
|
return days;
|
}
|
|
private static void inject(Object target, String field, Object value) throws Exception {
|
Field declared = target.getClass().getDeclaredField(field);
|
declared.setAccessible(true);
|
declared.set(target, value);
|
}
|
}
|