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 := admin.GetUser(context.Background(), "alice") if !found { t.Fatal("expected found") } if !auths.Has(app.AUTH_MAP) { t.Fatal("expected map auth") } } func TestAdminGetUser_NotFound(t *testing.T) { admin, _ := newTestAdmin(t) _, found := admin.GetUser(context.Background(), "ghost") 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 := admin.GetUser(ctx, "bob") if !found { t.Fatal("expected user to exist") } 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 := admin.GetUser(ctx, "alice") if !found { t.Fatal("expected user") } 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 := admin.GetUser(ctx, "alice") if found { t.Fatal("expected user to be deleted") } } 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 := admin.GetMap(ctx, 1) if !found || mi == nil { t.Fatal("expected map") } 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() st.Update(ctx, func(tx *bbolt.Tx) error { st.PutGrid(tx, "g1", []byte("data")) st.PutMap(tx, 1, []byte("data")) st.PutTile(tx, 1, 0, "0_0", []byte("data")) st.CreateMarkersBuckets(tx) return nil }) if err := admin.Wipe(ctx); err != nil { t.Fatal(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 }) } func TestGetMap_NotFound(t *testing.T) { admin, _ := newTestAdmin(t) _, found := admin.GetMap(context.Background(), 999) if found { t.Fatal("expected not found") } }