64 lines
2.6 KiB
Go
64 lines
2.6 KiB
Go
package httpapi
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"data-terminal-cloud/internal/device"
|
||
|
|
"data-terminal-cloud/internal/deviceauth"
|
||
|
|
)
|
||
|
|
|
||
|
|
type fakeDeviceService struct {
|
||
|
|
bootstrap device.Bootstrap
|
||
|
|
config device.Configuration
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s fakeDeviceService) ReportBootstrap(context.Context, deviceauth.Identity, device.BootstrapReport) (device.Bootstrap, error) {
|
||
|
|
return s.bootstrap, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s fakeDeviceService) GetConfiguration(context.Context, deviceauth.Identity) (device.Configuration, error) {
|
||
|
|
return s.config, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestBootstrapValidationAndResponse(t *testing.T) {
|
||
|
|
service := fakeDeviceService{bootstrap: device.Bootstrap{DeviceID: "device-1", Status: "registered", ConfigRevision: 3}}
|
||
|
|
handler := DeviceBootstrapHandler(service)
|
||
|
|
badRequest := httptest.NewRequest(http.MethodGet, "/device/v2/bootstrap", nil)
|
||
|
|
badRequest = badRequest.WithContext(deviceauth.WithIdentity(badRequest.Context(), deviceauth.Identity{PublicID: "device-1"}))
|
||
|
|
badRecorder := httptest.NewRecorder()
|
||
|
|
handler.ServeHTTP(badRecorder, badRequest)
|
||
|
|
if badRecorder.Code != http.StatusBadRequest {
|
||
|
|
t.Fatalf("validation status = %d", badRecorder.Code)
|
||
|
|
}
|
||
|
|
|
||
|
|
request := httptest.NewRequest(http.MethodGet, "/device/v2/bootstrap?firmware_version=1.0&device_time=2026-08-23T12%3A00%3A00Z&sample_rate=16000", nil)
|
||
|
|
request = request.WithContext(deviceauth.WithIdentity(request.Context(), deviceauth.Identity{PublicID: "device-1"}))
|
||
|
|
recorder := httptest.NewRecorder()
|
||
|
|
handler.ServeHTTP(recorder, request)
|
||
|
|
if recorder.Code != http.StatusOK || !json.Valid(recorder.Body.Bytes()) || !containsText(recorder.Body.String(), `"device_id":"device-1"`) {
|
||
|
|
t.Fatalf("unexpected response: %d %s", recorder.Code, recorder.Body.String())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestConfigUsesETagAndConditionalGet(t *testing.T) {
|
||
|
|
service := fakeDeviceService{config: device.Configuration{DeviceID: "device-1", Revision: 3, DesiredConfig: json.RawMessage(`{"codec":"opus"}`)}}
|
||
|
|
handler := DeviceConfigHandler(service)
|
||
|
|
for _, test := range []struct {
|
||
|
|
ifNoneMatch string
|
||
|
|
status int
|
||
|
|
}{{"", http.StatusOK}, {`"v3"`, http.StatusNotModified}} {
|
||
|
|
request := httptest.NewRequest(http.MethodGet, "/device/v2/config", nil)
|
||
|
|
request.Header.Set("If-None-Match", test.ifNoneMatch)
|
||
|
|
request = request.WithContext(deviceauth.WithIdentity(request.Context(), deviceauth.Identity{PublicID: "device-1"}))
|
||
|
|
recorder := httptest.NewRecorder()
|
||
|
|
handler.ServeHTTP(recorder, request)
|
||
|
|
if recorder.Code != test.status || recorder.Header().Get("ETag") != `"v3"` {
|
||
|
|
t.Fatalf("If-None-Match=%q status=%d etag=%q", test.ifNoneMatch, recorder.Code, recorder.Header().Get("ETag"))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|