Files
dognation_BT/src/test/java/com/dog/dognation/scheduler/MatchQuotaSchedulerTest.java
T

90 lines
3.5 KiB
Java
Raw Normal View History

package com.dog.dognation.scheduler;
import com.dog.dognation.domain.matching.DailyMatchQuota;
import com.dog.dognation.domain.matching.DailyMatchQuotaRepository;
import com.dog.dognation.domain.matching.MatchQuotaService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* 자정 매칭 쿼터 초기화 스케줄러 검증.
* 실제 스케줄러 빈 -> 서비스 -> 리포지토리(JPQL 벌크 UPDATE) 경로를 그대로 실행한다.
*/
@SpringBootTest
class MatchQuotaSchedulerTest {
@Autowired MatchQuotaScheduler scheduler;
@Autowired MatchQuotaService quotaService;
@Autowired DailyMatchQuotaRepository quotaRepository;
@Autowired JdbcTemplate jdbc;
private long freeUserId;
private long adFreeUserId;
private long premiumUserId;
@BeforeEach
void setUp() {
jdbc.update("DELETE FROM daily_match_quota");
jdbc.update("DELETE FROM users");
// 잔여 0으로 소진된 상태를 만들어 초기화가 실제로 일어나는지 관찰
freeUserId = seedUser("free@dog.com", "FREE", 0);
adFreeUserId = seedUser("adfree@dog.com", "AD_FREE", 0);
premiumUserId = seedUser("premium@dog.com", "PREMIUM", 0);
}
@Test
@DisplayName("자정 배치: FREE/AD_FREE 는 3으로 초기화, PREMIUM 은 손대지 않는다")
void reset_resetsNonPremiumOnly() {
scheduler.resetDailyMatchQuota();
assertThat(remaining(freeUserId)).isEqualTo(3);
assertThat(remaining(adFreeUserId)).isEqualTo(3);
assertThat(remaining(premiumUserId)).isEqualTo(0); // PREMIUM 은 배치 대상 아님(무제한)
}
@Test
@DisplayName("초기화 대상(비 PREMIUM) 행 수를 정확히 반환한다")
void reset_returnsAffectedRowCount() {
int updated = quotaService.resetAll();
assertThat(updated).isEqualTo(2); // FREE + AD_FREE
}
@Test
@DisplayName("소진 로직: 3회까지 차감되고 이후 신청은 차단된다")
void consume_blocksAfterLimit() {
// 쿼터 행이 3으로 초기화된 상태에서 시작
scheduler.resetDailyMatchQuota();
assertThat(quotaService.consumeOne(freeUserId)).isTrue(); // 3 -> 2
assertThat(quotaService.consumeOne(freeUserId)).isTrue(); // 2 -> 1
assertThat(quotaService.consumeOne(freeUserId)).isTrue(); // 1 -> 0
assertThat(quotaService.consumeOne(freeUserId)).isFalse(); // 0 -> 차단
assertThat(remaining(freeUserId)).isEqualTo(0);
}
// --- helpers ---
private long seedUser(String email, String tier, int remaining) {
jdbc.update("""
INSERT INTO users(email, password_hash, nickname, subscription_tier, status, created_at, updated_at)
VALUES (?, 'x', ?, ?, 'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
""", email, email, tier);
Long id = jdbc.queryForObject("SELECT id FROM users WHERE email = ?", Long.class, email);
quotaRepository.save(new DailyMatchQuota(id, remaining, java.time.LocalDate.now()));
return id;
}
private int remaining(long userId) {
Integer r = jdbc.queryForObject(
"SELECT remaining_count FROM daily_match_quota WHERE user_id = ?", Integer.class, userId);
return r == null ? -1 : r;
}
}