package resources import ( "testing" "github.com/stretchr/testify/assert" "github.com/grafana/grafana/apps/provisioning/pkg/safepath" ) func TestGetPathType(t *testing.T) { tests := []struct { name string isDir bool expected string }{ { name: "directory path", isDir: true, expected: "directory (ends with '/')", }, { name: "file path", isDir: false, expected: "file (no trailing '/')", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := getPathType(tt.isDir) assert.Equal(t, tt.expected, result) }) } } func TestMovePathValidation(t *testing.T) { tests := []struct { name string originalPath string newPath string expectError bool errorMessage string }{ { name: "file to file move (valid)", originalPath: "old/file.json", newPath: "new/file.json", expectError: false, }, { name: "directory to directory move (valid)", originalPath: "old/folder/", newPath: "new/folder/", expectError: false, }, { name: "file to directory move (invalid)", originalPath: "old/file.json", newPath: "new/folder/", expectError: true, errorMessage: "cannot move between file and directory types", }, { name: "directory to file move (invalid)", originalPath: "old/folder/", newPath: "new/file.json", expectError: true, errorMessage: "cannot move between file and directory types", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Test the path validation logic that would be used in MoveResource sourceIsDir := safepath.IsDir(tt.originalPath) targetIsDir := safepath.IsDir(tt.newPath) if tt.expectError { assert.NotEqual(t, sourceIsDir, targetIsDir, "Path types should be different for invalid moves") } else { assert.Equal(t, sourceIsDir, targetIsDir, "Path types should be the same for valid moves") } }) } } func TestMoveOptionsContentHandling(t *testing.T) { tests := []struct { name string opts DualWriteOptions originalData []byte expectedContentToUse []byte expectedUseOriginal bool }{ { name: "move with new content provided", opts: DualWriteOptions{ Path: "new/file.json", OriginalPath: "old/file.json", Data: []byte(`{"updated": "content"}`), }, originalData: []byte(`{"original": "content"}`), expectedContentToUse: []byte(`{"updated": "content"}`), expectedUseOriginal: false, }, { name: "move without new content (nil)", opts: DualWriteOptions{ Path: "new/file.json", OriginalPath: "old/file.json", Data: nil, }, originalData: []byte(`{"original": "content"}`), expectedContentToUse: []byte(`{"original": "content"}`), expectedUseOriginal: true, }, { name: "move without new content (empty slice)", opts: DualWriteOptions{ Path: "new/file.json", OriginalPath: "old/file.json", Data: []byte{}, }, originalData: []byte(`{"original": "content"}`), expectedContentToUse: []byte(`{"original": "content"}`), expectedUseOriginal: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Simulate the content selection logic from moveFile method var destinationData []byte useOriginal := len(tt.opts.Data) == 0 if useOriginal { destinationData = tt.originalData } else { destinationData = tt.opts.Data } assert.Equal(t, tt.expectedUseOriginal, useOriginal, "Should correctly determine whether to use original content") assert.Equal(t, tt.expectedContentToUse, destinationData, "Should select correct content for destination") }) } }