package com.mydreamjob.auth; import com.mydreamjob.config.AppJwtProperties; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; /** * S02 Refresh Token 摘要(设计 D07 / 第八节)。 * *

只验证确定性、长度与常量时间比较的语义;不依赖 Spring 上下文。

*/ class AuthTokenHasherTest { private static final String HASH_SECRET = "test-token-hash-secret-key-for-unit-tests-only-not-for-production"; private static final String OTHER_SECRET = "another-token-hash-secret-key-for-unit-tests-only-not-for-prod"; private static AuthTokenHasher hasher(String secret) { AppJwtProperties p = new AppJwtProperties(); p.setAccessSecret("test-access-secret-key-for-unit-tests-only-not-for-production"); p.setRefreshSecret("test-refresh-secret-key-for-unit-tests-only-not-for-production"); p.setTokenHashSecret(secret); return new AuthTokenHasher(p); } @Test void hashIsStableForSameInput() { AuthTokenHasher hasher = hasher(HASH_SECRET); String a = hasher.hash("refresh-token-value"); String b = hasher.hash("refresh-token-value"); assertEquals(a, b, "同一输入必须得到同一摘要"); } @Test void hashIsFixedLengthLowercaseHex() { String hash = hasher(HASH_SECRET).hash("refresh-token-value"); assertEquals(64, hash.length(), "HmacSHA256 十六进制摘要固定 64 字符"); assertTrue(hash.matches("[0-9a-f]{64}"), "必须是规范小写十六进制"); } @Test void differentInputsProduceDifferentHashes() { AuthTokenHasher hasher = hasher(HASH_SECRET); assertNotEquals(hasher.hash("token-a"), hasher.hash("token-b")); } @Test void differentSecretsProduceDifferentHashes() { String a = hasher(HASH_SECRET).hash("same-input"); String b = hasher(OTHER_SECRET).hash("same-input"); assertNotEquals(a, b, "摘要必须依赖密钥,不能是无密钥裸摘要"); } @Test void nullAndEmptyAreHandledDeterministically() { AuthTokenHasher hasher = hasher(HASH_SECRET); assertEquals(hasher.hash(""), hasher.hash(null)); } @Test void matchesIsConstantTimeComparisonSemantics() { AuthTokenHasher hasher = hasher(HASH_SECRET); String hash = hasher.hash("value"); assertTrue(hasher.matches(hash, hash)); assertFalse(hasher.matches(hash, hasher.hash("other"))); assertFalse(hasher.matches(hash, null)); assertFalse(hasher.matches(null, hash)); } }