Files
hnh-map/internal/app/services/admin_test.go
Nikolay Tatarinov 761fbaed55 Refactor Docker and Makefile configurations for improved build processes
- Updated docker-compose.tools.yml to mount source code at /src and set working directory for backend tools, ensuring proper Go module caching.
- Modified Dockerfile.tools to install the latest golangci-lint version compatible with Go 1.24 and adjusted working directory for build-time operations.
- Enhanced Makefile to build backend tools before running tests and linting, ensuring dependencies are up-to-date and improving overall workflow efficiency.
- Refactored test and handler files to include error handling for database operations, enhancing reliability and debugging capabilities.
2026-03-04 13:59:00 +03:00

309 lines
7.2 KiB
Go

package services_test
import (
"context"
"testing"
"github.com/andyleap/hnh-map/internal/app"
"github.com/andyleap/hnh-map/internal/app/services"
"github.com/andyleap/hnh-map/internal/app/store"
"go.etcd.io/bbolt"
)
func newTestAdmin(t *testing.T) (*services.AdminService, *store.Store) {
t.Helper()
db := newTestDB(t)
st := store.New(db)
mapSvc := services.NewMapService(services.MapServiceDeps{
Store: st,
GridStorage: t.TempDir(),
GridUpdates: &app.Topic[app.TileData]{},
})
return services.NewAdminService(st, mapSvc), st
}
func TestListUsers_Empty(t *testing.T) {
admin, _ := newTestAdmin(t)
users, err := admin.ListUsers(context.Background())
if err != nil {
t.Fatal(err)
}
if len(users) != 0 {
t.Fatalf("expected 0 users, got %d", len(users))
}
}
func TestListUsers_WithUsers(t *testing.T) {
admin, st := newTestAdmin(t)
ctx := context.Background()
createUser(t, st, "alice", "pass", nil)
createUser(t, st, "bob", "pass", nil)
users, err := admin.ListUsers(ctx)
if err != nil {
t.Fatal(err)
}
if len(users) != 2 {
t.Fatalf("expected 2 users, got %d", len(users))
}
}
func TestAdminGetUser_Found(t *testing.T) {
admin, st := newTestAdmin(t)
createUser(t, st, "alice", "pass", app.Auths{app.AUTH_MAP, app.AUTH_UPLOAD})
auths, found, err := admin.GetUser(context.Background(), "alice")
if err != nil || !found {
t.Fatalf("expected found, err=%v", err)
}
if !auths.Has(app.AUTH_MAP) {
t.Fatal("expected map auth")
}
}
func TestAdminGetUser_NotFound(t *testing.T) {
admin, _ := newTestAdmin(t)
_, found, err := admin.GetUser(context.Background(), "ghost")
if err != nil {
t.Fatal(err)
}
if found {
t.Fatal("expected not found")
}
}
func TestCreateOrUpdateUser_New(t *testing.T) {
admin, _ := newTestAdmin(t)
ctx := context.Background()
_, err := admin.CreateOrUpdateUser(ctx, "bob", "secret", app.Auths{app.AUTH_MAP})
if err != nil {
t.Fatal(err)
}
auths, found, err := admin.GetUser(ctx, "bob")
if err != nil || !found {
t.Fatalf("expected user to exist, err=%v", err)
}
if !auths.Has(app.AUTH_MAP) {
t.Fatal("expected map auth")
}
}
func TestCreateOrUpdateUser_Update(t *testing.T) {
admin, st := newTestAdmin(t)
ctx := context.Background()
createUser(t, st, "alice", "old", app.Auths{app.AUTH_MAP})
_, err := admin.CreateOrUpdateUser(ctx, "alice", "new", app.Auths{app.AUTH_ADMIN, app.AUTH_MAP})
if err != nil {
t.Fatal(err)
}
auths, found, err := admin.GetUser(ctx, "alice")
if err != nil || !found {
t.Fatalf("expected user, err=%v", err)
}
if !auths.Has(app.AUTH_ADMIN) {
t.Fatal("expected admin auth after update")
}
}
func TestCreateOrUpdateUser_AdminBootstrap(t *testing.T) {
admin, _ := newTestAdmin(t)
ctx := context.Background()
adminCreated, err := admin.CreateOrUpdateUser(ctx, "admin", "pass", app.Auths{app.AUTH_ADMIN})
if err != nil {
t.Fatal(err)
}
if !adminCreated {
t.Fatal("expected adminCreated=true for new admin user")
}
adminCreated, err = admin.CreateOrUpdateUser(ctx, "admin", "pass2", app.Auths{app.AUTH_ADMIN})
if err != nil {
t.Fatal(err)
}
if adminCreated {
t.Fatal("expected adminCreated=false for existing admin user")
}
}
func TestDeleteUser(t *testing.T) {
admin, st := newTestAdmin(t)
ctx := context.Background()
createUser(t, st, "alice", "pass", app.Auths{app.AUTH_UPLOAD})
auth := services.NewAuthService(st)
auth.GenerateTokenForUser(ctx, "alice")
if err := admin.DeleteUser(ctx, "alice"); err != nil {
t.Fatal(err)
}
_, found, err := admin.GetUser(ctx, "alice")
if err != nil || found {
t.Fatalf("expected user to be deleted, err=%v", err)
}
}
func TestGetSettings_Defaults(t *testing.T) {
admin, _ := newTestAdmin(t)
prefix, defaultHide, title, err := admin.GetSettings(context.Background())
if err != nil {
t.Fatal(err)
}
if prefix != "" || defaultHide || title != "" {
t.Fatalf("expected empty defaults, got prefix=%q defaultHide=%v title=%q", prefix, defaultHide, title)
}
}
func TestUpdateSettings(t *testing.T) {
admin, _ := newTestAdmin(t)
ctx := context.Background()
p := "pfx"
dh := true
ti := "My Map"
if err := admin.UpdateSettings(ctx, &p, &dh, &ti); err != nil {
t.Fatal(err)
}
prefix, defaultHide, title, err := admin.GetSettings(ctx)
if err != nil {
t.Fatal(err)
}
if prefix != "pfx" {
t.Fatalf("expected pfx, got %s", prefix)
}
if !defaultHide {
t.Fatal("expected defaultHide=true")
}
if title != "My Map" {
t.Fatalf("expected My Map, got %s", title)
}
dh2 := false
if err := admin.UpdateSettings(ctx, nil, &dh2, nil); err != nil {
t.Fatal(err)
}
_, defaultHide2, _, _ := admin.GetSettings(ctx)
if defaultHide2 {
t.Fatal("expected defaultHide=false after update")
}
}
func TestListMaps_Empty(t *testing.T) {
admin, _ := newTestAdmin(t)
maps, err := admin.ListMaps(context.Background())
if err != nil {
t.Fatal(err)
}
if len(maps) != 0 {
t.Fatalf("expected 0 maps, got %d", len(maps))
}
}
func TestMapCRUD(t *testing.T) {
admin, _ := newTestAdmin(t)
ctx := context.Background()
if err := admin.UpdateMap(ctx, 1, "world", false, false); err != nil {
t.Fatal(err)
}
mi, found, err := admin.GetMap(ctx, 1)
if err != nil || !found || mi == nil {
t.Fatalf("expected map, err=%v", err)
}
if mi.Name != "world" {
t.Fatalf("expected world, got %s", mi.Name)
}
maps, err := admin.ListMaps(ctx)
if err != nil {
t.Fatal(err)
}
if len(maps) != 1 {
t.Fatalf("expected 1 map, got %d", len(maps))
}
}
func TestToggleMapHidden(t *testing.T) {
admin, _ := newTestAdmin(t)
ctx := context.Background()
_ = admin.UpdateMap(ctx, 1, "world", false, false)
mi, err := admin.ToggleMapHidden(ctx, 1)
if err != nil {
t.Fatal(err)
}
if !mi.Hidden {
t.Fatal("expected hidden=true after toggle")
}
mi, err = admin.ToggleMapHidden(ctx, 1)
if err != nil {
t.Fatal(err)
}
if mi.Hidden {
t.Fatal("expected hidden=false after second toggle")
}
}
func TestWipe(t *testing.T) {
admin, st := newTestAdmin(t)
ctx := context.Background()
if err := st.Update(ctx, func(tx *bbolt.Tx) error {
if err := st.PutGrid(tx, "g1", []byte("data")); err != nil {
return err
}
if err := st.PutMap(tx, 1, []byte("data")); err != nil {
return err
}
if err := st.PutTile(tx, 1, 0, "0_0", []byte("data")); err != nil {
return err
}
_, _, err := st.CreateMarkersBuckets(tx)
return err
}); err != nil {
t.Fatal(err)
}
if err := admin.Wipe(ctx); err != nil {
t.Fatal(err)
}
if err := st.View(ctx, func(tx *bbolt.Tx) error {
if st.GetGrid(tx, "g1") != nil {
t.Fatal("expected grids wiped")
}
if st.GetMap(tx, 1) != nil {
t.Fatal("expected maps wiped")
}
if st.GetTile(tx, 1, 0, "0_0") != nil {
t.Fatal("expected tiles wiped")
}
if st.GetMarkersGridBucket(tx) != nil {
t.Fatal("expected markers wiped")
}
return nil
}); err != nil {
t.Fatal(err)
}
}
func TestGetMap_NotFound(t *testing.T) {
admin, _ := newTestAdmin(t)
_, found, err := admin.GetMap(context.Background(), 999)
if err != nil {
t.Fatal(err)
}
if found {
t.Fatal("expected not found")
}
}