Files
go-unifi/codegen/download_test.go
2025-02-12 00:10:46 +01:00

142 lines
4.3 KiB
Go

package main
import (
"archive/zip"
"net/url"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// Helper function to create a temporary zip file with given entries. 'entries' maps file names to their content.
func createTempZipFile(t *testing.T, entries map[string]string) string {
t.Helper()
tempDir := t.TempDir()
tempFileName := filepath.Join(tempDir, "test.zip")
tempFile, err := os.Create(tempFileName)
require.NoError(t, err, "Failed to create temp zip file")
// We need to truncate and write zip contents
w := zip.NewWriter(tempFile)
for name, content := range entries {
f, err := w.Create(name)
require.NoError(t, err, "Failed to add entry %s", name)
_, err = f.Write([]byte(content))
require.NoError(t, err, "Failed to write content for %s", name)
}
err = w.Close()
require.NoError(t, err, "Failed to close zip writer")
err = tempFile.Close()
require.NoError(t, err, "Failed to close temp file")
return tempFile.Name()
}
// Test when the output directory already exists. In this case, DownloadAndExtract should not call downloadJarFn or extractJSONFn.
func TestDownloadAndExtract_WithExistingDirectory(t *testing.T) {
t.Parallel()
r := require.New(t)
tempDir := t.TempDir()
testURL, _ := url.Parse("http://example.com/test.deb")
err := DownloadAndExtract(*testURL, tempDir)
r.NoError(err, "Expected no error when directory exists")
}
// // Test when output path is not a directory.
func TestDownloadAndExtract_PathNotDirectory(t *testing.T) {
t.Parallel()
r := require.New(t)
tempDir := t.TempDir()
tempFilePath := filepath.Join(tempDir, "dummy")
_, err := os.Create(tempFilePath)
r.NoError(err, "Failed to create temp file")
testURL, _ := url.Parse("http://example.com/test.deb")
err = DownloadAndExtract(*testURL, tempFilePath)
r.Error(err, "Expected error because tempFilePath is not a directory")
r.ErrorContains(err, tempFilePath+" isn't a directory")
}
// // Test extractJSON when the jar file cannot be opened.
func TestExtractJSON_OpenJarError(t *testing.T) {
t.Parallel()
r := require.New(t)
err := extractJSON("nonexisting.jar", t.TempDir())
r.Error(err)
r.ErrorContains(err, "unable to open jar")
}
// Test extractJSON with a valid zip file that contains a JSON file under api/fields/ and no Setting.json (so splitting is skipped).
func TestExtractJSON_NoSettings(t *testing.T) {
t.Parallel()
r := require.New(t)
tempDir := t.TempDir()
jarFile := createTempZipFile(t, map[string]string{"api/fields/dummy.json": "{\"key\": \"value\"}"})
err := extractJSON(jarFile, tempDir)
r.NoError(err)
// Check that dummy.json has been extracted
expectedPath := filepath.Join(tempDir, "dummy.json")
data, err := os.ReadFile(expectedPath)
r.NoError(err, "Expected file %s to exist", expectedPath)
r.JSONEq("{\"key\": \"value\"}", string(data), "Extracted file content mismatch")
}
// Test extractJSON with Setting.json present, so that it splits settings into individual files.
func TestExtractJSON_WithSettings(t *testing.T) {
t.Parallel()
r := require.New(t)
tempDir := t.TempDir()
entries := map[string]string{"api/fields/Setting.json": "{\"foo\": {\"bar\": 1}}"}
jarFile := createTempZipFile(t, entries)
err := extractJSON(jarFile, tempDir)
r.NoError(err)
// Check that the split settings file exists
settingFile := filepath.Join(tempDir, "SettingFoo.json")
data, err := os.ReadFile(settingFile)
r.NoError(err)
r.Contains(string(data), "bar")
}
// Test sanitizeExtractedPath with valid input.
func TestSanitizeExtractedPath_Valid(t *testing.T) {
t.Parallel()
a := assert.New(t)
r := require.New(t)
tempDir := t.TempDir()
filePath := "api/fields/dummy.json"
result, err := sanitizeExtractedPath(filePath, tempDir)
r.NoError(err, "Expected nil error from sanitizeExtractedPath")
expExpected := filepath.Join(tempDir, "dummy.json")
absExpected, err := filepath.Abs(expExpected)
r.NoError(err, "Failed to get abs path")
a.Equal(absExpected, result, "Sanitized path mismatch")
}
// Test extractJSON with invalid Setting.json content, expecting an unmarshal error.
func TestExtractJSON_InvalidSettings(t *testing.T) {
t.Parallel()
r := require.New(t)
tempDir := t.TempDir()
jarFile := createTempZipFile(t, map[string]string{"api/fields/Setting.json": "invalid json"})
err := extractJSON(jarFile, tempDir)
r.Error(err)
r.ErrorContains(err, "unable to unmarshal settings")
}