103 lines
5.2 KiB
Go
103 lines
5.2 KiB
Go
package validator
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"browser.local/platform/domain"
|
|
)
|
|
|
|
const scumProbeHash = "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
func TestValidateSCUMSchemaProbeRequestAllowsBoundedGenericProbe(t *testing.T) {
|
|
request := domain.SCUMSchemaProbeRequest{RequestID: "probe-1", JobID: "job-1", Binding: validatorSCUMBinding(), Bounds: domain.DefaultSCUMSchemaProbeBounds(), RequestedAt: time.Now()}
|
|
|
|
if err := ValidateSCUMSchemaProbeRequest(request); err != nil {
|
|
t.Fatalf("expected valid probe request, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestValidateSCUMSchemaProbeRequestRejectsHostPathsAndLooseBounds(t *testing.T) {
|
|
request := domain.SCUMSchemaProbeRequest{RequestID: "probe-1", JobID: "job-1", Binding: validatorSCUMBinding(), Bounds: domain.DefaultSCUMSchemaProbeBounds()}
|
|
request.Binding.DatabaseIdentity = `C:\SCUM\Saved\SaveFiles\SCUM.db`
|
|
request.Bounds.MaxSampleRows = 25
|
|
|
|
err := ValidateSCUMSchemaProbeRequest(request)
|
|
if err == nil || !strings.Contains(err.Error(), "protected connection material") || !strings.Contains(err.Error(), "maxSampleRows") {
|
|
t.Fatalf("expected protected material and bound violations, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestValidateSCUMSchemaProbeResultRejectsRawSQLAndRows(t *testing.T) {
|
|
result := domain.SCUMSchemaProbeResult{
|
|
RequestID: "probe-1",
|
|
JobID: "job-1",
|
|
Binding: validatorSCUMBinding(),
|
|
Status: domain.SCUMCapabilityEvidenceCompatible,
|
|
SchemaFingerprint: scumProbeHash,
|
|
ObservedAt: time.Now(),
|
|
ResultDigest: scumProbeHash,
|
|
Limits: domain.DefaultSCUMSchemaProbeBounds(),
|
|
Objects: []domain.SCUMSchemaObjectEvidence{{
|
|
ObjectHash: scumProbeHash,
|
|
Kind: "table",
|
|
NameFingerprint: "select * from players",
|
|
DeclaredColumns: []domain.SCUMSchemaColumnEvidence{{NameFingerprint: scumProbeHash, DeclaredType: "TEXT", Ordinal: 1}},
|
|
SampleFingerprints: []string{"{\"raw\":\"row\"}"},
|
|
}},
|
|
}
|
|
|
|
err := ValidateSCUMSchemaProbeResult(result)
|
|
if err == nil || !strings.Contains(err.Error(), "nameFingerprint must be redacted") || !strings.Contains(err.Error(), "sampleFingerprints") {
|
|
t.Fatalf("expected redaction violations, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestValidateSCUMSchemaProbeResultAcceptsRunTerminalStatuses(t *testing.T) {
|
|
succeeded := domain.SCUMSchemaProbeResult{RequestID: "probe-1", JobID: "job-1", Binding: validatorSCUMBinding(), Status: domain.SCUMSchemaProbeStatusSucceeded, SourceFingerprint: scumProbeHash, SchemaFingerprint: scumProbeHash, ObservedAt: time.Now(), ResultDigest: scumProbeHash, Limits: domain.DefaultSCUMSchemaProbeBounds(), SafeError: domain.SCUMSafeError{Code: domain.SCUMSafeErrorNone}}
|
|
if err := ValidateSCUMSchemaProbeResult(succeeded); err != nil {
|
|
t.Fatalf("expected succeeded Run probe result to validate, got %v", err)
|
|
}
|
|
|
|
succeeded.SourceFingerprint = "C:/db/SCUM.db"
|
|
if err := ValidateSCUMSchemaProbeResult(succeeded); err == nil || !strings.Contains(err.Error(), "sourceFingerprint must be a digest/fingerprint") {
|
|
t.Fatalf("expected raw source fingerprint rejection, got %v", err)
|
|
}
|
|
succeeded.SourceFingerprint = scumProbeHash
|
|
|
|
failed := succeeded
|
|
failed.Status = domain.SCUMCapabilityEvidenceFailed
|
|
failed.SchemaFingerprint = ""
|
|
failed.SafeError = domain.SCUMSafeError{Code: domain.SCUMSafeErrorTargetUnavailable, Retryable: false}
|
|
if err := ValidateSCUMSchemaProbeResult(failed); err != nil {
|
|
t.Fatalf("expected safe failed Run probe result to validate, got %v", err)
|
|
}
|
|
|
|
failed.SafeError = domain.SCUMSafeError{Code: domain.SCUMSafeErrorCode("data_target_plan_invalid"), Retryable: false}
|
|
if err := ValidateSCUMSchemaProbeResult(failed); err != nil {
|
|
t.Fatalf("expected generic Run data-target failure to validate, got %v", err)
|
|
}
|
|
|
|
failed.SafeError = domain.SCUMSafeError{Code: domain.SCUMSafeErrorCode("data_target_invalid path"), Retryable: false}
|
|
if err := ValidateSCUMSchemaProbeResult(failed); err == nil || !strings.Contains(err.Error(), "safeError.code is invalid") {
|
|
t.Fatalf("expected unsafe data-target code rejection, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestValidateSCUMCapabilityEvidenceRequiresSafeCurrentServiceIdentity(t *testing.T) {
|
|
evidence := domain.SCUMCapabilityEvidence{Capability: domain.SCUMDataCapabilityPlayerRead, Status: domain.SCUMCapabilityEvidenceCompatible, Binding: validatorSCUMBinding(), AdapterVersion: "adapter-1", SchemaFingerprint: scumProbeHash, ProbeResultDigest: scumProbeHash, AssetDigests: []string{scumProbeHash}, SafeError: domain.SCUMSafeError{Code: domain.SCUMSafeErrorNone}}
|
|
if err := ValidateSCUMCapabilityEvidence(evidence); err != nil {
|
|
t.Fatalf("expected valid evidence, got %v", err)
|
|
}
|
|
|
|
evidence.SafeError = domain.SCUMSafeError{Code: domain.SCUMSafeErrorProbeFailed, Message: "sqlite:///private/tmp/SCUM.db locked"}
|
|
if err := ValidateSCUMCapabilityEvidence(evidence); err == nil || !strings.Contains(err.Error(), "protected material") {
|
|
t.Fatalf("expected safe error redaction violation, got %v", err)
|
|
}
|
|
}
|
|
|
|
func validatorSCUMBinding() domain.SCUMBindingIdentity {
|
|
return domain.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-fingerprint-1"}
|
|
}
|