Rename the module, proto service, and all identifiers from simple_bank/ SimpleBank to api_tmpl/ApiTmpl, and regenerate the gRPC/gateway/swagger/ mock code accordingly. - Scrub real secrets (SMTP password, auth token secret) from api.env/ api_test.env, untrack them, and add api.env.example/api_test.env.example - Remove committed build artifacts (tmp/main, tmp/build-errors.log, dbml-error.log) and gitignore them going forward - Fix Dockerfile paths (build target, migrations copy) that referenced a stale project layout - Rewrite README to match the actual cmd/ + internal/ structure and add a "using this as a template" section
115 lines
3.5 KiB
Go
115 lines
3.5 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/FernandoJVideira/api_tmpl/internal/auth"
|
|
"github.com/FernandoJVideira/api_tmpl/internal/domain/role"
|
|
mocksvc "github.com/FernandoJVideira/api_tmpl/internal/service/mock"
|
|
"github.com/FernandoJVideira/api_tmpl/pkg/testutil"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/mock/gomock"
|
|
)
|
|
|
|
func addAuth(t *testing.T, request *http.Request, tokenMaker auth.Maker, authType string, username string, role string, duration time.Duration) {
|
|
token, payload, err := tokenMaker.CreateToken(username, role, duration)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, payload)
|
|
|
|
authorizationHeader := fmt.Sprintf("%s %s", authType, token)
|
|
request.Header.Set(authHeaderKey, authorizationHeader)
|
|
}
|
|
|
|
func TestAuthMiddleware(t *testing.T) {
|
|
|
|
username := testutil.RandomOwner()
|
|
testRole := role.MemberRole
|
|
|
|
testCases := []struct {
|
|
name string
|
|
setupAuth func(t *testing.T, request *http.Request, tokenMaker auth.Maker)
|
|
checkResponse func(t *testing.T, recorder *httptest.ResponseRecorder)
|
|
}{
|
|
{
|
|
name: "OK",
|
|
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
|
|
addAuth(t, request, tokenMaker, authTypeBearer, username, testRole, time.Minute)
|
|
},
|
|
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
|
|
require.Equal(t, http.StatusOK, recorder.Code)
|
|
},
|
|
},
|
|
{
|
|
name: "NoAuthorization",
|
|
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
|
|
// Do not add any authorization header
|
|
},
|
|
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
|
|
require.Equal(t, http.StatusUnauthorized, recorder.Code)
|
|
},
|
|
},
|
|
{
|
|
name: "UnsupportedAuthType",
|
|
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
|
|
addAuth(t, request, tokenMaker, "UnsupportedAuthType", username, testRole, time.Minute)
|
|
},
|
|
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
|
|
require.Equal(t, http.StatusUnauthorized, recorder.Code)
|
|
},
|
|
},
|
|
{
|
|
name: "InvalidAuthFormat",
|
|
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
|
|
addAuth(t, request, tokenMaker, "", username, testRole, time.Minute)
|
|
},
|
|
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
|
|
require.Equal(t, http.StatusUnauthorized, recorder.Code)
|
|
},
|
|
},
|
|
{
|
|
name: "ExpiredAtToken",
|
|
setupAuth: func(t *testing.T, request *http.Request, tokenMaker auth.Maker) {
|
|
addAuth(t, request, tokenMaker, authTypeBearer, username, testRole, -time.Minute)
|
|
},
|
|
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
|
|
require.Equal(t, http.StatusUnauthorized, recorder.Code)
|
|
},
|
|
},
|
|
}
|
|
|
|
for i := range testCases {
|
|
tc := testCases[i]
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
authCtrl := gomock.NewController(t)
|
|
defer authCtrl.Finish()
|
|
|
|
authService := mocksvc.NewMockAuthService(authCtrl)
|
|
|
|
s := newTestServer(t, nil, nil, nil, authService)
|
|
|
|
authPath := "/auth"
|
|
s.router.GET(
|
|
authPath,
|
|
authMiddleware(s.tokenMaker, []string{role.AdminRole, role.MemberRole}),
|
|
func(ctx *gin.Context) {
|
|
ctx.JSON(200, gin.H{})
|
|
},
|
|
)
|
|
recorder := httptest.NewRecorder()
|
|
request, err := http.NewRequest(http.MethodGet, authPath, nil)
|
|
require.NoError(t, err)
|
|
|
|
tc.setupAuth(t, request, s.tokenMaker)
|
|
s.router.ServeHTTP(recorder, request)
|
|
tc.checkResponse(t, recorder)
|
|
})
|
|
}
|
|
}
|