返回 DeepSeek-Reasonix
updater_mac_bundle_test.go
根目录 / desktop / updater_mac_bundle_test.go
1 //go:build darwin
2
3 package main
4
5 import (
6 "os"
7 "path/filepath"
8 "strings"
9 "testing"
10 )
11
12 func writeMacBundleFixture(t *testing.T, root, identifier string) string {
13 t.Helper()
14 contents := filepath.Join(root, "Reasonix.app", "Contents")
15 if err := os.MkdirAll(filepath.Join(contents, "Resources", "service"), 0o755); err != nil {
16 t.Fatal(err)
17 }
18 plist := `<?xml version="1.0" encoding="UTF-8"?>
19 <plist version="1.0"><dict><key>CFBundleIdentifier</key><string>` + identifier + `</string></dict></plist>`
20 if err := os.WriteFile(filepath.Join(contents, "Info.plist"), []byte(plist), 0o644); err != nil {
21 t.Fatal(err)
22 }
23 return contents
24 }
25
26 func TestMacAppBundleForExecutableSupportsPackagedLayouts(t *testing.T) {
27 root := filepath.Join(t.TempDir(), "parent.app cache", "中文目录")
28 contents := writeMacBundleFixture(t, root, macBundleID)
29 for _, relative := range []string{"MacOS/reasonix-desktop", "Resources/service/reasonix-desktop"} {
30 exe := filepath.Join(contents, filepath.FromSlash(relative))
31 if err := os.MkdirAll(filepath.Dir(exe), 0o755); err != nil {
32 t.Fatal(err)
33 }
34 if err := os.WriteFile(exe, []byte("service"), 0o755); err != nil {
35 t.Fatal(err)
36 }
37 got, err := macAppBundleForExecutable(exe)
38 if err != nil || got != filepath.Dir(contents) {
39 t.Fatalf("%s: bundle=%q err=%v", relative, got, err)
40 }
41 }
42 }
43
44 func TestMacAppBundleForExecutableResolvesCompatibilitySymlink(t *testing.T) {
45 contents := writeMacBundleFixture(t, t.TempDir(), macBundleID)
46 target := filepath.Join(contents, "Resources", "service", "reasonix-desktop")
47 if err := os.WriteFile(target, []byte("service"), 0o755); err != nil {
48 t.Fatal(err)
49 }
50 link := filepath.Join(contents, "MacOS", "reasonix-desktop")
51 if err := os.MkdirAll(filepath.Dir(link), 0o755); err != nil {
52 t.Fatal(err)
53 }
54 if err := os.Symlink(filepath.Join("..", "Resources", "service", "reasonix-desktop"), link); err != nil {
55 t.Fatal(err)
56 }
57 if got, err := macAppBundleForExecutable(link); err != nil || got != filepath.Dir(contents) {
58 t.Fatalf("bundle=%q err=%v", got, err)
59 }
60 }
61
62 func TestMacAppBundleForExecutableRejectsInvalidInputs(t *testing.T) {
63 outside := filepath.Join(t.TempDir(), "reasonix-desktop")
64 if err := os.WriteFile(outside, []byte("service"), 0o755); err != nil {
65 t.Fatal(err)
66 }
67 if _, err := macAppBundleForExecutable(outside); err == nil || !strings.Contains(err.Error(), "not inside") {
68 t.Fatalf("outside error = %v", err)
69 }
70
71 contents := writeMacBundleFixture(t, t.TempDir(), "example.invalid")
72 exe := filepath.Join(contents, "Resources", "service", "reasonix-desktop")
73 if err := os.WriteFile(exe, []byte("service"), 0o755); err != nil {
74 t.Fatal(err)
75 }
76 if _, err := macAppBundleForExecutable(exe); err == nil || !strings.Contains(err.Error(), "identifier") {
77 t.Fatalf("identifier error = %v", err)
78 }
79
80 malformedContents := writeMacBundleFixture(t, t.TempDir(), macBundleID)
81 malformedExe := filepath.Join(malformedContents, "Resources", "service", "reasonix-desktop")
82 if err := os.WriteFile(malformedExe, []byte("service"), 0o755); err != nil {
83 t.Fatal(err)
84 }
85 if err := os.WriteFile(filepath.Join(malformedContents, "Info.plist"), []byte("not a plist"), 0o644); err != nil {
86 t.Fatal(err)
87 }
88 if _, err := macAppBundleForExecutable(malformedExe); err == nil || !strings.Contains(err.Error(), "read bundle identifier") {
89 t.Fatalf("malformed plist error = %v", err)
90 }
91
92 broken := filepath.Join(contents, "MacOS", "broken")
93 if err := os.MkdirAll(filepath.Dir(broken), 0o755); err != nil {
94 t.Fatal(err)
95 }
96 if err := os.Symlink("missing", broken); err != nil {
97 t.Fatal(err)
98 }
99 if _, err := macAppBundleForExecutable(broken); err == nil || !strings.Contains(err.Error(), "resolve") {
100 t.Fatalf("broken link error = %v", err)
101 }
102 }
103
103 lines GO