Skip to content

Commit b58a2b8

Browse files
added test for user handler
1 parent 95747c5 commit b58a2b8

File tree

5 files changed

+149
-0
lines changed

5 files changed

+149
-0
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"makefile.configureOnOpen": true
3+
}

cmd/api/test_utils.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package main
2+
3+
import (
4+
"blogsapi/internal/auth"
5+
"blogsapi/internal/store"
6+
"net/http"
7+
"net/http/httptest"
8+
"testing"
9+
10+
"go.uber.org/zap"
11+
)
12+
13+
func newTestApplication(t *testing.T) *application {
14+
t.Helper()
15+
16+
//zap.NewNop().Sugar() will prevent log happening in terminal
17+
logger := zap.NewNop().Sugar()
18+
mockStore := store.NewMockStore()
19+
testAuth := &auth.TestAuthenticator{}
20+
21+
return &application{
22+
logger: logger,
23+
store: mockStore,
24+
authenticator: testAuth,
25+
}
26+
}
27+
28+
func executeRequest(req *http.Request, mux http.Handler) *httptest.ResponseRecorder {
29+
rr := httptest.NewRecorder()
30+
mux.ServeHTTP(rr, req)
31+
return rr
32+
}
33+
34+
func checkResponseCode(t *testing.T, expected, actual int) {
35+
if expected != actual {
36+
t.Errorf("Expected response code %d. got %d", expected, actual)
37+
}
38+
}

cmd/api/users_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
"testing"
7+
)
8+
9+
func TestGetUser(t *testing.T) {
10+
app := newTestApplication(t)
11+
mux := app.mount()
12+
13+
testToken, err := app.authenticator.GenerateToken(nil)
14+
if err != nil {
15+
t.Fatal(err)
16+
}
17+
t.Run("should not allow unauthenticated requests", func(t *testing.T) {
18+
req, err := http.NewRequest(http.MethodGet, "/v1/users/1", nil)
19+
if err != nil {
20+
t.Fatal(err)
21+
}
22+
rr := executeRequest(req, mux)
23+
checkResponseCode(t, http.StatusUnauthorized, rr.Code)
24+
})
25+
26+
t.Run("should allow authenticated requests", func(t *testing.T) {
27+
req, err := http.NewRequest(http.MethodGet, "/v1/users/1", nil)
28+
if err != nil {
29+
t.Fatal(err)
30+
}
31+
32+
req.Header.Set("Authorization", "Bearer "+testToken)
33+
rr := executeRequest(req, mux)
34+
checkResponseCode(t, http.StatusOK, rr.Code)
35+
log.Println(req.Body)
36+
})
37+
38+
}

internal/auth/mocks.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package auth
2+
3+
import (
4+
"time"
5+
6+
"github.com/golang-jwt/jwt/v5"
7+
)
8+
9+
type TestAuthenticator struct{}
10+
11+
const secret = "test"
12+
13+
var testClaims = jwt.MapClaims{
14+
"aud": "test-aud",
15+
"iss": "test-aud",
16+
"sub": int64(1),
17+
"exp": time.Now().Add(time.Hour).Unix(),
18+
}
19+
20+
func (a *TestAuthenticator) GenerateToken(claims jwt.Claims) (string, error) {
21+
token := jwt.NewWithClaims(jwt.SigningMethodHS256, testClaims)
22+
23+
tokenString, _ := token.SignedString([]byte(secret))
24+
return tokenString, nil
25+
}
26+
27+
func (a *TestAuthenticator) ValidateToken(token string) (*jwt.Token, error) {
28+
return jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
29+
return []byte(secret), nil
30+
})
31+
}

internal/store/mocks.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package store
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
"time"
7+
)
8+
9+
func NewMockStore() Storage {
10+
return Storage{
11+
Users: &MockUserStore{},
12+
}
13+
}
14+
15+
type MockUserStore struct{}
16+
17+
func (m *MockUserStore) Create(ctx context.Context, tx *sql.Tx, u *User) error {
18+
return nil
19+
}
20+
21+
func (m *MockUserStore) GetByID(ctx context.Context, userID int64) (*User, error) {
22+
return &User{ID: userID}, nil
23+
}
24+
25+
func (m *MockUserStore) GetByEmail(context.Context, string) (*User, error) {
26+
return &User{}, nil
27+
}
28+
29+
func (m *MockUserStore) CreateAndInvite(ctx context.Context, user *User, token string, exp time.Duration) error {
30+
return nil
31+
}
32+
33+
func (m *MockUserStore) Activate(ctx context.Context, t string) error {
34+
return nil
35+
}
36+
37+
func (m *MockUserStore) Delete(ctx context.Context, id int64) error {
38+
return nil
39+
}

0 commit comments

Comments
 (0)