Files

84 lines
3.8 KiB
Go
Raw Permalink Normal View History

2026-09-06 17:04:11 +08:00
package httpapi
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"data-terminal-cloud/internal/deviceauth"
"data-terminal-cloud/internal/hardwareprovision"
)
type fakeHardwareProvisioner struct {
response hardwareprovision.ProvisionResponse
err error
input hardwareprovision.ProvisionInput
}
func (f *fakeHardwareProvisioner) Provision(_ context.Context, _ deviceauth.Identity, _ string, input hardwareprovision.ProvisionInput) (hardwareprovision.ProvisionResponse, error) {
f.input = input
return f.response, f.err
}
func TestProvisionHardwareAgentCredentialHandlerReturnsNoStoreCredential(t *testing.T) {
service := &fakeHardwareProvisioner{response: hardwareprovision.ProvisionResponse{
InstanceID: "instance", ProductKey: "product", DeviceName: "device", HardwareID: "hardware",
DeviceSecret: "device-secret", CredentialRef: "credential-ref", CredentialVersion: 1,
CredentialSource: "platform_dynamic_registration", IssuedAt: time.Unix(1_700_000_000, 0).UTC(),
}}
request := httptest.NewRequest(http.MethodPost, "/device/v3/hardware-agent-credentials:provision", strings.NewReader(`{"hardware_id":"hardware"}`))
request.Header.Set("Idempotency-Key", "provision-request-123456")
request = request.WithContext(deviceauth.WithIdentity(request.Context(), deviceauth.Identity{ID: "internal", PublicID: "public", TenantID: "tenant", Status: "registered"}))
recorder := httptest.NewRecorder()
ProvisionHardwareAgentCredentialHandler(service).ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, body = %s", recorder.Code, recorder.Body.String())
}
if recorder.Header().Get("Cache-Control") != "no-store" || recorder.Header().Get("Pragma") != "no-cache" {
t.Fatalf("credential response was cacheable: headers=%v", recorder.Header())
}
var response struct {
Data hardwareprovision.ProvisionResponse `json:"data"`
}
if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil {
t.Fatal(err)
}
if response.Data.DeviceSecret != "device-secret" || service.input.HardwareID != "hardware" {
t.Fatalf("unexpected response/input: response=%+v input=%+v", response.Data, service.input)
}
}
func TestProvisionHardwareAgentCredentialHandlerMapsUnavailable(t *testing.T) {
service := &fakeHardwareProvisioner{err: hardwareprovision.ErrUnavailable}
request := httptest.NewRequest(http.MethodPost, "/device/v3/hardware-agent-credentials:provision", strings.NewReader(`{"hardware_id":"hardware"}`))
request.Header.Set("Idempotency-Key", "provision-request-123456")
request = request.WithContext(deviceauth.WithIdentity(request.Context(), deviceauth.Identity{}))
recorder := httptest.NewRecorder()
ProvisionHardwareAgentCredentialHandler(service).ServeHTTP(recorder, request)
if recorder.Code != http.StatusServiceUnavailable || !strings.Contains(recorder.Body.String(), "HARDWARE_AGENT_PROVISIONING_UNAVAILABLE") {
t.Fatalf("status = %d, body = %s", recorder.Code, recorder.Body.String())
}
}
func TestProvisionHardwareAgentCredentialHandlerRejectsHardwareMismatch(t *testing.T) {
service := &fakeHardwareProvisioner{err: hardwareprovision.ErrHardwareMismatch}
request := httptest.NewRequest(http.MethodPost, "/device/v3/hardware-agent-credentials:provision", strings.NewReader(`{"hardware_id":"hardware"}`))
request.Header.Set("Idempotency-Key", "provision-request-123456")
request = request.WithContext(deviceauth.WithIdentity(request.Context(), deviceauth.Identity{}))
recorder := httptest.NewRecorder()
ProvisionHardwareAgentCredentialHandler(service).ServeHTTP(recorder, request)
if recorder.Code != http.StatusConflict || !strings.Contains(recorder.Body.String(), "HARDWARE_AGENT_HARDWARE_MISMATCH") {
t.Fatalf("status = %d, body = %s", recorder.Code, recorder.Body.String())
}
}