first commit

This commit is contained in:
npc0-hue
2026-07-11 14:56:10 +08:00
commit 7e05d0a4e7
660 changed files with 78119 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
package api
import (
"net/http"
"net/http/httptest"
"testing"
"browser.local/platform/domain"
"browser.local/platform/dto"
)
func TestRunControlAPIHelloHeartbeatWorkflow(t *testing.T) {
router := newTestRouter()
helloRecorder := performJSON(t, router, http.MethodPost, "/api/v1/run/control/hello", validRunControlHelloRequest())
assertStatus(t, helloRecorder, http.StatusOK)
hello := decodeBody[dto.RunControlHelloResponse](t, helloRecorder)
if !hello.Accepted || hello.SessionToken == "" || hello.RunEndpointID != "run-local" {
t.Fatalf("expected accepted hello response, got %+v", hello)
}
endpoint := getJSON[dto.RunEndpointResponse](t, router, "/api/v1/run/endpoints/run-local")
if endpoint.Status != domain.RunEndpointStatusOnline || len(endpoint.Capabilities) != 2 {
t.Fatalf("expected registered endpoint metadata, got %+v", endpoint)
}
heartbeatRecorder := performJSON(t, router, http.MethodPost, "/api/v1/run/control/heartbeat", dto.RunControlHeartbeatRequest{
RunEndpointID: "run-local",
SessionToken: hello.SessionToken,
Version: "0.1.1",
Status: domain.RunEndpointStatusOnline,
CapabilityFingerprint: "cap-v2",
Capacity: dto.RunCapacityResponse{
MaxJobs: 4,
RunningJobs: 1,
},
})
assertStatus(t, heartbeatRecorder, http.StatusOK)
heartbeat := decodeBody[dto.RunControlHeartbeatResponse](t, heartbeatRecorder)
if !heartbeat.Accepted || !heartbeat.RefreshCapabilities || heartbeat.NextHeartbeatSeconds <= 0 {
t.Fatalf("expected accepted heartbeat with refresh, got %+v", heartbeat)
}
}
func TestRunControlAPIReRegistrationRotatesToken(t *testing.T) {
router := newTestRouter()
first := decodeBody[dto.RunControlHelloResponse](t, performRunControlHello(t, router, validRunControlHelloRequest()))
request := validRunControlHelloRequest()
request.Version = "0.2.0"
second := decodeBody[dto.RunControlHelloResponse](t, performRunControlHello(t, router, request))
if second.SessionToken == first.SessionToken {
t.Fatalf("expected new session token after re-registration, got %q", second.SessionToken)
}
}
func TestRunControlAPIErrors(t *testing.T) {
router := newTestRouter()
invalid := validRunControlHelloRequest()
invalid.RegistrationToken = ""
invalid.Capacity.RunningJobs = 8
invalid.Capacity.MaxJobs = 4
invalidHello := performJSON(t, router, http.MethodPost, "/api/v1/run/control/hello", invalid)
assertErrorResponse(t, invalidHello, http.StatusBadRequest, errorCodeValidation)
hello := decodeBody[dto.RunControlHelloResponse](t, performRunControlHello(t, router, validRunControlHelloRequest()))
invalidHeartbeat := performJSON(t, router, http.MethodPost, "/api/v1/run/control/heartbeat", dto.RunControlHeartbeatRequest{
RunEndpointID: "run-local",
SessionToken: "stale-token",
Version: "0.1.1",
Status: domain.RunEndpointStatusOnline,
CapabilityFingerprint: "cap-v1",
Capacity: dto.RunCapacityResponse{MaxJobs: 4},
})
assertErrorResponse(t, invalidHeartbeat, http.StatusBadRequest, errorCodeValidation)
validHeartbeat := performJSON(t, router, http.MethodPost, "/api/v1/run/control/heartbeat", dto.RunControlHeartbeatRequest{
RunEndpointID: "run-local",
SessionToken: hello.SessionToken,
Version: "0.1.1",
Status: domain.RunEndpointStatusOnline,
CapabilityFingerprint: "cap-v1",
Capacity: dto.RunCapacityResponse{MaxJobs: 4},
})
assertStatus(t, validHeartbeat, http.StatusOK)
methodFailure := performRaw(t, router, http.MethodGet, "/api/v1/run/control/hello", "")
assertErrorResponse(t, methodFailure, http.StatusMethodNotAllowed, errorCodeMethodNotAllowed)
}
func performRunControlHello(t *testing.T, router http.Handler, request dto.RunControlHelloRequest) *httptest.ResponseRecorder {
t.Helper()
recorder := performJSON(t, router, http.MethodPost, "/api/v1/run/control/hello", request)
assertStatus(t, recorder, http.StatusOK)
return recorder
}
func validRunControlHelloRequest() dto.RunControlHelloRequest {
return dto.RunControlHelloRequest{
RegistrationToken: "registration-token",
RunEndpointID: "run-local",
DisplayName: "Local Run",
Version: "0.1.0",
Status: domain.RunEndpointStatusOnline,
Platform: "darwin/arm64",
CapabilityReport: dto.RunCapabilityReport{
Capabilities: []string{"control.hello", "control.heartbeat"},
Fingerprint: "cap-v1",
},
Capacity: dto.RunCapacityResponse{MaxJobs: 4},
}
}