package httpapi import ( "context" "errors" "fmt" "net/http" "net/http/httptest" "strings" "testing" "time" "data-terminal-cloud/internal/deviceauth" "data-terminal-cloud/internal/devicereset" ) type fakeDeviceFactoryResetService struct { response devicereset.Response replayed bool err error calls int } func validDeviceFactoryResetBody() string { return fmt.Sprintf(`{"reset_id":"10000000-0000-0000-0000-000000000901","reset_counter":2,"occurred_at":%q,"trigger":"physical_long_press","firmware_version":"1.1.0","pending_turn_count":0}`, time.Now().UTC().Format(time.RFC3339)) } func (f *fakeDeviceFactoryResetService) Reset(_ context.Context, _ deviceauth.Identity, _ string, _ string, _ []byte, _ devicereset.Input) (devicereset.Response, bool, error) { f.calls++ return f.response, f.replayed, f.err } func TestDeviceFactoryResetHandlerReturnsClaimableState(t *testing.T) { service := &fakeDeviceFactoryResetService{replayed: true, response: devicereset.Response{ ResetID: "10000000-0000-0000-0000-000000000901", DeviceID: "10000000-0000-0000-0000-000000000512", ActivationState: "CLAIMABLE", ResetCounter: 2, BindingRemoved: true, ProviderCredentialStatus: "SUSPENDED", LicenseAction: "RETAINED", Claim: &devicereset.Claim{Code: "ABCD-EFGH-IJKL-MNOP", IssuedAt: time.Now().UTC(), ExpiresAt: time.Now().UTC().Add(24 * time.Hour)}, }} body := validDeviceFactoryResetBody() request := httptest.NewRequest(http.MethodPost, "/device/v3/factory-reset", strings.NewReader(body)) request.Header.Set("Idempotency-Key", "factory-reset-key-0001") request = request.WithContext(deviceauth.WithIdentity(request.Context(), deviceauth.Identity{PublicID: "10000000-0000-0000-0000-000000000512"})) recorder := httptest.NewRecorder() DeviceFactoryResetHandler(service).ServeHTTP(recorder, request) if recorder.Code != http.StatusOK || service.calls != 1 || recorder.Header().Get("Idempotency-Replayed") != "true" || !strings.Contains(recorder.Body.String(), `"activation_state":"CLAIMABLE"`) || !strings.Contains(recorder.Body.String(), `"code":"ABCD-EFGH-IJKL-MNOP"`) { t.Fatalf("status=%d calls=%d headers=%v body=%s", recorder.Code, service.calls, recorder.Header(), recorder.Body.String()) } } func TestDeviceFactoryResetHandlerRejectsInvalidInput(t *testing.T) { service := &fakeDeviceFactoryResetService{} request := httptest.NewRequest(http.MethodPost, "/device/v3/factory-reset", strings.NewReader(`{"reset_id":"bad"}`)) request.Header.Set("Idempotency-Key", "factory-reset-key-0001") request = request.WithContext(deviceauth.WithIdentity(request.Context(), deviceauth.Identity{PublicID: "10000000-0000-0000-0000-000000000512"})) recorder := httptest.NewRecorder() DeviceFactoryResetHandler(service).ServeHTTP(recorder, request) if recorder.Code != http.StatusBadRequest || service.calls != 0 || !strings.Contains(recorder.Body.String(), "VALIDATION_FAILED") { t.Fatalf("status=%d calls=%d body=%s", recorder.Code, service.calls, recorder.Body.String()) } } func TestDeviceFactoryResetHandlerMapsPendingTranscripts(t *testing.T) { service := &fakeDeviceFactoryResetService{err: devicereset.ErrPendingTranscripts} body := validDeviceFactoryResetBody() request := httptest.NewRequest(http.MethodPost, "/device/v3/factory-reset", strings.NewReader(body)) request.Header.Set("Idempotency-Key", "factory-reset-key-0001") request = request.WithContext(deviceauth.WithIdentity(request.Context(), deviceauth.Identity{PublicID: "10000000-0000-0000-0000-000000000512"})) recorder := httptest.NewRecorder() DeviceFactoryResetHandler(service).ServeHTTP(recorder, request) if recorder.Code != http.StatusConflict || !strings.Contains(recorder.Body.String(), "DEVICE_RESET_PENDING_TRANSCRIPTS") { t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String()) } } func TestDeviceFactoryResetHandlerMapsIdempotencyConflict(t *testing.T) { service := &fakeDeviceFactoryResetService{err: errors.New("unexpected")} body := validDeviceFactoryResetBody() request := httptest.NewRequest(http.MethodPost, "/device/v3/factory-reset", strings.NewReader(body)) request.Header.Set("Idempotency-Key", "factory-reset-key-0001") request = request.WithContext(deviceauth.WithIdentity(request.Context(), deviceauth.Identity{PublicID: "10000000-0000-0000-0000-000000000512"})) recorder := httptest.NewRecorder() DeviceFactoryResetHandler(service).ServeHTTP(recorder, request) if recorder.Code != http.StatusServiceUnavailable || !strings.Contains(recorder.Body.String(), "DEVICE_RESET_FAILED") { t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String()) } }