package handlers import ( "net/http" "net/http/httptest" "path/filepath" "strings" "testing" "teraclone/internal/service" ) func TestDashboardRendersLiveMetricPlaceholdersAndAccessiblePortFilters(t *testing.T) { app, err := service.NewAppService(filepath.Join(t.TempDir(), "frontend.db")) if err != nil { t.Fatal(err) } defer app.Close() handler, err := NewDeviceHandler(app, "http://127.0.0.1:1") if err != nil { t.Fatal(err) } mux := http.NewServeMux() handler.RegisterRoutes(mux) for _, role := range []string{"administrator", "port_operator"} { t.Run(role, func(t *testing.T) { handler.sessions[role] = browserSession{Username: "test", BackendToken: "test-token", Role: role} request := httptest.NewRequest(http.MethodGet, "/", nil) request.AddCookie(&http.Cookie{Name: sessionCookieName, Value: role}) response := httptest.NewRecorder() mux.ServeHTTP(response, request) if response.Code != http.StatusOK { t.Fatalf("dashboard status = %d", response.Code) } body := response.Body.String() for _, required := range []string{"data-dashboard", `data-dashboard-value="cpu" data-i18n-skip>—`, `data-port-filter="all" aria-pressed="true"`, `data-port-filter="unknown"`, `role="status"`, "dashboard.js?v=20260907-storage-logs-1", "미확인은 아직 장비 응답", "실시간 속도가 아닙니다."} { if !strings.Contains(body, required) { t.Errorf("missing dashboard element: %s", required) } } if got := strings.Count(body, `data-dashboard-port="`); got != 48 { t.Errorf("port tile count = %d, want 48", got) } for _, required := range []string{`data-metric="storage"`, `data-dashboard-value="storage-detail"`, "사용 가능 공간", "RAM 사용률", "저장공간과 RAM은 별개"} { if !strings.Contains(body, required) { t.Errorf("missing storage UI: %s", required) } } if strings.Contains(body, `data-metric="memory"`) { t.Fatal("RAM still occupies the main storage card") } for _, fabricated := range []string{"N010-0020-2609-0062", "53.8°C", "RMM4027N850000026090062"} { if strings.Contains(body, fabricated) { t.Errorf("dashboard exposed mock data before fetching live metrics: %s", fabricated) } } }) } }