164 lines
5.1 KiB
Go
164 lines
5.1 KiB
Go
|
package entity
|
|||
|
|
|||
|
import (
|
|||
|
"testing"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
// TestAccessTokenExpires 測試 AccessTokenExpires 方法是否能正確將 ExpiresIn 轉換成 time.Duration(秒)
|
|||
|
func TestAccessTokenExpires(t *testing.T) {
|
|||
|
tests := []struct {
|
|||
|
name string // 測試案例名稱
|
|||
|
expiresIn int64 // 輸入的 ExpiresIn 值,單位為秒
|
|||
|
want time.Duration // 預期返回的時間間隔
|
|||
|
}{
|
|||
|
{"zero expiration", 0, 0},
|
|||
|
{"1 second expiration", 1, 1 * time.Second},
|
|||
|
{"60 seconds expiration", 60, 60 * time.Second},
|
|||
|
}
|
|||
|
|
|||
|
for _, tt := range tests {
|
|||
|
t.Run(tt.name, func(t *testing.T) {
|
|||
|
// 建立一個 Token 實例,僅設置 ExpiresIn 欄位
|
|||
|
token := Token{
|
|||
|
ExpiresIn: tt.expiresIn,
|
|||
|
}
|
|||
|
// 呼叫 AccessTokenExpires 方法
|
|||
|
got := token.AccessTokenExpires() // ex 1m0s, 1s, 0s etc ....
|
|||
|
// 檢查返回值是否與預期相符
|
|||
|
if got != tt.want {
|
|||
|
t.Errorf("AccessTokenExpires() = %v, want %v", got, tt.want)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// TestRefreshTokenExpires 測試 RefreshTokenExpires 方法是否能正確將 RefreshExpiresIn(秒)轉換成 time.Duration
|
|||
|
func TestRefreshTokenExpires(t *testing.T) {
|
|||
|
tests := []struct {
|
|||
|
name string
|
|||
|
refreshExpiresIn int64
|
|||
|
want time.Duration
|
|||
|
}{
|
|||
|
{"zero", 0, 0},
|
|||
|
{"1 second", 1, 1 * time.Second},
|
|||
|
{"60 seconds", 60, 60 * time.Second},
|
|||
|
}
|
|||
|
|
|||
|
for _, tt := range tests {
|
|||
|
t.Run(tt.name, func(t *testing.T) {
|
|||
|
token := Token{
|
|||
|
RefreshExpiresIn: tt.refreshExpiresIn,
|
|||
|
}
|
|||
|
got := token.RefreshTokenExpires()
|
|||
|
if got != tt.want {
|
|||
|
t.Errorf("RefreshTokenExpires() = %v, want %v", got, tt.want)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// TestRefreshTokenExpiresUnix 測試 RefreshTokenExpiresUnix 方法返回的 UnixNano 時間戳是否大致符合預期
|
|||
|
func TestRefreshTokenExpiresUnix(t *testing.T) {
|
|||
|
// 設定 refreshExpiresIn 為 60 秒
|
|||
|
token := Token{
|
|||
|
RefreshExpiresIn: 60,
|
|||
|
}
|
|||
|
// 取得測試開始時的時間
|
|||
|
now := time.Now()
|
|||
|
// 預期值:now + 60 秒
|
|||
|
expected := now.Add(60 * time.Second).UnixNano()
|
|||
|
got := token.RefreshTokenExpiresUnix()
|
|||
|
|
|||
|
// 設定允許誤差 50 毫秒
|
|||
|
tolerance := int64(50 * time.Millisecond)
|
|||
|
if got < expected-tolerance || got > expected+tolerance {
|
|||
|
t.Errorf("RefreshTokenExpiresUnix() = %v, want approx %v", got, expected)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// TestIsExpires 測試 IsExpires 方法判斷 token 是否過期
|
|||
|
func TestIsExpires(t *testing.T) {
|
|||
|
now := time.Now()
|
|||
|
|
|||
|
// 測試未過期:token 創建時間為現在,過期時長為 10 秒
|
|||
|
tokenValid := Token{
|
|||
|
AccessCreateAt: now.UnixNano(),
|
|||
|
ExpiresIn: 10, // 此處 ExpiresIn 為有效時長(秒)
|
|||
|
}
|
|||
|
if tokenValid.IsExpires() {
|
|||
|
t.Errorf("IsExpires() 返回 true,但 token 尚未過期")
|
|||
|
}
|
|||
|
|
|||
|
// 測試已過期:token 創建時間為 20 秒前,過期時長為 10 秒
|
|||
|
tokenExpired := Token{
|
|||
|
AccessCreateAt: now.Add(-20 * time.Second).UnixNano(),
|
|||
|
ExpiresIn: 10,
|
|||
|
}
|
|||
|
if !tokenExpired.IsExpires() {
|
|||
|
t.Errorf("IsExpires() 返回 false,但 token 已過期")
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// TestRedisExpiredSec 測試 RedisExpiredSec 方法
|
|||
|
// 此方法根據 t.ExpiresIn (UnixNano 表示的到期時間) 與當前 UTC 時間計算剩餘秒數
|
|||
|
func TestRedisExpiredSec(t *testing.T) {
|
|||
|
// 定義測試案例:
|
|||
|
// - expireOffset 為從當前時間的偏移量(正數表示未過期,負數表示已過期)
|
|||
|
// - minExpected 與 maxExpected 為允許的返回值範圍(因為執行期間會有少量延遲)
|
|||
|
tests := []struct {
|
|||
|
name string
|
|||
|
expireOffset time.Duration // token 過期時間相對於當前的偏移量
|
|||
|
minExpected int64 // 預期返回值下限(秒)
|
|||
|
maxExpected int64 // 預期返回值上限(秒)
|
|||
|
}{
|
|||
|
{"Not expired +10s", 10 * time.Second, 9, 10},
|
|||
|
{"Expired -5s", -5 * time.Second, -6, -5},
|
|||
|
}
|
|||
|
|
|||
|
for _, tt := range tests {
|
|||
|
t.Run(tt.name, func(t *testing.T) {
|
|||
|
now := time.Now().UTC()
|
|||
|
// token 的到期時間設定為當前時間加上偏移量
|
|||
|
expTime := now.Add(tt.expireOffset)
|
|||
|
token := Token{
|
|||
|
ExpiresIn: expTime.UnixNano(),
|
|||
|
}
|
|||
|
|
|||
|
got := token.RedisExpiredSec()
|
|||
|
if got < tt.minExpected || got > tt.maxExpected {
|
|||
|
t.Errorf("RedisExpiredSec() = %d, want between %d and %d", got, tt.minExpected, tt.maxExpected)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// TestRedisRefreshExpiredSec 測試 RedisRefreshExpiredSec 方法
|
|||
|
// 此方法根據 t.RefreshExpiresIn (UnixNano 表示的刷新到期時間) 與當前 UTC 時間計算剩餘秒數
|
|||
|
func TestRedisRefreshExpiredSec(t *testing.T) {
|
|||
|
tests := []struct {
|
|||
|
name string
|
|||
|
expireOffset time.Duration // 刷新 token 到期時間相對於當前的偏移量
|
|||
|
minExpected int64 // 預期返回值下限(秒)
|
|||
|
maxExpected int64 // 預期返回值上限(秒)
|
|||
|
}{
|
|||
|
{"Not expired +20s", 20 * time.Second, 19, 20},
|
|||
|
{"Expired -5s", -5 * time.Second, -6, -5},
|
|||
|
}
|
|||
|
|
|||
|
for _, tt := range tests {
|
|||
|
t.Run(tt.name, func(t *testing.T) {
|
|||
|
now := time.Now().UTC()
|
|||
|
expTime := now.Add(tt.expireOffset)
|
|||
|
token := Token{
|
|||
|
RefreshExpiresIn: expTime.UnixNano(),
|
|||
|
}
|
|||
|
|
|||
|
got := token.RedisRefreshExpiredSec()
|
|||
|
if got < tt.minExpected || got > tt.maxExpected {
|
|||
|
t.Errorf("RedisRefreshExpiredSec() = %d, want between %d and %d", got, tt.minExpected, tt.maxExpected)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
}
|