package domain import ( "testing" "time" ) func TestSCUMCapabilityGateDefaultsClosedWithoutProbeEvidence(t *testing.T) { active := scumGateBinding() requirement := SCUMCapabilityRequirement{Capability: SCUMDataCapabilityPlayerRead, AdapterVersion: "adapter-1", SchemaFingerprint: "schema-1", AssetDigests: []string{"sha256:query"}} gate := EvaluateSCUMCapabilityGate(requirement, SCUMCapabilityEvidence{}, active, true, time.Now()) if gate.Enabled || gate.State != SCUMCapabilityGateDisabled || gate.ReasonCode != SCUMSafeErrorProbeMissing { t.Fatalf("expected closed gate without evidence, got %#v", gate) } } func TestSCUMCapabilityGateDefaultsClosedWhenProbeExecutorUnavailable(t *testing.T) { active := scumGateBinding() requirement := SCUMCapabilityRequirement{Capability: SCUMDataCapabilityPlayerRead, AdapterVersion: "adapter-1", SchemaFingerprint: "schema-1"} evidence := SCUMCapabilityEvidence{Capability: SCUMDataCapabilityPlayerRead, Status: SCUMCapabilityEvidenceCompatible, Binding: active, AdapterVersion: "adapter-1", SchemaFingerprint: "schema-1"} gate := EvaluateSCUMCapabilityGate(requirement, evidence, active, false, time.Now()) if gate.Enabled || gate.ReasonCode != SCUMSafeErrorProbeExecutorAbsent { t.Fatalf("expected executor gate failure, got %#v", gate) } } func TestSCUMCapabilityGateEnablesOnlyMatchingEvidence(t *testing.T) { now := time.Date(2026, 8, 11, 12, 0, 0, 0, time.UTC) active := scumGateBinding() requirement := SCUMCapabilityRequirement{Capability: SCUMDataCapabilityVehicleRead, AdapterVersion: "adapter-1", SchemaFingerprint: "schema-1", AssetDigests: []string{"sha256:vehicle-query"}} evidence := SCUMCapabilityEvidence{Capability: SCUMDataCapabilityVehicleRead, Status: SCUMCapabilityEvidenceCompatible, Binding: active, AdapterVersion: "adapter-1", SchemaFingerprint: "schema-1", AssetDigests: []string{"sha256:vehicle-query", "sha256:result-schema"}, ExpiresAt: now.Add(time.Hour)} gate := EvaluateSCUMCapabilityGate(requirement, evidence, active, true, now) if !gate.Enabled || gate.State != SCUMCapabilityGateEnabled || gate.ReasonCode != SCUMSafeErrorNone { t.Fatalf("expected enabled gate, got %#v", gate) } } func TestSCUMCapabilityGateRejectsMismatchedCurrentServiceEvidence(t *testing.T) { now := time.Date(2026, 8, 11, 12, 0, 0, 0, time.UTC) active := scumGateBinding() requirement := SCUMCapabilityRequirement{Capability: SCUMDataCapabilityPositionRead, AdapterVersion: "adapter-1", SchemaFingerprint: "schema-1", AssetDigests: []string{"sha256:positions"}} evidence := SCUMCapabilityEvidence{Capability: SCUMDataCapabilityPositionRead, Status: SCUMCapabilityEvidenceCompatible, Binding: active, AdapterVersion: "adapter-1", SchemaFingerprint: "schema-1", AssetDigests: []string{"sha256:positions"}, ExpiresAt: now.Add(time.Hour)} changedBinding := evidence changedBinding.Binding.DatabaseIdentity = "db-other" if gate := EvaluateSCUMCapabilityGate(requirement, changedBinding, active, true, now); gate.Enabled || gate.ReasonCode != SCUMSafeErrorBindingMismatch { t.Fatalf("expected binding mismatch, got %#v", gate) } changedFingerprint := evidence changedFingerprint.SchemaFingerprint = "schema-other" if gate := EvaluateSCUMCapabilityGate(requirement, changedFingerprint, active, true, now); gate.Enabled || gate.ReasonCode != SCUMSafeErrorFingerprintMismatch { t.Fatalf("expected fingerprint mismatch, got %#v", gate) } changedDigest := evidence changedDigest.AssetDigests = []string{"sha256:different"} if gate := EvaluateSCUMCapabilityGate(requirement, changedDigest, active, true, now); gate.Enabled || gate.ReasonCode != SCUMSafeErrorDigestMismatch { t.Fatalf("expected digest mismatch, got %#v", gate) } } func TestDefaultSCUMSchemaProbeBoundsAreBoundedAndDiagnosticOnly(t *testing.T) { bounds := DefaultSCUMSchemaProbeBounds() if bounds.MaxObjects <= 0 || bounds.MaxSampleRows > 3 || bounds.TimeoutMS > 5000 || bounds.MaxResultBytes > 512*1024 { t.Fatalf("unexpected unsafe default probe bounds: %#v", bounds) } } func scumGateBinding() SCUMBindingIdentity { return SCUMBindingIdentity{ServerInstanceID: "server-1", RunBindingID: "binding-1", RunEndpointID: "run-1", PluginID: "game.scum", PluginVersion: "0.1.6", AdapterVersion: "adapter-1", GameVersion: "scum-1", DatabaseIdentity: "db-current"} }