package platform import ( "context" "encoding/json" "net/http" "net/http/httptest" "strings" "testing" ) // MintDeviceSession sends the bootstrap token as Bearer + the device descriptor, and maps // the response into the device-session result the desktop then rides. func TestMintDeviceSession(t *testing.T) { var gotAuth string var gotBody map[string]string srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost || r.URL.Path != "/api/auth/device-session" { http.NotFound(w, r) return } gotAuth = r.Header.Get("Authorization") _ = json.NewDecoder(r.Body).Decode(&gotBody) _ = json.NewEncoder(w).Encode(map[string]any{ "access_token": "acc-x", "refresh_token": "rtk-x", "expires_in": 900, "device_id": "dev_abc", "user_id": "sub-1", "name": "Commilitia", "avatar": "https://example.net/a.png", }) })) defer srv.Close() res, err := MintDeviceSession(context.Background(), srv.URL, "boot-token", "dev_abc", "Mac", "macos") if err != nil { t.Fatalf("MintDeviceSession: %v", err) } if gotAuth != "Bearer boot-token" { t.Errorf("Authorization: got %q, want Bearer boot-token", gotAuth) } if gotBody["device_id"] != "dev_abc" || gotBody["device_name"] != "Mac" || gotBody["device_type"] != "macos" { t.Errorf("request body: %+v", gotBody) } if res.AccessToken != "acc-x" || res.RefreshToken != "rtk-x" || res.DeviceID != "dev_abc" || res.UserID != "sub-1" || res.Name != "Commilitia" || res.ExpiresIn != 900 || res.Avatar != "https://example.net/a.png" { t.Errorf("result: %+v", res) } } // A non-200 from the endpoint surfaces as an error rather than a half-built session. func TestMintDeviceSession_ErrorStatus(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusBadGateway) })) defer srv.Close() if _, err := MintDeviceSession(context.Background(), srv.URL, "boot", "dev_abc", "Mac", "macos"); err == nil { t.Fatal("expected error on non-200, got nil") } } // ResolveDeviceID mints a validMeta-safe "dev_"-prefixed id and persists it (stable across // calls). Uses an isolated config dir so it doesn't touch the real one. func TestResolveDeviceID(t *testing.T) { // os.UserConfigDir honours XDG_CONFIG_HOME on Linux and HOME on macOS. dir := t.TempDir() t.Setenv("XDG_CONFIG_HOME", dir) t.Setenv("HOME", dir) id, err := ResolveDeviceID() if err != nil { t.Fatalf("ResolveDeviceID: %v", err) } if !strings.HasPrefix(id, "dev_") || len(id) < 8 { t.Errorf("device id format: %q", id) } again, err := ResolveDeviceID() if err != nil { t.Fatalf("ResolveDeviceID (2): %v", err) } if again != id { t.Errorf("device id not stable: %q != %q", again, id) } }