package topdata import ( "path/filepath" "testing" "git.westgate.pw/ShadowsOverWestgate/sow-tools/internal/project" ) // The manifest_file branch reads a local autogenManifest JSON, augments the // visualeffects dataset from its entries, and assigns lock IDs — no network. func TestApplyAutogenConsumersReadsManifestFile(t *testing.T) { root := testProjectRoot(t) manifestPath := filepath.Join(root, ".cache", "sow-accessory-vfx-manifest.json") mkdirAll(t, filepath.Join(root, ".cache")) writeFile(t, manifestPath, `{ "id": "accessory_visualeffects", "repo": "ShadowsOverWestgate/sow-assets-manifest", "ref": "v1.2.3", "generated_at": "2026-06-21T00:00:00Z", "entries": [ {"source": "head_accessories/hat/hfx_bandana.mdl", "model_stem": "hfx_bandana", "group": "head_accessories", "subgroup": "hat"} ] }`+"\n") p := testProject(root) p.Config.Autogen.Consumers = []project.AutogenConsumerConfig{ { ID: "accessory_visualeffects", Producer: "accessory_visualeffects", Dataset: "visualeffects", Mode: "accessory_visualeffects", Optional: true, ManifestFile: ".cache/sow-accessory-vfx-manifest.json", }, } collected := []nativeCollectedDataset{ { Dataset: nativeDataset{Name: "visualeffects", Kind: nativeDatasetBase}, Columns: []string{"Label", "Type_FD", "OrientWithGround", "Imp_HeadCon_Node", "OrientWithObject"}, Rows: nil, LockData: map[string]int{ "visualeffects:existing": 17, }, }, } got, err := applyAutogenConsumers(p, collected, nil) if err != nil { t.Fatalf("applyAutogenConsumers failed: %v", err) } if len(got) != 1 || len(got[0].Rows) != 1 { t.Fatalf("expected one autogenerated row, got %#v", got) } row := got[0].Rows[0] if row["key"] != "visualeffects:head_accessories/hat/bandana" || row["Imp_HeadCon_Node"] != "hfx_bandana" { t.Fatalf("unexpected generated row: %#v", row) } if _, ok := got[0].LockData["visualeffects:head_accessories/hat/bandana"]; !ok { t.Fatalf("expected lock id for generated accessory, got %#v", got[0].LockData) } // Authored key untouched. if got[0].LockData["visualeffects:existing"] != 17 { t.Fatalf("expected authored lock id retained at 17, got %#v", got[0].LockData) } } // A missing manifest_file is an ignorable-optional condition: the optional // consumer fails open (no rows) and preserves existing lock IDs. func TestApplyAutogenConsumersMissingManifestFileFailsOpen(t *testing.T) { root := testProjectRoot(t) lockPath := filepath.Join(root, "visualeffects-lock.json") writeFile(t, lockPath, `{"visualeffects:head_accessories/hat/bandana":10101}`+"\n") p := testProject(root) p.Config.Autogen.Consumers = []project.AutogenConsumerConfig{ { ID: "accessory_visualeffects", Producer: "accessory_visualeffects", Dataset: "visualeffects", Mode: "accessory_visualeffects", Optional: true, ManifestFile: ".cache/does-not-exist.json", }, } collected := []nativeCollectedDataset{ { Dataset: nativeDataset{Name: "visualeffects", Kind: nativeDatasetBase, LockPath: lockPath}, Columns: []string{"Label"}, Rows: nil, LockData: map[string]int{}, }, } got, err := applyAutogenConsumers(p, collected, nil) if err != nil { t.Fatalf("expected fail-open, got error: %v", err) } if id, ok := got[0].LockData["visualeffects:head_accessories/hat/bandana"]; !ok || id != 10101 { t.Fatalf("expected preserved lock id 10101, got %v (present=%v)", id, ok) } }