Файлы без stem (.env, .gitignore, .npmrc) давали FileDedupKey="", и findWithinFolderDuplicates/findCrossFolderDuplicates считали их одной группой дублей и удаляли лишние. Пустой ключ больше не образует группу.
128 lines
4.4 KiB
Go
128 lines
4.4 KiB
Go
package onlyoffice
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestFileDedupKey(t *testing.T) {
|
|
title := "OO-HONDA-7-INDEX.docx"
|
|
exst := ".docx"
|
|
f := &FileEntry{Title: &title, FileExst: &exst}
|
|
if got := FileDedupKey(f); got != "OO-HONDA-7-INDEX|docx" {
|
|
t.Fatalf("got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestFindFilesByDedupKey(t *testing.T) {
|
|
a := &FileEntry{Title: strPtr("foo.docx"), FileExst: strPtr(".docx")}
|
|
b := &FileEntry{Title: strPtr("foo.md"), FileExst: strPtr(".md")}
|
|
files := []*FileEntry{a, b}
|
|
got := FindFilesByDedupKey(files, "foo", ".docx")
|
|
if len(got) != 1 || got[0] != a {
|
|
t.Fatalf("got %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestFindWithinFolderDuplicates(t *testing.T) {
|
|
t1 := time.Date(2026, 8, 27, 16, 0, 0, 0, time.UTC)
|
|
t2 := t1.Add(time.Hour)
|
|
old := &FileEntry{ID: jsonNum("1"), Title: strPtr("idx.docx"), FileExst: strPtr(".docx"), Updated: &t1}
|
|
new := &FileEntry{ID: jsonNum("2"), Title: strPtr("idx.docx"), FileExst: strPtr(".docx"), Updated: &t2}
|
|
indexed := []ProjectFolderFile{
|
|
{FolderID: "490", FolderTitle: "00-Index", File: old},
|
|
{FolderID: "490", FolderTitle: "00-Index", File: new},
|
|
}
|
|
groups := findWithinFolderDuplicates(indexed)
|
|
if len(groups) != 1 {
|
|
t.Fatalf("groups=%d", len(groups))
|
|
}
|
|
if FileEntryNumericID(groups[0].Keep) != 2 {
|
|
t.Fatalf("keep id=%d", FileEntryNumericID(groups[0].Keep))
|
|
}
|
|
if len(groups[0].Remove) != 1 || FileEntryNumericID(groups[0].Remove[0]) != 1 {
|
|
t.Fatalf("remove=%v", groups[0].Remove)
|
|
}
|
|
}
|
|
|
|
func TestCrossFolderPrefersNonTrash(t *testing.T) {
|
|
t1 := time.Date(2026, 8, 27, 18, 0, 0, 0, time.UTC)
|
|
t2 := t1.Add(-time.Hour)
|
|
trash := &FileEntry{ID: jsonNum("10"), Title: strPtr("INDEX.md"), FileExst: strPtr(".md"), Updated: &t1}
|
|
good := &FileEntry{ID: jsonNum("20"), Title: strPtr("INDEX.md"), FileExst: strPtr(".md"), Updated: &t2}
|
|
indexed := []ProjectFolderFile{
|
|
{FolderID: "493", FolderTitle: "_trash-md", File: trash},
|
|
{FolderID: "492", FolderTitle: "OCR", File: good},
|
|
}
|
|
groups := findCrossFolderDuplicates(indexed)
|
|
if len(groups) != 1 {
|
|
t.Fatalf("groups=%d", len(groups))
|
|
}
|
|
if FileEntryNumericID(groups[0].Keep) != 20 {
|
|
t.Fatalf("keep id=%d", FileEntryNumericID(groups[0].Keep))
|
|
}
|
|
}
|
|
|
|
func TestMergeProjectRootForDedupe(t *testing.T) {
|
|
old := &FileEntry{ID: jsonNum("1"), Title: strPtr("a.docx"), FileExst: strPtr(".docx")}
|
|
newer := &FileEntry{ID: jsonNum("2"), Title: strPtr("a.docx"), FileExst: strPtr(".docx")}
|
|
rootFiles := []*FileEntry{old, newer}
|
|
folders, byFolder := mergeProjectRootForDedupe("489", nil, nil, rootFiles)
|
|
if len(folders) != 1 || folders[0].ID.String() != "489" {
|
|
t.Fatalf("folders=%+v", folders)
|
|
}
|
|
if len(byFolder["489"]) != 2 {
|
|
t.Fatalf("root files=%d", len(byFolder["489"]))
|
|
}
|
|
groups := findWithinFolderDuplicates([]ProjectFolderFile{
|
|
{FolderID: "489", FolderTitle: "(project root)", File: old},
|
|
{FolderID: "489", FolderTitle: "(project root)", File: newer},
|
|
})
|
|
if len(groups) != 1 {
|
|
t.Fatalf("groups=%d", len(groups))
|
|
}
|
|
}
|
|
|
|
func TestFindDuplicatesSkipsEmptyKey(t *testing.T) {
|
|
// Dotfiles (".env", ".gitignore", ".npmrc") normalize to an empty stem, so
|
|
// FileDedupKey is "". They are not duplicates of each other and must never
|
|
// form a dedup group that would delete one of them.
|
|
env := &FileEntry{ID: jsonNum("1"), Title: strPtr(".env")}
|
|
gitignore := &FileEntry{ID: jsonNum("2"), Title: strPtr(".gitignore")}
|
|
npmrc := &FileEntry{ID: jsonNum("3"), Title: strPtr(".npmrc")}
|
|
if FileDedupKey(env) != "" || FileDedupKey(gitignore) != "" || FileDedupKey(npmrc) != "" {
|
|
t.Fatalf("dotfiles should have empty dedup key")
|
|
}
|
|
within := []ProjectFolderFile{
|
|
{FolderID: "500", FolderTitle: "Cfg", File: env},
|
|
{FolderID: "500", FolderTitle: "Cfg", File: gitignore},
|
|
}
|
|
if groups := findWithinFolderDuplicates(within); len(groups) != 0 {
|
|
t.Fatalf("within-folder empty-key groups = %d, want 0 (%+v)", len(groups), groups)
|
|
}
|
|
cross := []ProjectFolderFile{
|
|
{FolderID: "500", FolderTitle: "Cfg", File: env},
|
|
{FolderID: "501", FolderTitle: "Other", File: npmrc},
|
|
}
|
|
if groups := findCrossFolderDuplicates(cross); len(groups) != 0 {
|
|
t.Fatalf("cross-folder empty-key groups = %d, want 0 (%+v)", len(groups), groups)
|
|
}
|
|
}
|
|
|
|
func TestIsTrashFolderTitle(t *testing.T) {
|
|
if !IsTrashFolderTitle("_trash-md") {
|
|
t.Fatal("expected trash")
|
|
}
|
|
if IsTrashFolderTitle("00-Index") {
|
|
t.Fatal("expected not trash")
|
|
}
|
|
}
|
|
|
|
func strPtr(s string) *string { return &s }
|
|
|
|
func jsonNum(s string) *json.Number {
|
|
n := json.Number(s)
|
|
return &n
|
|
}
|