package companion import ( "context" "encoding/json" "fmt" "net/http" "strings" "testing" "time" ) func TestRunOneShotSmokeProcessesOnlySafeDiagnosticsAndUploadsIsolatedHealth(t *testing.T) { stamp := time.Date(2026, 7, 20, 9, 10, 11, 123456789, time.UTC) config := loadTestConfig(t) sessionExpiry := stamp.Add(15 * time.Minute) step := 0 transport := roundTripFunc(func(request *http.Request) (*http.Response, error) { switch step { case 0: assertPlatformRequest(t, request, registerPath) step++ return jsonHTTPResponse(http.StatusOK, registerResponse{Accepted: true, InstallationID: config.Component.InstallationID, SessionToken: "component-session-smoke", ExpiresAt: sessionExpiry, HeartbeatEverySeconds: 30, ServerTime: stamp}), nil case 1: assertPlatformRequest(t, request, heartbeatPath) var body heartbeatRequest decodeRequest(t, request, &body) if body.SessionToken != "component-session-smoke" || body.HealthReason != "one-shot smoke ready" { t.Fatalf("unexpected smoke heartbeat: %+v", body) } step++ return jsonHTTPResponse(http.StatusOK, heartbeatResponse{Accepted: true, InstallationID: config.Component.InstallationID, Status: "online", Health: "healthy", NextHeartbeatSeconds: 30, SessionExpiresAt: sessionExpiry, ServerTime: stamp}), nil case 2: assertPlatformRequest(t, request, claimPath) var body claimRequest decodeRequest(t, request, &body) if body.SessionToken != "component-session-smoke" || body.Limit != 1 { t.Fatalf("unexpected smoke claim: %+v", body) } step++ return jsonHTTPResponse(http.StatusOK, claimResponse{Items: []ClaimedCommand{{ID: "diagnostics-1", ProfileKey: ProfileKey, CommandType: companionDiagnosticsCommandType, Payload: map[string]any{"includeWindowState": true, "maxEntries": 3}, FencingToken: 17, LeaseExpiresAt: stamp.Add(time.Minute), ExpiresAt: stamp.Add(5 * time.Minute)}}, Count: 1}), nil case 3: assertPlatformRequest(t, request, "/api/v1/game-client-bridge/companion/commands/diagnostics-1/ack") var body ackRequest decodeRequest(t, request, &body) if body.SessionToken != "component-session-smoke" || body.FencingToken != 17 { t.Fatalf("unexpected smoke ack: %+v", body) } step++ return jsonHTTPResponse(http.StatusOK, CommandAck{CommandID: "diagnostics-1", State: "claimed", FencingToken: 17, AcknowledgedAt: stamp}), nil case 4: assertPlatformRequest(t, request, "/api/v1/game-client-bridge/companion/commands/diagnostics-1/result") var body resultRequest decodeRequest(t, request, &body) if body.SessionToken != "component-session-smoke" || body.FencingToken != 17 || body.Status != "succeeded" || body.Summary != "companion diagnostics available" { t.Fatalf("unexpected smoke result: %+v", body) } if body.Payload["status"] != "online" || body.Payload["version"] != config.Component.Version || body.Payload["lastHeartbeatAt"] != stamp.Format(time.RFC3339Nano) { t.Fatalf("unexpected bounded diagnostics payload: %+v", body.Payload) } serialized, _ := json.Marshal(body) if strings.Contains(string(serialized), testProof) { t.Fatalf("result exposed proof: %s", serialized) } step++ return jsonHTTPResponse(http.StatusOK, map[string]any{"commandId": "diagnostics-1", "state": "succeeded", "result": map[string]any{"status": "succeeded", "summary": "companion diagnostics available", "completedAt": stamp}, "updatedAt": stamp, "completedAt": stamp}), nil case 5: assertPlatformRequest(t, request, snapshotPath) var body snapshotRequest decodeRequest(t, request, &body) if body.SessionToken != "component-session-smoke" || body.Type != companionHealthSnapshotType || body.SchemaVersion != companionHealthSchemaVersion || body.StreamKey != "smoke-fixture-stream-nonce-0001" || body.Sequence != 1 { t.Fatalf("unexpected isolated smoke snapshot identity: %+v", body) } if !body.ObservedAt.Equal(stamp) || body.KeepForSeconds != 604800 || body.MaxRecords != 1000 || body.Payload["status"] != "online" || body.Payload["observedAt"] != stamp.Format(time.RFC3339Nano) { t.Fatalf("unexpected typed health snapshot: %+v", body) } step++ return jsonHTTPResponse(http.StatusAccepted, AcceptedSnapshot{SnapshotID: "health-snapshot-1", ProfileKey: ProfileKey, Type: body.Type, SchemaVersion: body.SchemaVersion, StreamKey: body.StreamKey, Sequence: body.Sequence, AcceptedAt: stamp, ExpiresAt: stamp.Add(7 * 24 * time.Hour)}), nil default: return nil, fmt.Errorf("unexpected smoke transport: %s", request.URL.Path) } }) client := newTestClient(t, config, transport, stamp) result, err := RunOneShotSmoke(context.Background(), client, SmokeOptions{IsolatedNonProduction: true, StreamSuffix: func() (string, error) { return "fixture-stream-nonce-0001", nil }}) if err != nil { t.Fatalf("run one-shot smoke: %v", err) } if result.ClaimedCount != 1 || result.CompletedCount != 1 || result.UnsupportedCount != 0 || result.SnapshotID != "health-snapshot-1" { t.Fatalf("unexpected safe smoke result: %+v", result) } if len(result.CompletedCommandIDs) != 1 || result.CompletedCommandIDs[0] != "diagnostics-1" || len(result.UnsupportedCommandIDs) != 0 { t.Fatalf("unexpected smoke IDs: %+v", result) } assertSafeSmokeOutput(t, result) if step != 6 { t.Fatalf("expected diagnostics ack/result plus snapshot, got %d requests", step) } } func TestRunOneShotSmokeLeavesUnsupportedCommandUnackedAndUnexecuted(t *testing.T) { stamp := time.Date(2026, 7, 20, 10, 0, 0, 0, time.UTC) config := loadTestConfig(t) sessionExpiry := stamp.Add(15 * time.Minute) step := 0 transport := roundTripFunc(func(request *http.Request) (*http.Response, error) { switch step { case 0: step++ return jsonHTTPResponse(http.StatusOK, registerResponse{Accepted: true, InstallationID: config.Component.InstallationID, SessionToken: "component-session-unsupported", ExpiresAt: sessionExpiry, HeartbeatEverySeconds: 30, ServerTime: stamp}), nil case 1: step++ return jsonHTTPResponse(http.StatusOK, heartbeatResponse{Accepted: true, InstallationID: config.Component.InstallationID, Status: "online", Health: "healthy", NextHeartbeatSeconds: 30, SessionExpiresAt: sessionExpiry, ServerTime: stamp}), nil case 2: step++ return jsonHTTPResponse(http.StatusOK, claimResponse{Items: []ClaimedCommand{{ID: "unsupported-1", ProfileKey: ProfileKey, CommandType: "announcement.send", Payload: map[string]any{"message": "must not execute"}, FencingToken: 18, LeaseExpiresAt: stamp.Add(time.Minute), ExpiresAt: stamp.Add(5 * time.Minute)}}, Count: 1}), nil default: return nil, fmt.Errorf("unsupported command triggered transport: %s", request.URL.Path) } }) client := newTestClient(t, config, transport, stamp) result, err := RunOneShotSmoke(context.Background(), client, SmokeOptions{IsolatedNonProduction: true, StreamSuffix: func() (string, error) { return "fixture-stream-nonce-0002", nil }}) if err == nil || !strings.Contains(err.Error(), "unsupported") { t.Fatalf("expected unsupported smoke to stop, result=%+v err=%v", result, err) } if result.ClaimedCount != 1 || result.CompletedCount != 0 || result.UnsupportedCount != 1 || len(result.CompletedCommandIDs) != 0 || len(result.UnsupportedCommandIDs) != 1 || result.UnsupportedCommandIDs[0] != "unsupported-1" { t.Fatalf("unsupported command did not fail safely: %+v", result) } assertSafeSmokeOutput(t, result) if step != 3 { t.Fatalf("expected no unsupported ack/result requests, got %d steps", step) } } func TestRunOneShotSmokeRejectsNonSingletonClaimBeforeExecution(t *testing.T) { stamp := time.Date(2026, 7, 20, 10, 30, 0, 0, time.UTC) for _, test := range []struct { name string items []ClaimedCommand }{ {name: "zero"}, {name: "multiple", items: []ClaimedCommand{{ID: "diagnostics-1"}, {ID: "diagnostics-2"}}}, } { t.Run(test.name, func(t *testing.T) { config := loadTestConfig(t) step := 0 transport := roundTripFunc(func(request *http.Request) (*http.Response, error) { step++ switch step { case 1: return jsonHTTPResponse(http.StatusOK, registerResponse{Accepted: true, InstallationID: config.Component.InstallationID, SessionToken: "component-session-singleton", ExpiresAt: stamp.Add(15 * time.Minute), HeartbeatEverySeconds: 30, ServerTime: stamp}), nil case 2: return jsonHTTPResponse(http.StatusOK, heartbeatResponse{Accepted: true, InstallationID: config.Component.InstallationID, Status: "online", Health: "healthy", NextHeartbeatSeconds: 30, SessionExpiresAt: stamp.Add(15 * time.Minute), ServerTime: stamp}), nil case 3: return jsonHTTPResponse(http.StatusOK, claimResponse{Items: test.items, Count: len(test.items)}), nil default: return nil, fmt.Errorf("non-singleton claim triggered execution: %s", request.URL.Path) } }) client := newTestClient(t, config, transport, stamp) result, err := RunOneShotSmoke(context.Background(), client, SmokeOptions{IsolatedNonProduction: true, StreamSuffix: func() (string, error) { return "fixture-singleton-nonce", nil }}) if err == nil || !strings.Contains(err.Error(), "exactly one") || result.ClaimedCount != len(test.items) || step != 3 { t.Fatalf("non-singleton claim was not rejected: result=%+v step=%d err=%v", result, step, err) } }) } } func TestValidateSmokeDiagnosticsCommandRejectsUnsafeClaims(t *testing.T) { stamp := time.Date(2026, 7, 20, 11, 0, 0, 0, time.UTC) valid := ClaimedCommand{ID: "diagnostics-1", ProfileKey: ProfileKey, CommandType: companionDiagnosticsCommandType, Payload: map[string]any{"includeWindowState": false, "maxEntries": float64(5)}, FencingToken: 7, LeaseExpiresAt: stamp.Add(time.Minute), ExpiresAt: stamp.Add(2 * time.Minute)} tests := []struct { name string mutate func(*ClaimedCommand) }{ {name: "profile", mutate: func(command *ClaimedCommand) { command.ProfileKey = "other" }}, {name: "fence", mutate: func(command *ClaimedCommand) { command.FencingToken = 0 }}, {name: "lease", mutate: func(command *ClaimedCommand) { command.LeaseExpiresAt = stamp }}, {name: "expiry", mutate: func(command *ClaimedCommand) { command.ExpiresAt = stamp.Add(-time.Second) }}, {name: "nil payload", mutate: func(command *ClaimedCommand) { command.Payload = nil }}, {name: "unknown payload", mutate: func(command *ClaimedCommand) { command.Payload["message"] = "not allowed" }}, {name: "payload type", mutate: func(command *ClaimedCommand) { command.Payload["maxEntries"] = 2.5 }}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { candidate := valid candidate.Payload = map[string]any{"includeWindowState": false, "maxEntries": float64(5)} test.mutate(&candidate) if err := validateSmokeDiagnosticsCommand(candidate, stamp); err == nil { t.Fatalf("expected unsafe diagnostics claim to be rejected: %+v", candidate) } }) } } func TestRunOneShotSmokeRequiresIsolatedNonProductionQueue(t *testing.T) { result, err := RunOneShotSmoke(context.Background(), &Client{}, SmokeOptions{}) if err == nil || !strings.Contains(err.Error(), "isolated non-production") { t.Fatalf("expected isolation gate, result=%+v err=%v", result, err) } } func assertSafeSmokeOutput(t *testing.T, result SmokeResult) { t.Helper() serialized, err := json.Marshal(result) if err != nil { t.Fatalf("marshal smoke result: %v", err) } for _, forbidden := range []string{testProof, "component-session", "includeWindowState", "must not execute", "payload"} { if strings.Contains(string(serialized), forbidden) { t.Fatalf("smoke output exposed %q: %s", forbidden, serialized) } } }