98 lines
4.5 KiB
Go
98 lines
4.5 KiB
Go
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())
|
|
}
|
|
}
|