Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ public AppDataUsageResDto getAppDataUsage(Long lineId, Integer month, AuthUserDe
FamilyLine familyLine = familyLineMapper.findByLineId(lineId)
.orElseThrow(() -> new ApplicationException(DataErrorCode.DATA_NOT_FOUND));

boolean isPublic = Boolean.TRUE.equals(permissionEnabled) && Boolean.TRUE.equals(familyLine.getIsPublic());
boolean canUsePrivacy = Boolean.TRUE.equals(permissionEnabled);
boolean isPublic = !canUsePrivacy || Boolean.TRUE.equals(familyLine.getIsPublic());
boolean isSelf = principal.getLineId() != null && principal.getLineId().equals(lineId);

if (!isPublic && !isSelf) {
Expand Down
104 changes: 79 additions & 25 deletions src/test/java/com/pooli/data/service/impl/DataServiceImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class DataServiceImplTest {
private DataServiceImpl dataService;

@Test
@DisplayName("월별 데이터 사용량: yearMonth가 null이면 INVALID_MONTH")
@DisplayName("월간 데이터 사용량: yearMonth가 null이면 INVALID_MONTH")
void getMonthlyDataUsage_nullMonth_throws() {
assertThatThrownBy(() -> dataService.getMonthlyDataUsage(1L, null))
.isInstanceOf(ApplicationException.class)
Expand All @@ -80,7 +80,7 @@ void getMonthlyDataUsage_nullMonth_throws() {
}

@Test
@DisplayName("월별 데이터 사용량: yearMonth 하한 미만이면 INVALID_MONTH")
@DisplayName("월간 데이터 사용량: yearMonth가 하한 미만이면 INVALID_MONTH")
void getMonthlyDataUsage_tooSmallMonth_throws() {
assertThatThrownBy(() -> dataService.getMonthlyDataUsage(1L, 100000))
.isInstanceOf(ApplicationException.class)
Expand All @@ -89,7 +89,7 @@ void getMonthlyDataUsage_tooSmallMonth_throws() {
}

@Test
@DisplayName("월별 데이터 사용량: yearMonth 상한 초과면 INVALID_MONTH")
@DisplayName("월간 데이터 사용량: yearMonth가 상한 초과면 INVALID_MONTH")
void getMonthlyDataUsage_tooLargeMonth_throws() {
assertThatThrownBy(() -> dataService.getMonthlyDataUsage(1L, 1000000))
.isInstanceOf(ApplicationException.class)
Expand All @@ -98,7 +98,7 @@ void getMonthlyDataUsage_tooLargeMonth_throws() {
}

@Test
@DisplayName("월별 데이터 사용량: month 형식이 잘못되면 INVALID_MONTH")
@DisplayName("월간 데이터 사용량: month 형식이 잘못되면 INVALID_MONTH")
void getMonthlyDataUsage_invalidMonth_throws() {
assertThatThrownBy(() -> dataService.getMonthlyDataUsage(1L, 202313))
.isInstanceOf(ApplicationException.class)
Expand All @@ -107,7 +107,7 @@ void getMonthlyDataUsage_invalidMonth_throws() {
}

@Test
@DisplayName("월별 데이터 사용량: month가 00이면 INVALID_MONTH")
@DisplayName("월간 데이터 사용량: month가 00이면 INVALID_MONTH")
void getMonthlyDataUsage_zeroMonth_throws() {
assertThatThrownBy(() -> dataService.getMonthlyDataUsage(1L, 202300))
.isInstanceOf(ApplicationException.class)
Expand All @@ -116,7 +116,7 @@ void getMonthlyDataUsage_zeroMonth_throws() {
}

@Test
@DisplayName("월별 데이터 사용량: 조회 결과 없으면 DATA_NOT_FOUND")
@DisplayName("월간 데이터 사용량: 조회 결과 없으면 DATA_NOT_FOUND")
void getMonthlyDataUsage_empty_throws() {
when(dataMapper.findRecentMonthlyUsageByLineId(1L, 202603)).thenReturn(List.of());

Expand All @@ -127,15 +127,24 @@ void getMonthlyDataUsage_empty_throws() {
}

@Test
@DisplayName("월별 데이터 사용량: 평균 계산 포함 반환")
@DisplayName("월간 데이터 사용량: 평균 계산 포함 반환")
void getMonthlyDataUsage_success_returnsAverage() {
int yearMonth = previousYearMonth();
YearMonth targetMonth = YearMonth.of(yearMonth / 100, yearMonth % 100);
YearMonth previousMonth = targetMonth.minusMonths(1);
List<MonthlyUsageDto> usages = List.of(
MonthlyUsageDto.builder().yearMonth("202603").usedAmount(100L).build(),
MonthlyUsageDto.builder().yearMonth("202602").usedAmount(300L).build()
MonthlyUsageDto.builder()
.yearMonth(targetMonth.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM")))
.usedAmount(100L)
.build(),
MonthlyUsageDto.builder()
.yearMonth(previousMonth.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM")))
.usedAmount(300L)
.build()
);
when(dataMapper.findRecentMonthlyUsageByLineId(1L, 202603)).thenReturn(usages);
when(dataMapper.findRecentMonthlyUsageByLineId(1L, yearMonth)).thenReturn(usages);

MonthlyDataUsageResDto result = dataService.getMonthlyDataUsage(1L, 202603);
MonthlyDataUsageResDto result = dataService.getMonthlyDataUsage(1L, yearMonth);

assertThat(result.getUsages()).isEqualTo(usages);
assertThat(result.getAverageAmount()).isEqualTo(200L);
Expand Down Expand Up @@ -166,17 +175,22 @@ void getAppDataUsage_familyLineNotFound_throws() {
}

@Test
@DisplayName("앱 데이터 사용량: 권한 비활성 또는 비공개면 isPublic=false 반환")
void getAppDataUsage_permissionDisabled_returnsPrivate() {
@DisplayName("앱 데이터 사용량: 권한 비활성이면 비공개 설정이어도 공개 반환")
void getAppDataUsage_permissionDisabled_returnsUsage() {
AuthUserDetails principal = principalWithLineId(2L);
List<AppDataUsageResDto.AppUsageDto> apps = List.of(
AppDataUsageResDto.AppUsageDto.builder().appName("A").usedAmount(100L).build(),
AppDataUsageResDto.AppUsageDto.builder().appName("B").usedAmount(300L).build()
);
when(permissionLineMapper.isPermissionEnabledByTitle(1L)).thenReturn(false);
when(familyLineMapper.findByLineId(1L)).thenReturn(Optional.of(familyLine(false)));
when(dataMapper.findAppDataUsageByLineIdAndMonth(1L, 202603)).thenReturn(apps);

AppDataUsageResDto result = dataService.getAppDataUsage(1L, 202603, principal);

assertThat(result.getIsPublic()).isFalse();
assertThat(result.getTotalUsedAmount()).isNull();
assertThat(result.getApps()).isNull();
assertThat(result.getIsPublic()).isTrue();
assertThat(result.getTotalUsedAmount()).isEqualTo(400L);
assertThat(result.getApps()).isEqualTo(apps);
}

@Test
Expand Down Expand Up @@ -236,7 +250,7 @@ void getDataSummary_null_throws() {
}

@Test
@DisplayName("데이터 요약: Redis 버퍼 잔여량을 합산해서 반환")
@DisplayName("데이터 요약: Redis 버퍼 잔량을 합산해서 반환")
void getDataSummary_success_returnsMergedBalances() {
YearMonth targetMonth = YearMonth.of(2026, 3);
DataBalancesResDto dto = DataBalancesResDto.builder()
Expand Down Expand Up @@ -342,22 +356,61 @@ void getDataUsage_currentMonth_returnsTotals() {
.thenReturn("25");
when(valueOperations.get("pooli:monthly_shared_usage:1:" + targetMonth.format(java.time.format.DateTimeFormatter.ofPattern("yyyyMM"))))
.thenReturn("30");
when(familySharedPoolsService.resolveFamilyMemberActualDisplay(1L)).thenReturn(
FamilyMembersResDto.FamilyMemberDto.builder()
.basicDataAmount(100L)
.remainingData(90L)
when(familySharedPoolsService.resolveFamilyMemberActualDisplay(1L))
.thenReturn(FamilyMembersResDto.FamilyMemberDto.builder()
.lineId(1)
.remainingData(95L)
.basicDataAmount(120L)
.sharedPoolTotalAmount(200L)
.sharedPoolRemainingAmount(170L)
.build()
);
.build());

DataUsageResDto result = dataService.getDataUsage(1L, yearMonth);

assertThat(result.getIsCurrentMonth()).isTrue();
assertThat(result.getPersonalUsedAmount()).isEqualTo(10L);
assertThat(result.getPersonalUsedAmount()).isEqualTo(25L);
assertThat(result.getSharedPoolUsedAmount()).isEqualTo(30L);
assertThat(result.getPersonalTotalAmount()).isEqualTo(100L);
assertThat(result.getPersonalTotalAmount()).isEqualTo(120L);
assertThat(result.getSharedPoolTotalAmount()).isEqualTo(200L);
assertThat(result.getSharedPoolRemainingAmount()).isEqualTo(170L);
}

@Test
@DisplayName("데이터 사용량: 현재 월 무제한 공유 한도면 총량 -1 유지")
void getDataUsage_currentMonth_unlimitedSharedLimit_preservesUnlimitedTotal() {
int yearMonth = currentYearMonth();
YearMonth targetMonth = YearMonth.now(ZoneId.of("Asia/Seoul"));
LocalDate today = LocalDate.now(ZoneId.of("Asia/Seoul"));
DataUsageResDto row = DataUsageResDto.builder()
.personalUsedAmount(10L)
.sharedPoolUsedAmount(20L)
.personalTotalAmount(100L)
.sharedPoolTotalAmount(200L)
.build();
when(trafficRedisRuntimePolicy.zoneId()).thenReturn(ZoneId.of("Asia/Seoul"));
when(dataMapper.findDataUsageAggregateByLineIdAndMonth(1L, yearMonth)).thenReturn(row);
when(dataMapper.findDailyTotalUsageByLineIdAndDate(1L, today)).thenReturn(15L);
when(trafficRedisKeyFactory.dailyTotalUsageKey(1L, today))
.thenReturn("pooli:daily_total_usage:1:" + today.format(java.time.format.DateTimeFormatter.BASIC_ISO_DATE));
when(trafficRedisKeyFactory.monthlySharedUsageKey(1L, targetMonth))
.thenReturn("pooli:monthly_shared_usage:1:" + targetMonth.format(java.time.format.DateTimeFormatter.ofPattern("yyyyMM")));
when(cacheStringRedisTemplate.opsForValue()).thenReturn(valueOperations);
when(valueOperations.get("pooli:daily_total_usage:1:" + today.format(java.time.format.DateTimeFormatter.BASIC_ISO_DATE)))
.thenReturn("25");
when(valueOperations.get("pooli:monthly_shared_usage:1:" + targetMonth.format(java.time.format.DateTimeFormatter.ofPattern("yyyyMM"))))
.thenReturn("30");
when(familySharedPoolsService.resolveFamilyMemberActualDisplay(1L))
.thenReturn(FamilyMembersResDto.FamilyMemberDto.builder()
.lineId(1)
.sharedPoolTotalAmount(-1L)
.sharedPoolRemainingAmount(170L)
.build());

DataUsageResDto result = dataService.getDataUsage(1L, yearMonth);

assertThat(result.getSharedPoolUsedAmount()).isEqualTo(30L);
assertThat(result.getSharedPoolTotalAmount()).isEqualTo(-1L);
assertThat(result.getSharedPoolRemainingAmount()).isEqualTo(170L);
}

@Test
Expand All @@ -378,6 +431,7 @@ void getDataUsage_notCurrentMonth_returnsNullTotals() {
assertThat(result.getIsCurrentMonth()).isFalse();
assertThat(result.getPersonalTotalAmount()).isNull();
assertThat(result.getSharedPoolTotalAmount()).isNull();
assertThat(result.getSharedPoolRemainingAmount()).isNull();
}

private static FamilyLine familyLine(boolean isPublic) {
Expand Down