Your IP : 216.73.216.224


Current Path : /home/hotlineuser/mobius/hotline/
Upload File :
Current File : //home/hotlineuser/mobius/hotline/files_test.go

package hotline

import (
	"bytes"
	"encoding/binary"
	"log/slog"
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
	"golang.org/x/text/encoding"
	"golang.org/x/text/encoding/charmap"
)

func TestEncodeFilePath(t *testing.T) {
	var tests = []struct {
		filePath string
		want     []byte
	}{
		{
			filePath: "kitten1.jpg",
			want: []byte{
				0x00, 0x01, // number of items in path
				0x00, 0x00, // leading path separator
				0x0b,                                                             // length of next path section (11)
				0x6b, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x31, 0x2e, 0x6a, 0x70, 0x67, // kitten1.jpg
			},
		},
		{
			filePath: "foo/kitten1.jpg",
			want: []byte{
				0x00, 0x02, // number of items in path
				0x00, 0x00,
				0x03,
				0x66, 0x6f, 0x6f,
				0x00, 0x00, // leading path separator
				0x0b,                                                             // length of next path section (11)
				0x6b, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x31, 0x2e, 0x6a, 0x70, 0x67, // kitten1.jpg
			},
		},
	}

	for _, test := range tests {
		got := EncodeFilePath(test.filePath)
		if !bytes.Equal(got, test.want) {
			t.Errorf("field mismatch:  want: %#v got: %#v", test.want, got)
		}
	}
}

func TestCalcTotalSize(t *testing.T) {
	cwd, _ := os.Getwd()
	defer func() { _ = os.Chdir(cwd) }()

	_ = os.Chdir("test/config/Files")

	type args struct {
		filePath string
	}
	tests := []struct {
		name    string
		args    args
		want    []byte
		wantErr bool
	}{
		{
			name: "Foo",
			args: args{
				filePath: "test",
			},
			want:    []byte{0x00, 0x00, 0x18, 0x00},
			wantErr: false,
		},
		// TODO: Add more test cases.
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := CalcTotalSize(tt.args.filePath)
			if (err != nil) != tt.wantErr {
				t.Errorf("CalcTotalSize() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !assert.Equal(t, tt.want, got) {
				t.Errorf("CalcTotalSize() got = %v, want %v", got, tt.want)
			}
		})
	}
}

func createTestDirStructure(baseDir string, structure map[string]string) error {
	// First pass: create directories
	for path, content := range structure {
		if content == "dir" {
			if err := os.MkdirAll(filepath.Join(baseDir, path), 0755); err != nil {
				return err
			}
		}
	}

	// Second pass: create files
	for path, content := range structure {
		if content != "dir" {
			fullPath := filepath.Join(baseDir, path)
			dir := filepath.Dir(fullPath)
			if err := os.MkdirAll(dir, 0755); err != nil {
				return err
			}
			if err := os.WriteFile(fullPath, []byte(content), 0644); err != nil {
				return err
			}
		}
	}
	return nil
}

func TestCalcItemCount(t *testing.T) {
	tests := []struct {
		name      string
		structure map[string]string
		expected  uint16
	}{
		{
			name: "directory with files",
			structure: map[string]string{
				"file1.txt":        "content1",
				"file2.txt":        "content2",
				"subdir/":          "dir",
				"subdir/file3.txt": "content3",
			},
			expected: 4, // 3 files and 1 directory, should count 4 items
		},
		{
			name: "directory with hidden files",
			structure: map[string]string{
				".hiddenfile": "hiddencontent",
				"file1.txt":   "content1",
			},
			expected: 1, // 1 non-hidden file
		},
		{
			name:      "empty directory",
			structure: map[string]string{},
			expected:  0, // 0 files
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Create a temporary directory for the test
			tempDir, err := os.MkdirTemp("", "test")
			if err != nil {
				t.Fatalf("Failed to create temp dir: %v", err)
			}
			defer func() { _ = os.RemoveAll(tempDir) }()

			// Create the test directory structure
			if err := createTestDirStructure(tempDir, tt.structure); err != nil {
				t.Fatalf("Failed to create test dir structure: %v", err)
			}

			// Calculate item count
			result, err := CalcItemCount(tempDir)
			if err != nil {
				t.Fatalf("CalcItemCount returned an error: %v", err)
			}

			// Convert result to uint16
			count := binary.BigEndian.Uint16(result)
			if count != tt.expected {
				t.Errorf("expected %d, got %d", tt.expected, count)
			}
		})
	}
}

func TestGetFileNameList_Encoding(t *testing.T) {
	// Create a temp dir with a file whose name contains a non-ASCII UTF-8 character.
	tempDir, err := os.MkdirTemp("", "test-encoding")
	if err != nil {
		t.Fatalf("Failed to create temp dir: %v", err)
	}
	defer func() { _ = os.RemoveAll(tempDir) }()

	// "café.txt" — the é is UTF-8 on disk
	if err := os.WriteFile(filepath.Join(tempDir, "café.txt"), []byte("hello"), 0644); err != nil {
		t.Fatalf("Failed to create test file: %v", err)
	}

	// FileNameWithInfoHeader is 20 bytes: Type[4] + Creator[4] + FileSize[4] + RSVD[4] + NameScript[2] + NameSize[2]
	const headerLen = 20

	extractName := func(fields []Field) string {
		for _, f := range fields {
			if f.Type == FieldFileNameWithInfo {
				nameSize := binary.BigEndian.Uint16(f.Data[headerLen-2 : headerLen])
				return string(f.Data[headerLen : headerLen+nameSize])
			}
		}
		return ""
	}

	t.Run("macintosh encoder converts UTF-8 to Mac Roman", func(t *testing.T) {
		fields, err := GetFileNameList(tempDir, nil, charmap.Macintosh.NewEncoder(), slog.Default())
		assert.NoError(t, err)
		assert.Len(t, fields, 1)

		name := extractName(fields)
		// Mac Roman é is 0x8e, so "café.txt" becomes "caf\x8e.txt"
		assert.Equal(t, "caf\x8e.txt", name)
	})

	t.Run("nop encoder passes UTF-8 through unchanged", func(t *testing.T) {
		fields, err := GetFileNameList(tempDir, nil, encoding.Nop.NewEncoder(), slog.Default())
		assert.NoError(t, err)
		assert.Len(t, fields, 1)

		name := extractName(fields)
		assert.Equal(t, "café.txt", name)
	})
}