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()) } }