package api import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" "crypto-miner-server/internal/db" "crypto-miner-server/internal/models" ) func TestAgentBeaconFleetSecretAuth(t *testing.T) { resetAuthState(t) const secret = "beacon-test-secret" SetAgentPathSecret(secret) database, err := db.New(t.TempDir()) if err != nil { t.Fatal(err) } defer database.Close() hub := NewWSHub(database) hub.SetFleetSecret(secret) body, _ := json.Marshal(map[string]interface{}{ "agent_id": "agent-beacon-1", "stats": map[string]interface{}{ "hashrate_15s": 100.0, "hashrate_1m": 100.0, "hashrate_15m": 100.0, }, }) h := basicAuthMiddleware(http.HandlerFunc(hub.HandleAgentBeacon)) req := httptest.NewRequest(http.MethodPost, "/api/v1/agent/beacon", bytes.NewReader(body)) rec := httptest.NewRecorder() h.ServeHTTP(rec, req) if rec.Code != http.StatusForbidden { t.Fatalf("missing secret: got %d", rec.Code) } req.Header.Set("X-Fleet-Secret", secret) rec = httptest.NewRecorder() h.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("valid secret: got %d body=%s", rec.Code, rec.Body.String()) } var resp beaconResponse if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil { t.Fatal(err) } if !resp.OK { t.Fatal("expected ok") } } func TestBeaconCommandQueueRoundtrip(t *testing.T) { database, err := db.New(t.TempDir()) if err != nil { t.Fatal(err) } defer database.Close() _ = database.UpsertAgent(&models.Agent{ID: "q-agent", Name: "host", Status: "offline"}) hub := NewWSHub(database) hub.MarkBeaconSeen("q-agent") if !hub.EnqueueBeaconCommand("q-agent", "pause", nil) { t.Fatal("enqueue failed") } cmds := hub.dequeueBeaconCommands("q-agent") if len(cmds) != 1 || cmds[0].Action != "pause" { t.Fatalf("commands: %+v", cmds) } if len(hub.dequeueBeaconCommands("q-agent")) != 0 { t.Fatal("queue should be empty") } } func TestAgentBeaconReturnsQueuedCommands(t *testing.T) { resetAuthState(t) const secret = "beacon-cmd-secret" SetAgentPathSecret(secret) database, err := db.New(t.TempDir()) if err != nil { t.Fatal(err) } defer database.Close() _ = database.UpsertAgent(&models.Agent{ID: "cmd-agent", Name: "pc", Status: "offline"}) hub := NewWSHub(database) hub.MarkBeaconSeen("cmd-agent") _ = hub.EnqueueBeaconCommand("cmd-agent", "resume", nil) body, _ := json.Marshal(map[string]string{"agent_id": "cmd-agent"}) h := basicAuthMiddleware(http.HandlerFunc(hub.HandleAgentBeacon)) req := httptest.NewRequest(http.MethodPost, "/api/v1/agent/beacon", bytes.NewReader(body)) req.Header.Set("X-Fleet-Secret", secret) rec := httptest.NewRecorder() h.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("beacon: %d %s", rec.Code, rec.Body.String()) } var resp beaconResponse if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil { t.Fatal(err) } if len(resp.Commands) != 1 || resp.Commands[0].Action != "resume" { t.Fatalf("commands: %+v", resp.Commands) } }