You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
3.0 KiB
86 lines
3.0 KiB
package com.mydreamjob.auth;
|
|
|
|
import org.junit.jupiter.api.AfterEach;
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.boot.test.context.SpringBootTest;
|
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
import org.springframework.data.redis.core.ValueOperations;
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
import org.springframework.test.context.ActiveProfiles;
|
|
|
|
import java.sql.Timestamp;
|
|
import java.time.Instant;
|
|
import java.time.LocalDateTime;
|
|
import java.time.ZoneId;
|
|
import java.util.Set;
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.when;
|
|
|
|
/** Independent S02 acceptance reproduction for persisted timestamp consistency. */
|
|
@SpringBootTest
|
|
@ActiveProfiles("integration-test")
|
|
class S02IndependentClockAcceptanceTest {
|
|
|
|
private static final AtomicLong PHONE_SEQ = new AtomicLong(9800);
|
|
private static final Instant CAPTURED_NOW = Instant.parse("2026-01-02T03:04:05Z");
|
|
private static final ZoneId ZONE = ZoneId.of("Asia/Shanghai");
|
|
|
|
@MockBean
|
|
private RedisTemplate<String, Object> redisTemplate;
|
|
|
|
@Autowired
|
|
private UserRepository userRepository;
|
|
|
|
@Autowired
|
|
private AuthSessionService authSessionService;
|
|
|
|
@Autowired
|
|
private JdbcTemplate jdbcTemplate;
|
|
|
|
private Long userId;
|
|
|
|
@BeforeEach
|
|
@SuppressWarnings("unchecked")
|
|
void setUp() {
|
|
ValueOperations<String, Object> operations = mock(ValueOperations.class);
|
|
when(redisTemplate.opsForValue()).thenReturn(operations);
|
|
|
|
userId = userRepository.save(User.builder()
|
|
.phone("12" + String.format("%09d", PHONE_SEQ.incrementAndGet()))
|
|
.nickname("S02 independent clock")
|
|
.role(User.Role.STUDENT)
|
|
.roles(Set.of(User.Role.STUDENT))
|
|
.active(true)
|
|
.verified(true)
|
|
.build()).getId();
|
|
}
|
|
|
|
@AfterEach
|
|
void tearDown() {
|
|
if (userId != null) {
|
|
jdbcTemplate.update("DELETE FROM audit_logs WHERE user_id = ?", userId);
|
|
jdbcTemplate.update("DELETE FROM auth_tokens WHERE user_id = ?", userId);
|
|
userRepository.deleteById(userId);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void persistedTokenCreatedAtMustUseCapturedNow() {
|
|
AuthSessionService.SessionTokens tokens = authSessionService.createSession(
|
|
userRepository.findById(userId).orElseThrow(), CAPTURED_NOW, null);
|
|
|
|
Timestamp createdAt = jdbcTemplate.queryForObject(
|
|
"SELECT created_at FROM auth_tokens WHERE session_id = ?",
|
|
Timestamp.class,
|
|
tokens.sessionId());
|
|
|
|
assertThat(createdAt.toLocalDateTime())
|
|
.isEqualTo(LocalDateTime.ofInstant(CAPTURED_NOW, ZONE));
|
|
}
|
|
}
|
|
|