aboutsummaryrefslogtreecommitdiff
path: root/internal/trash/trash_test.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 21:28:11 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 21:28:11 +0200
commit7e0d8494074398854f30feb75211c52ea5cc2635 (patch)
treef8ab4b7ce5dac8e75aded9ef4d4cd488d948d339 /internal/trash/trash_test.go
parentaca389f0e63713b890214cad950ac3aee7e6aaf4 (diff)
downloadkrino-7e0d8494074398854f30feb75211c52ea5cc2635.tar.gz
krino-7e0d8494074398854f30feb75211c52ea5cc2635.zip
plan 9: trash skips orphaned names, fits long names, exposes InfoPath
Diffstat (limited to 'internal/trash/trash_test.go')
-rw-r--r--internal/trash/trash_test.go61
1 files changed, 61 insertions, 0 deletions
diff --git a/internal/trash/trash_test.go b/internal/trash/trash_test.go
index 24f4ea8..9c3eed2 100644
--- a/internal/trash/trash_test.go
+++ b/internal/trash/trash_test.go
@@ -8,6 +8,7 @@ import (
"path/filepath"
"strings"
"testing"
+ "unicode/utf8"
)
// sandbox points XDG_DATA_HOME at a temporary tree, so the real Trash is
@@ -171,3 +172,63 @@ func TestPutRefusesOtherFilesystem(t *testing.T) {
t.Errorf("a refused Put left %d orphaned info files", len(entries))
}
}
+
+// TestPutSkipsOrphanedFiles: a name already taken in files/ - left there
+// without its trashinfo - is not overwritten; Put takes the next free name
+// (review planapply F5).
+func TestPutSkipsOrphanedFiles(t *testing.T) {
+ h := sandbox(t)
+ orphan := filepath.Join(Dir(), "files", "a.pdf")
+ write(t, orphan, "OLD TRASHED CONTENT")
+ src := filepath.Join(h, "a.pdf")
+ write(t, src, "new")
+ entry, err := Put(src)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if entry != "a_1.pdf" {
+ t.Errorf("entry = %q, want a_1.pdf", entry)
+ }
+ if b, _ := os.ReadFile(orphan); string(b) != "OLD TRASHED CONTENT" {
+ t.Errorf("the orphaned file was overwritten: %q", b)
+ }
+}
+
+// TestPutTrashesLongNames: a name near the 255-byte limit still goes to the
+// Trash - its entry name is shortened so ".trashinfo" and a suffix fit - and
+// comes back under its full original name (review planapply F6).
+func TestPutTrashesLongNames(t *testing.T) {
+ h := sandbox(t)
+ name := strings.Repeat("ż", 123) + ".pdf" // 246 + 4 = 250 bytes
+ src := filepath.Join(h, name)
+ write(t, src, "long")
+ entry, err := Put(src)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(entry) > 239 || !strings.HasSuffix(entry, ".pdf") || !utf8.ValidString(entry) {
+ t.Errorf("entry %q (%d bytes) does not fit, lost its extension, or split a character", entry, len(entry))
+ }
+ restored, err := Restore(entry)
+ if err != nil || restored != src {
+ t.Errorf("Restore = %q, %v; want %q", restored, err, src)
+ }
+}
+
+// TestInfoPath: the original path a trash entry records, and refusal of an
+// entry name that is not a plain name inside the Trash.
+func TestInfoPath(t *testing.T) {
+ h := sandbox(t)
+ src := filepath.Join(h, "dl", "a.pdf")
+ write(t, src, "x")
+ entry, err := Put(src)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if p, err := InfoPath(entry); err != nil || p != src {
+ t.Errorf("InfoPath = %q, %v; want %q", p, err, src)
+ }
+ if _, err := InfoPath("../x"); err == nil {
+ t.Error("InfoPath accepted ../x")
+ }
+}