Align runtime profiles with plugin-owned records
This commit is contained in:
@@ -139,20 +139,15 @@ func TestGameClientBridgeQueryTemplateDeclarationRoundTripIsSafe(t *testing.T) {
|
||||
ParameterSchemaRef: "schemas/bridge/query/player-lookup.parameters.schema.json", ResultSchemaRef: "schemas/bridge/query/player-lookup.result.schema.json", SQLRef: "sql/player-lookup.sql", MaxRows: 50, TimeoutSeconds: 10, PollIntervalSeconds: 3,
|
||||
Projections: []GameClientBridgeQueryProjectionDeclarationBody{{Collection: "users", RowPath: "rows", MatchField: "kind", MatchValue: "player", UpsertKeys: []string{"steamId"}, FieldMappings: map[string]string{"steamId": "steamId"}, FixedValues: map[string]string{"source": "sqlite"}, ObservedAtField: "sampledAt", MergeExisting: true}},
|
||||
}},
|
||||
LogProjections: []GameClientBridgeLogProjectionDeclarationBody{{
|
||||
Key: "player.login", StreamKeys: []string{"process.stdout"}, Steps: []GameClientBridgeLogProjectionStepDeclarationBody{{Pattern: `Player (?<slot>\d+)`}}, CorrelationFields: []string{"slot"}, MaxInterveningLines: 8,
|
||||
Target: GameClientBridgeLogProjectionTargetDeclarationBody{Collection: "users", UpsertKeys: []string{"steamId"}, CaptureMappings: map[string]string{"steamId": "steamId"}, HashMappings: map[string]string{"networkCorrelation": "ip"}, FixedValues: map[string]string{"source": "stdout"}, ObservedAtField: "lastLoginAt"},
|
||||
Presence: &GameClientBridgeLogProjectionPresenceDeclarationBody{TimestampField: "lastLoginAt", ActiveWindowSeconds: 600, ActivityTarget: &GameClientBridgeLogProjectionTargetDeclarationBody{Collection: "activity", UpsertKeys: []string{"steamId"}, CaptureMappings: map[string]string{"steamId": "steamId"}}},
|
||||
}},
|
||||
LifecycleProjections: []GameClientBridgeLifecycleProjectionDeclarationBody{{Key: "server.stop", Capabilities: []string{"process.stop"}, Target: GameClientBridgeBulkProjectionTargetBody{Collection: "users", MatchField: "online", MatchValue: "true", FixedValues: map[string]string{"online": "false"}, ObservedAtField: "lastLogoutAt", ActivityTarget: &GameClientBridgeBulkActivityTargetBody{Collection: "activity", UpsertKeys: []string{"steamId", "observedAt"}, RowMappings: map[string]string{"steamId": "steamId"}, FixedValues: map[string]string{"eventType": "logout"}, ObservedAtField: "observedAt"}}}},
|
||||
DataPacks: []GameClientBridgeDataPackDeclarationBody{{Key: "db-v1", DatabaseUserVersion: 1, LogParserRefs: []string{"data/logs.json"}, ConfigMapRefs: []string{"data/config.json"}, DataRefs: []string{"data/items.json"}}},
|
||||
DataPacks: []GameClientBridgeDataPackDeclarationBody{{Key: "db-v1", DatabaseUserVersion: 1, ConfigMapRefs: []string{"data/config.json"}, DataRefs: []string{"data/items.json"}}},
|
||||
CommandRetentionSeconds: 86400,
|
||||
MaxCommands: 1000,
|
||||
Pages: []GameClientBridgePageContractBody{{PageKey: "players", QueryTemplateKeys: []string{"player.lookup"}}},
|
||||
}
|
||||
|
||||
domainManifest := body.ToDomain()
|
||||
if len(domainManifest.QueryTemplates) != 1 || domainManifest.QueryTemplates[0].SQLRef != "sql/player-lookup.sql" || domainManifest.QueryTemplates[0].PollIntervalSeconds != 3 || len(domainManifest.QueryTemplates[0].Projections) != 1 || domainManifest.QueryTemplates[0].Projections[0].MatchValue != "player" || !domainManifest.QueryTemplates[0].Projections[0].MergeExisting || len(domainManifest.LogProjections) != 1 || domainManifest.LogProjections[0].Presence.ActiveWindowSeconds != 600 || domainManifest.LogProjections[0].Target.HashMappings["networkCorrelation"] != "ip" || len(domainManifest.LifecycleProjections) != 1 || domainManifest.LifecycleProjections[0].Target.ActivityTarget.FixedValues["eventType"] != "logout" || len(domainManifest.DataPacks) != 1 || domainManifest.DataPacks[0].DataRefs[0] != "data/items.json" || domainManifest.Pages[0].QueryTemplateKeys[0] != "player.lookup" {
|
||||
if len(domainManifest.QueryTemplates) != 1 || domainManifest.QueryTemplates[0].SQLRef != "sql/player-lookup.sql" || domainManifest.QueryTemplates[0].PollIntervalSeconds != 3 || len(domainManifest.QueryTemplates[0].Projections) != 1 || domainManifest.QueryTemplates[0].Projections[0].MatchValue != "player" || !domainManifest.QueryTemplates[0].Projections[0].MergeExisting || len(domainManifest.LifecycleProjections) != 1 || domainManifest.LifecycleProjections[0].Target.ActivityTarget.FixedValues["eventType"] != "logout" || len(domainManifest.DataPacks) != 1 || domainManifest.DataPacks[0].DataRefs[0] != "data/items.json" || domainManifest.Pages[0].QueryTemplateKeys[0] != "player.lookup" {
|
||||
t.Fatalf("query template conversion lost declaration fields: %#v", domainManifest)
|
||||
}
|
||||
domainManifest.QueryTemplates[0].Projections[0].FieldMappings["steamId"] = "mutated"
|
||||
@@ -160,11 +155,6 @@ func TestGameClientBridgeQueryTemplateDeclarationRoundTripIsSafe(t *testing.T) {
|
||||
t.Fatal("query projection target aliases request DTO data")
|
||||
}
|
||||
domainManifest.QueryTemplates[0].Projections[0].FieldMappings["steamId"] = "steamId"
|
||||
domainManifest.LogProjections[0].Target.CaptureMappings["steamId"] = "mutated"
|
||||
if body.LogProjections[0].Target.CaptureMappings["steamId"] != "steamId" {
|
||||
t.Fatal("log projection target aliases request DTO data")
|
||||
}
|
||||
domainManifest.LogProjections[0].Target.CaptureMappings["steamId"] = "steamId"
|
||||
domainManifest.LifecycleProjections[0].Target.ActivityTarget.RowMappings["steamId"] = "mutated"
|
||||
if body.LifecycleProjections[0].Target.ActivityTarget.RowMappings["steamId"] != "steamId" {
|
||||
t.Fatal("lifecycle projection target aliases request DTO data")
|
||||
@@ -190,10 +180,6 @@ func TestGameClientBridgeQueryTemplateDeclarationRoundTripIsSafe(t *testing.T) {
|
||||
t.Fatal("query projection target aliases domain data")
|
||||
}
|
||||
response.QueryTemplates[0].Projections[0].FixedValues["source"] = "sqlite"
|
||||
response.LogProjections[0].Target.FixedValues["source"] = "mutated"
|
||||
if domainManifest.LogProjections[0].Target.FixedValues["source"] != "stdout" {
|
||||
t.Fatal("log projection target aliases domain data")
|
||||
}
|
||||
response.LifecycleProjections[0].Target.FixedValues["online"] = "mutated"
|
||||
if domainManifest.LifecycleProjections[0].Target.FixedValues["online"] != "false" {
|
||||
t.Fatal("lifecycle projection target aliases domain data")
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"browser.local/platform/domain"
|
||||
)
|
||||
|
||||
func TestRuntimeLogEventDeclarationRoundTripUsesSafeProjection(t *testing.T) {
|
||||
body := GamePluginRuntimeProfilesBody{
|
||||
LogEvents: []RuntimeLogEventBody{{
|
||||
Key: "chat-message", Title: "Chat message", SourceKey: "chat-log", EventType: "chat.message",
|
||||
Permission: "server.logs.read", SchemaRef: "schemas/log-events/chat-message.schema.json", RetentionDays: 30, Severity: "info",
|
||||
}},
|
||||
}
|
||||
|
||||
profiles := body.ToDomain()
|
||||
if len(profiles.LogEvents) != 1 || profiles.LogEvents[0].EventType != "chat.message" || profiles.LogEvents[0].Severity != "info" {
|
||||
t.Fatalf("log event conversion lost declaration fields: %+v", profiles.LogEvents)
|
||||
}
|
||||
profiles.LogEvents[0].Title = "Mutated"
|
||||
if body.LogEvents[0].Title != "Chat message" {
|
||||
t.Fatal("log event domain conversion aliases request DTO data")
|
||||
}
|
||||
|
||||
projection := runtimeProfilesFromDomain(domain.GamePluginRuntimeProfiles{LogEvents: profiles.LogEvents})
|
||||
encoded, err := json.Marshal(projection.LogEvents[0])
|
||||
if err != nil {
|
||||
t.Fatalf("marshal log event projection: %v", err)
|
||||
}
|
||||
var fields map[string]any
|
||||
if err := json.Unmarshal(encoded, &fields); err != nil {
|
||||
t.Fatalf("decode log event projection: %v", err)
|
||||
}
|
||||
expected := []string{"key", "title", "sourceKey", "eventType", "permission", "schemaRef", "retentionDays", "severity"}
|
||||
if len(fields) != len(expected) {
|
||||
t.Fatalf("log event projection contains unexpected fields: %s", encoded)
|
||||
}
|
||||
for _, field := range expected {
|
||||
if _, exists := fields[field]; !exists {
|
||||
t.Fatalf("log event projection is missing %q: %s", field, encoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user