I have a middleware handler function and I would like to be able to write unit tests for this function. How might I go about doing this in GoLang? I would like to be able to verify when I call to add this middleware that the context will have the user id if successfully verifying jwt token or API key. And also confirm if the right error message gets sent if I have the wrong key for some reason.
Here is the function.
// Middleware wraps the request with auth middleware
func Middleware(path string, cfg *cfg.Server, orm *orm.ORM) gin.HandlerFunc {
logger.Info("[Auth.Middleware] Applied to path: %s", path)
return gin.HandlerFunc(func(c *gin.Context) {
// Check and authenticate with api key
if a, err := parseAPIKey(c, cfg); err == nil {
user, err := findUserByAPIKey(a, orm)
if err != nil {
authError(c, ErrForbidden)
}
if user != nil {
c.Request = addToContext(c, consts.ProjectContextKeys.UserCtxKey, user)
c.Request = addUserIdToContext(c, user.ID)
logger.Debug("User authenticated via api: %s", user.ID)
}
c.Next()
} else {
if err != ErrEmptyAPIKeyHeader {
authError(c, err)
} else {
// Authenticate via JWT Token
t, err := parseToken(c, cfg)
if err != nil {
authError(c, err)
} else {
if claims, ok := t.Claims.(jwt.MapClaims); ok {
if claims["exp"] != nil {
issuer := claims["iss"].(string)
userid := claims["jti"].(string)
email := claims["sub"].(string)
if claims["aud"] != nil {
audiences := claims["aud"]
logger.Warn("\n\naudiences: %s\n\n", audiences)
}
if claims["alg"] != nil {
algo := claims["alg"].(string)
logger.Warn("\n\nalgo: %s\n\n", algo)
}
if user, err := findUserByJWT(email, issuer, userid, orm); err != nil {
authError(c, ErrForbidden)
} else {
if user != nil {
c.Request = addToContext(c, consts.ProjectContextKeys.UserCtxKey, user)
c.Request = addUserIdToContext(c, user.ID)
logger.Debug("User: %s", user.ID)
}
c.Next()
}
} else {
authError(c, ErrMissingExpField)
}
} else {
authError(c, err)
}
}
}
}
})
}
and here is me trying to figure out how to get started with the tests
func TestMiddleware(t *testing.T) {
// TODO Need to update test
t.Run("middleware api key from header", func(t *testing.T) {
findUserByAPIKey = func(apiKey string, o *orm.ORM) (*models.User, error) {
return &models.User{}, nil
}
parseAPIKey = func(c *gin.Context, sc *cfg.Server) (apiKey string, err error) {
return "api_key", nil
}
svc := &cfg.Server{}
Middleware("/test", svc, &orm.ORM{})
})
// TODO Need to update test
t.Run("middleware jwt key from header", func(t *testing.T) {
findUserByJWT = func(email, provider, userID string, o *orm.ORM) (*models.User, error) {
return &models.User{}, nil
}
parseToken = func(c *gin.Context, sc *cfg.Server) (t *jwt.Token, err error) {
return &jwt.Token{}, nil
}
svc := &cfg.Server{}
Middleware("/test", svc, &orm.ORM{})
})
}