add test examples

This commit is contained in:
Pascal Fischer
2025-06-12 16:22:45 +02:00
parent f7d39754d3
commit 6d5800931e
11 changed files with 288 additions and 13 deletions
@@ -0,0 +1,48 @@
package manager
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/golang/mock/gomock"
"github.com/gorilla/mux"
nbcontext "github.com/netbirdio/netbird/management/server/context"
"github.com/stretchr/testify/require"
"github.com/netbirdio/management-refactor/internals/modules/users"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
"github.com/netbirdio/management-refactor/internals/shared/permissions/modules"
"github.com/netbirdio/management-refactor/internals/shared/permissions/operations"
)
func TestGetAllUsersReturnsUsers(t *testing.T) {
ctrl := gomock.NewController(t)
managerMock := NewMockManager(ctrl)
permissionsMock := permissions.NewMockManager(ctrl)
permissionsMock.EXPECT().WithPermission(modules.Users, operations.Read, gomock.Any()).DoAndReturn(
func(module modules.Module, operation operations.Operation, handlerFunc func(http.ResponseWriter, *http.Request, *nbcontext.UserAuth)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
handlerFunc(w, r, &nbcontext.UserAuth{UserId: "123", AccountId: "abc"})
}
}).AnyTimes()
managerMock.EXPECT().GetAllUsers(gomock.Any(), gomock.Any(), gomock.Any(), "abc").Return([]users.User{{Id: "1"}, {Id: "2"}}, nil).Times(1)
router := mux.NewRouter()
RegisterEndpoints(router, permissionsMock, managerMock)
req := httptest.NewRequest(http.MethodGet, "/users", nil)
req.Header.Set("Authorization", "Bearer token")
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
require.Equal(t, http.StatusOK, w.Code)
var response []users.User
err := json.NewDecoder(w.Body).Decode(&response)
require.NoError(t, err)
require.Len(t, response, 2)
require.Equal(t, "1", response[0].Id)
}
+10 -1
View File
@@ -1,5 +1,7 @@
package manager
//go:generate go run github.com/golang/mock/mockgen -package manager -destination=manager_mock.go -source=../interface.go -build_flags=-mod=mod
import (
"context"
@@ -20,5 +22,12 @@ func (m *Manager) GetAllUsers(ctx context.Context, tx db.Transaction, strength d
}
func (m *Manager) GetUserByID(ctx context.Context, tx db.Transaction, strength db.LockingStrength, id string) (*users.User, error) {
return m.repo.GetUserByID(tx, strength, id)
user, err := m.repo.GetUserByID(tx, strength, id)
if err != nil {
return nil, err
}
user.Issued = "****"
return user, nil
}
@@ -0,0 +1,67 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ../interface.go
// Package manager is a generated GoMock package.
package manager
import (
context "context"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
users "github.com/netbirdio/management-refactor/internals/modules/users"
db "github.com/netbirdio/management-refactor/internals/shared/db"
)
// MockManager is a mock of Manager interface.
type MockManager struct {
ctrl *gomock.Controller
recorder *MockManagerMockRecorder
}
// MockManagerMockRecorder is the mock recorder for MockManager.
type MockManagerMockRecorder struct {
mock *MockManager
}
// NewMockManager creates a new mock instance.
func NewMockManager(ctrl *gomock.Controller) *MockManager {
mock := &MockManager{ctrl: ctrl}
mock.recorder = &MockManagerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockManager) EXPECT() *MockManagerMockRecorder {
return m.recorder
}
// GetAllUsers mocks base method.
func (m *MockManager) GetAllUsers(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID string) ([]users.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAllUsers", ctx, tx, strength, accountID)
ret0, _ := ret[0].([]users.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAllUsers indicates an expected call of GetAllUsers.
func (mr *MockManagerMockRecorder) GetAllUsers(ctx, tx, strength, accountID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllUsers", reflect.TypeOf((*MockManager)(nil).GetAllUsers), ctx, tx, strength, accountID)
}
// GetUserByID mocks base method.
func (m *MockManager) GetUserByID(ctx context.Context, tx db.Transaction, strength db.LockingStrength, id string) (*users.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserByID", ctx, tx, strength, id)
ret0, _ := ret[0].(*users.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserByID indicates an expected call of GetUserByID.
func (mr *MockManagerMockRecorder) GetUserByID(ctx, tx, strength, id interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByID", reflect.TypeOf((*MockManager)(nil).GetUserByID), ctx, tx, strength, id)
}
@@ -0,0 +1,26 @@
package manager
import (
"context"
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/netbirdio/management-refactor/internals/modules/users"
"github.com/netbirdio/management-refactor/internals/shared/db"
)
func TestHideUserIssued(t *testing.T) {
ctrl := gomock.NewController(t)
repoMock := NewMockRepository(ctrl)
repoMock.EXPECT().GetUserByID(gomock.Any(), gomock.Any(), "5").Return(&users.User{Id: "5", Issued: "top secret"}, nil).AnyTimes()
manager := NewManager(repoMock)
result, err := manager.GetUserByID(context.Background(), nil, db.LockingStrengthShare, "5")
assert.NoError(t, err)
assert.Equal(t, "****", result.Issued)
}
@@ -1,5 +1,7 @@
package manager
//go:generate go run github.com/golang/mock/mockgen -package manager -destination=repository_mock.go -source=./repository.go -build_flags=-mod=mod
import (
log "github.com/sirupsen/logrus"
@@ -0,0 +1,94 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ./repository.go
// Package manager is a generated GoMock package.
package manager
import (
reflect "reflect"
gomock "github.com/golang/mock/gomock"
users "github.com/netbirdio/management-refactor/internals/modules/users"
db "github.com/netbirdio/management-refactor/internals/shared/db"
)
// MockRepository is a mock of Repository interface.
type MockRepository struct {
ctrl *gomock.Controller
recorder *MockRepositoryMockRecorder
}
// MockRepositoryMockRecorder is the mock recorder for MockRepository.
type MockRepositoryMockRecorder struct {
mock *MockRepository
}
// NewMockRepository creates a new mock instance.
func NewMockRepository(ctrl *gomock.Controller) *MockRepository {
mock := &MockRepository{ctrl: ctrl}
mock.recorder = &MockRepositoryMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder {
return m.recorder
}
// CreateUser mocks base method.
func (m *MockRepository) CreateUser(tx db.Transaction, u *users.User) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateUser", tx, u)
ret0, _ := ret[0].(error)
return ret0
}
// CreateUser indicates an expected call of CreateUser.
func (mr *MockRepositoryMockRecorder) CreateUser(tx, u interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockRepository)(nil).CreateUser), tx, u)
}
// GetAllUsers mocks base method.
func (m *MockRepository) GetAllUsers(tx db.Transaction, strength db.LockingStrength, accountID string) ([]users.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAllUsers", tx, strength, accountID)
ret0, _ := ret[0].([]users.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAllUsers indicates an expected call of GetAllUsers.
func (mr *MockRepositoryMockRecorder) GetAllUsers(tx, strength, accountID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllUsers", reflect.TypeOf((*MockRepository)(nil).GetAllUsers), tx, strength, accountID)
}
// GetUserByID mocks base method.
func (m *MockRepository) GetUserByID(tx db.Transaction, strength db.LockingStrength, id string) (*users.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserByID", tx, strength, id)
ret0, _ := ret[0].(*users.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserByID indicates an expected call of GetUserByID.
func (mr *MockRepositoryMockRecorder) GetUserByID(tx, strength, id interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByID", reflect.TypeOf((*MockRepository)(nil).GetUserByID), tx, strength, id)
}
// RunInTx mocks base method.
func (m *MockRepository) RunInTx(fn func(db.Transaction) error) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RunInTx", fn)
ret0, _ := ret[0].(error)
return ret0
}
// RunInTx indicates an expected call of RunInTx.
func (mr *MockRepositoryMockRecorder) RunInTx(fn interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunInTx", reflect.TypeOf((*MockRepository)(nil).RunInTx), fn)
}
@@ -0,0 +1,27 @@
package manager
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/netbirdio/management-refactor/internals/shared/db"
)
func TestGetUserByID(t *testing.T) {
cfg := &db.Config{
Engine: "",
PostgresDsn: "",
DataDir: "",
}
dbConn, err := db.NewDatabaseConn(context.Background(), cfg)
assert.NoError(t, err)
store := db.NewStore(context.Background(), dbConn)
repo := NewRepository(store)
result, err := repo.GetUserByID(nil, db.LockingStrengthShare, "5")
assert.NoError(t, err)
assert.Equal(t, "5", result.Id)
}
+8 -1
View File
@@ -14,12 +14,19 @@ import (
"github.com/netbirdio/management-refactor/internals/shared/api/rest"
"github.com/netbirdio/management-refactor/internals/shared/db"
"github.com/netbirdio/management-refactor/internals/shared/metrics"
"github.com/netbirdio/management-refactor/pkg/configuration"
)
func (s *BaseServer) Store() *db.Store {
return Create(s, func() *db.Store {
ctx := context.Background()
dbConn, err := db.NewDatabaseConn(ctx)
cfg, err := configuration.Parse[db.Config]()
if err != nil {
log.Fatalf("failed to parse config: %v", err)
}
dbConn, err := db.NewDatabaseConn(ctx, cfg)
if err != nil {
log.Fatalf("error while creating database connection: %s", err)
}
+1 -1
View File
@@ -1,6 +1,6 @@
package db
type config struct {
type Config struct {
Engine string `env:"NB_STORE_ENGINE" envDefault:"sqlite"`
PostgresDsn string `env:"NB_STORE_ENGINE_POSTGRES_DSN" envDefault:""`
DataDir string `env:"NB_STORE_DATA_DIR" envDefault:"/var/lib/netbird"`
+4 -9
View File
@@ -13,7 +13,6 @@ import (
"gorm.io/gorm/logger"
"github.com/netbirdio/management-refactor/internals/shared/errors"
"github.com/netbirdio/management-refactor/pkg/configuration"
)
const (
@@ -26,15 +25,11 @@ type DatabaseConn struct {
}
// NewDatabaseConn creates a new database connection based on the store engine
func NewDatabaseConn(ctx context.Context) (*DatabaseConn, error) {
cfg, err := configuration.Parse[config]()
if err != nil {
log.Fatalf("failed to parse config: %v", err)
}
func NewDatabaseConn(ctx context.Context, cfg *Config) (*DatabaseConn, error) {
log.WithContext(ctx).Infof("using %s store engine", cfg.Engine)
var db *gorm.DB
var err error
switch Engine(cfg.Engine) {
case SqliteStoreEngine:
db, err = openSQLiteDB(cfg)
@@ -76,7 +71,7 @@ func openMemoryDB() (*gorm.DB, error) {
}
// openSQLiteDB opens a new connection to a SQLite database
func openSQLiteDB(cfg *config) (*gorm.DB, error) {
func openSQLiteDB(cfg *Config) (*gorm.DB, error) {
storeStr := fmt.Sprintf("%s?cache=shared", storeSqliteFileName)
if runtime.GOOS == "windows" {
// To avoid `The process cannot access the file because it is being used by another process` on Windows
@@ -93,7 +88,7 @@ func openSQLiteDB(cfg *config) (*gorm.DB, error) {
}
// openPostgresDB opens a new connection to a Postgres database
func openPostgresDB(cfg *config) (*gorm.DB, error) {
func openPostgresDB(cfg *Config) (*gorm.DB, error) {
db, err := gorm.Open(postgres.Open(cfg.PostgresDsn), getGormConfig())
if err != nil {
return nil, err
+1 -1
View File
@@ -1,3 +1,3 @@
rootLogger=ERROR
rootLogger=TRACE
management-refactor/integrations/server=ERROR