app-cloudep-permission-server/pkg/domain/entity/token_test.go

164 lines
5.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
})
}
}