package unit import ( "context" "encoding/json" "testing" "time" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/internal/service/permission" "github.com/break/junhong_cmp_fiber/internal/store/postgres" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/middleware" "github.com/break/junhong_cmp_fiber/tests/testutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestPermissionCache_FirstCallMissSecondHit(t *testing.T) { db, rdb := testutils.SetupTestDB(t) defer testutils.TeardownTestDB(t, db, rdb) ctx := context.Background() accountStore := postgres.NewAccountStore(db, rdb) roleStore := postgres.NewRoleStore(db) permStore := postgres.NewPermissionStore(db) accountRoleStore := postgres.NewAccountRoleStore(db, rdb) rolePermStore := postgres.NewRolePermissionStore(db, rdb) permSvc := permission.New(permStore, accountRoleStore, rolePermStore, rdb) testUser := &model.Account{ Username: "testuser", Phone: "13900000001", Password: "Test@123456", UserType: constants.UserTypePlatform, Status: constants.StatusEnabled, } require.NoError(t, accountStore.Create(ctx, testUser)) testRole := &model.Role{ RoleName: "测试角色", RoleType: constants.RoleTypePlatform, Status: constants.StatusEnabled, } require.NoError(t, roleStore.Create(ctx, testRole)) testPerm := &model.Permission{ PermName: "测试权限", PermCode: "test:read", PermType: constants.PermissionTypeButton, Platform: constants.PlatformWeb, Status: constants.StatusEnabled, } require.NoError(t, permStore.Create(ctx, testPerm)) require.NoError(t, accountRoleStore.Create(ctx, &model.AccountRole{ AccountID: testUser.ID, RoleID: testRole.ID, })) require.NoError(t, rolePermStore.Create(ctx, &model.RolePermission{ RoleID: testRole.ID, PermID: testPerm.ID, })) ctx = middleware.SetUserContext(ctx, &middleware.UserContextInfo{ UserID: testUser.ID, UserType: testUser.UserType, }) cacheKey := constants.RedisUserPermissionsKey(testUser.ID) cachedData, err := rdb.Get(ctx, cacheKey).Result() assert.Error(t, err) assert.Empty(t, cachedData) hasPermission, err := permSvc.CheckPermission(ctx, testUser.ID, "test:read", constants.PlatformWeb) require.NoError(t, err) assert.True(t, hasPermission) cachedData, err = rdb.Get(ctx, cacheKey).Result() require.NoError(t, err) assert.NotEmpty(t, cachedData) type cacheItem struct { PermCode string `json:"perm_code"` Platform string `json:"platform"` } var cached []cacheItem require.NoError(t, json.Unmarshal([]byte(cachedData), &cached)) assert.Len(t, cached, 1) assert.Equal(t, "test:read", cached[0].PermCode) assert.Equal(t, constants.PlatformWeb, cached[0].Platform) hasPermission2, err := permSvc.CheckPermission(ctx, testUser.ID, "test:read", constants.PlatformWeb) require.NoError(t, err) assert.True(t, hasPermission2) } func TestPermissionCache_ExpiredAfter30Minutes(t *testing.T) { db, rdb := testutils.SetupTestDB(t) defer testutils.TeardownTestDB(t, db, rdb) ctx := context.Background() accountStore := postgres.NewAccountStore(db, rdb) roleStore := postgres.NewRoleStore(db) permStore := postgres.NewPermissionStore(db) accountRoleStore := postgres.NewAccountRoleStore(db, rdb) rolePermStore := postgres.NewRolePermissionStore(db, rdb) permSvc := permission.New(permStore, accountRoleStore, rolePermStore, rdb) testUser := &model.Account{ Username: "testuser2", Phone: "13900000002", Password: "Test@123456", UserType: constants.UserTypePlatform, Status: constants.StatusEnabled, } require.NoError(t, accountStore.Create(ctx, testUser)) testRole := &model.Role{ RoleName: "测试角色2", RoleType: constants.RoleTypePlatform, Status: constants.StatusEnabled, } require.NoError(t, roleStore.Create(ctx, testRole)) testPerm := &model.Permission{ PermName: "测试权限2", PermCode: "test:write", PermType: constants.PermissionTypeButton, Platform: constants.PlatformWeb, Status: constants.StatusEnabled, } require.NoError(t, permStore.Create(ctx, testPerm)) require.NoError(t, accountRoleStore.Create(ctx, &model.AccountRole{ AccountID: testUser.ID, RoleID: testRole.ID, })) require.NoError(t, rolePermStore.Create(ctx, &model.RolePermission{ RoleID: testRole.ID, PermID: testPerm.ID, })) ctx = middleware.SetUserContext(ctx, &middleware.UserContextInfo{ UserID: testUser.ID, UserType: testUser.UserType, }) hasPermission, err := permSvc.CheckPermission(ctx, testUser.ID, "test:write", constants.PlatformWeb) require.NoError(t, err) assert.True(t, hasPermission) cacheKey := constants.RedisUserPermissionsKey(testUser.ID) ttl, err := rdb.TTL(ctx, cacheKey).Result() require.NoError(t, err) assert.True(t, ttl > 29*time.Minute && ttl <= 30*time.Minute) }