gin-contrib / sessions

Gin middleware for session management
MIT License
1.46k stars 196 forks source link

panic: Key "github.com/gin-contrib/sessions" does not exist in unit test #261

Open DeNatur opened 8 months ago

DeNatur commented 8 months ago

Hi,

I try to use sessions in a unit test, but I'm facing a problem when trying to test a class, which uses "github.com/gin-contrib/sessions".

This is a stripped down version of a code which I'm trying to test:

import (
    "github.com/gin-contrib/sessions"
    "github.com/gin-gonic/gin"
)

const VALUE_KEY = "value"

func GetValueFromStore(c *gin.Context) int {
    session := sessions.Default(c)
    value := session.Get(VALUE_KEY)

    if value != nil {
        currentValue := value.(int)
        return currentValue
    }
    newValue := 0
    session.Set(VALUE_KEY, newValue)
    session.Save()
    return newValue
}

And the unit test:

import (
    "testing"

    "github.com/gin-contrib/sessions"
    "github.com/gin-contrib/sessions/memstore"
    "github.com/gin-gonic/gin"
)

func getMockContext() *gin.Context {
    gin.SetMode(gin.TestMode)
    router := gin.New()

    // Set up session store
    store := memstore.NewStore([]byte("secret"))
    router.Use(sessions.Sessions("mysession", store))
    c, _ := gin.CreateTestContext(nil)
    return c
}

func TestGetValueFromStore_NewValue(t *testing.T) {
    c := getMockContext()
    newValue := GetValueFromStore(c)
    if newValue != 0 {
        t.Error("New value is not 0")
    }
}

When running the go test -v ./... I get failure

--- FAIL: TestGetValueFromStore_NewValue (0.00s)
panic: Key "github.com/gin-contrib/sessions" does not exist [recovered]
        panic: Key "github.com/gin-contrib/sessions" does not exist
kdjomeda commented 4 months ago

Hi, This is also happening to me. I am not sure if you have found any answer to your issues. My error is as shown below


[GIN-debug] GET    /recipes                  --> distributed-application-with-gin/handlers.(*RecipesHandler).ListRecipesHandler-fm (3 handlers)
[GIN-debug] POST   /signin                   --> distributed-application-with-gin/handlers.(*AuthHandler).SignInHandleSession-fm (3 handlers)
[GIN-debug] POST   /signup                   --> distributed-application-with-gin/handlers.(*AuthHandler).SignUpHandler-fm (3 handlers)
[GIN-debug] POST   /recipes                  --> distributed-application-with-gin/handlers.(*RecipesHandler).NewRecipeHandler-fm (5 handlers)
[GIN-debug] PUT    /recipes/:id              --> distributed-application-with-gin/handlers.(*RecipesHandler).UpdateRecipeHandler-fm (5 handlers)
[GIN-debug] GET    /recipes/search           --> distributed-application-with-gin/handlers.(*RecipesHandler).SearchRecipesHandler-fm (5 handlers)
[GIN-debug] DELETE /recipes/:id              --> distributed-application-with-gin/handlers.(*RecipesHandler).DeleteRecipeHandler-fm (5 handlers)
[GIN-debug] GET    /recipes/:id              --> distributed-application-with-gin/handlers.(*RecipesHandler).GetRecipeHandler-fm (5 handlers)
[GIN-debug] POST   /refresh                  --> distributed-application-with-gin/handlers.(*AuthHandler).RefreshHandler-fm (5 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080

2024/07/14 16:16:26 [Recovery] 2024/07/14 - 16:16:26 panic recovered:
POST /signin HTTP/1.1
Host: localhost:8080
Accept: application/json, */*
Content-Length: 48
Content-Type: application/json
User-Agent: curl/8.6.0

Key "github.com/gin-contrib/sessions" does not exist
/Users/joseph/Tutorials/distributed-application-with-gin/vendor/github.com/gin-gonic/gin/context.go:284 (0x10298273b)
        (*Context).MustGet: panic("Key \"" + key + "\" does not exist")
/Users/joseph/Tutorials/distributed-application-with-gin/vendor/github.com/gin-contrib/sessions/sessions.go:146 (0x10298268c)
        Default: return c.MustGet(DefaultKey).(Session)
/Users/joseph/Tutorials/distributed-application-with-gin/handlers/auth.go:117 (0x102ad41e3)
        (*AuthHandler).SignInHandleSession: session := sessions.Default(c)
/Users/joseph/Tutorials/distributed-application-with-gin/vendor/github.com/gin-gonic/gin/context.go:185 (0x10297ce03)
        (*Context).Next: c.handlers[c.index](c)
/Users/joseph/Tutorials/distributed-application-with-gin/vendor/github.com/gin-gonic/gin/recovery.go:102 (0x10297cde4)
        CustomRecoveryWithWriter.func1: c.Next()
/Users/joseph/Tutorials/distributed-application-with-gin/vendor/github.com/gin-gonic/gin/context.go:185 (0x10297c167)
        (*Context).Next: c.handlers[c.index](c)
/Users/joseph/Tutorials/distributed-application-with-gin/vendor/github.com/gin-gonic/gin/logger.go:249 (0x10297c144)
        LoggerWithConfig.func1: c.Next()
/Users/joseph/Tutorials/distributed-application-with-gin/vendor/github.com/gin-gonic/gin/context.go:185 (0x10297b5a3)
        (*Context).Next: c.handlers[c.index](c)
/Users/joseph/Tutorials/distributed-application-with-gin/vendor/github.com/gin-gonic/gin/gin.go:633 (0x10297b12c)
        (*Engine).handleHTTPRequest: c.Next()
/Users/joseph/Tutorials/distributed-application-with-gin/vendor/github.com/gin-gonic/gin/gin.go:589 (0x10297ae73)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/opt/homebrew/opt/go/libexec/src/net/http/server.go:3142 (0x102835cbb)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/opt/homebrew/opt/go/libexec/src/net/http/server.go:2044 (0x1028326a7)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/opt/homebrew/opt/go/libexec/src/runtime/asm_arm64.s:1222 (0x10263a953)
        goexit: MOVD    R0, R0  // NOP

[GIN] 2024/07/14 - 16:16:26 | 500 |   18.925292ms |             ::1 | POST     "/signin"

here is a stripped down version of my main.go

import(
    "github.com/gin-contrib/sessions"
    storeInRedis "github.com/gin-contrib/sessions/redis"
)

func main() {
    router := gin.Default()
    router.GET("/recipes", recipesHandler.ListRecipesHandler)
    //router.POST("/signin", authHandler.SignInHandler)
    router.POST("/signin", authHandler.SignInHandleSession)
    router.POST("/signup", authHandler.SignUpHandler)

    store, _ := storeInRedis.NewStore(10, "tcp", os.Getenv("REDIS_URI"), "", []byte("secret"))
    router.Use(sessions.Sessions("recipes_api", store))
// ...

}

the auth.go where the authHandler is

func (handler *AuthHandler) SignInHandleSession(c *gin.Context) {
    var user models.User
    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    h := sha256.New()
    cur := handler.collection.FindOne(handler.ctx, bson.M{
        "username": user.Username,
        "password": string(h.Sum([]byte(user.Password))),
    })
    if cur.Err() != nil {
        c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"})
        return
    }
    sessionToken := xid.New().String()
    session := sessions.Default(c) //==> DefaultKey which is "github.com/gin-contrib/sessions"
    session.Set("username", user.Username)
    session.Set("token", sessionToken)
    session.Save()
    c.JSON(http.StatusOK, gin.H{"message": "User signed in"})
}

I have cross checked there is no usage of github.com/gin-gonic/contrib/sessions

ilhamefo commented 1 week ago

Any update on this issue? I have similar issue when creating test