返回 DeepSeek-Reasonix
icon_repair_darwin_test.go
根目录 / desktop / icon_repair_darwin_test.go
1 //go:build darwin && cgo
2
3 package main
4
5 import (
6 "net/url"
7 "os"
8 "path/filepath"
9 "testing"
10 )
11
12 func writeReasonixTestBundle(t *testing.T, path string) {
13 t.Helper()
14 if err := os.MkdirAll(filepath.Join(path, "Contents"), 0o755); err != nil {
15 t.Fatal(err)
16 }
17 plist := `<?xml version="1.0" encoding="UTF-8"?>
18 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
19 <plist version="1.0"><dict><key>CFBundleIdentifier</key><string>com.wails.reasonix-desktop</string></dict></plist>`
20 if err := os.WriteFile(filepath.Join(path, "Contents", "Info.plist"), []byte(plist), 0o644); err != nil {
21 t.Fatal(err)
22 }
23 }
24
25 func TestRepairMacDesktopAliasesRetargetsBrokenReasonixAlias(t *testing.T) {
26 root := t.TempDir()
27 desktop := filepath.Join(root, "Desktop")
28 if err := os.Mkdir(desktop, 0o755); err != nil {
29 t.Fatal(err)
30 }
31 oldApp := filepath.Join(root, "Reasonix.app.reasonix-update-backup")
32 currentApp := filepath.Join(root, "Reasonix.app")
33 writeReasonixTestBundle(t, oldApp)
34 writeReasonixTestBundle(t, currentApp)
35 alias := filepath.Join(desktop, "Reasonix")
36 if err := writeMacAlias(oldApp, alias); err != nil {
37 t.Fatal(err)
38 }
39 if err := os.RemoveAll(oldApp); err != nil {
40 t.Fatal(err)
41 }
42
43 if err := repairMacDesktopAliases(desktop, currentApp); err != nil {
44 t.Fatal(err)
45 }
46 resolved, err := resolveMacAlias(alias)
47 if err != nil {
48 t.Fatal(err)
49 }
50 want, err := filepath.EvalSymlinks(currentApp)
51 if err != nil {
52 t.Fatal(err)
53 }
54 if resolved != want {
55 t.Fatalf("alias target = %q, want %q", resolved, want)
56 }
57 }
58
59 func TestRepairMacDesktopAliasesPreservesUnrelatedBrokenAlias(t *testing.T) {
60 root := t.TempDir()
61 desktop := filepath.Join(root, "Desktop")
62 if err := os.Mkdir(desktop, 0o755); err != nil {
63 t.Fatal(err)
64 }
65 oldTarget := filepath.Join(root, "Other.app")
66 currentApp := filepath.Join(root, "Reasonix.app")
67 writeReasonixTestBundle(t, oldTarget)
68 writeReasonixTestBundle(t, currentApp)
69 alias := filepath.Join(desktop, "Other")
70 if err := writeMacAlias(oldTarget, alias); err != nil {
71 t.Fatal(err)
72 }
73 before, err := os.ReadFile(alias)
74 if err != nil {
75 t.Fatal(err)
76 }
77 if err := os.RemoveAll(oldTarget); err != nil {
78 t.Fatal(err)
79 }
80
81 if err := repairMacDesktopAliases(desktop, currentApp); err != nil {
82 t.Fatal(err)
83 }
84 after, err := os.ReadFile(alias)
85 if err != nil {
86 t.Fatal(err)
87 }
88 if string(after) != string(before) {
89 t.Fatal("unrelated broken Finder alias was rewritten")
90 }
91 }
92
93 func TestRepairMacDesktopAliasesPreservesUnrelatedHealthyAlias(t *testing.T) {
94 root := t.TempDir()
95 desktop := filepath.Join(root, "Desktop")
96 if err := os.Mkdir(desktop, 0o755); err != nil {
97 t.Fatal(err)
98 }
99 otherApp := filepath.Join(root, "Other.app")
100 currentApp := filepath.Join(root, "Reasonix.app")
101 if err := os.MkdirAll(filepath.Join(otherApp, "Contents"), 0o755); err != nil {
102 t.Fatal(err)
103 }
104 writeReasonixTestBundle(t, currentApp)
105 alias := filepath.Join(desktop, "Other")
106 if err := writeMacAlias(otherApp, alias); err != nil {
107 t.Fatal(err)
108 }
109 before, err := os.ReadFile(alias)
110 if err != nil {
111 t.Fatal(err)
112 }
113
114 if err := repairMacDesktopAliases(desktop, currentApp); err != nil {
115 t.Fatal(err)
116 }
117 after, err := os.ReadFile(alias)
118 if err != nil {
119 t.Fatal(err)
120 }
121 if string(after) != string(before) {
122 t.Fatal("unrelated healthy Finder alias was rewritten")
123 }
124 }
125
126 func TestRepairMacDesktopAliasesPreservesOrdinaryReasonixFile(t *testing.T) {
127 root := t.TempDir()
128 desktop := filepath.Join(root, "Desktop")
129 if err := os.Mkdir(desktop, 0o755); err != nil {
130 t.Fatal(err)
131 }
132 currentApp := filepath.Join(root, "Reasonix.app")
133 writeReasonixTestBundle(t, currentApp)
134 ordinary := filepath.Join(desktop, "Reasonix")
135 const content = "user-owned file"
136 if err := os.WriteFile(ordinary, []byte(content), 0o600); err != nil {
137 t.Fatal(err)
138 }
139
140 if err := repairMacDesktopAliases(desktop, currentApp); err != nil {
141 t.Fatal(err)
142 }
143 got, err := os.ReadFile(ordinary)
144 if err != nil {
145 t.Fatal(err)
146 }
147 if string(got) != content {
148 t.Fatalf("ordinary Reasonix file changed to %q", got)
149 }
150 }
151
152 func TestRepairMacDesktopAliasesPreservesHealthyReasonixAlias(t *testing.T) {
153 root := t.TempDir()
154 desktop := filepath.Join(root, "Desktop")
155 if err := os.Mkdir(desktop, 0o755); err != nil {
156 t.Fatal(err)
157 }
158 currentApp := filepath.Join(root, "Reasonix.app")
159 writeReasonixTestBundle(t, currentApp)
160 alias := filepath.Join(desktop, "Reasonix")
161 if err := writeMacAlias(currentApp, alias); err != nil {
162 t.Fatal(err)
163 }
164 before, err := os.ReadFile(alias)
165 if err != nil {
166 t.Fatal(err)
167 }
168
169 if err := repairMacDesktopAliases(desktop, currentApp); err != nil {
170 t.Fatal(err)
171 }
172 after, err := os.ReadFile(alias)
173 if err != nil {
174 t.Fatal(err)
175 }
176 if string(after) != string(before) {
177 t.Fatal("healthy Finder alias was rewritten")
178 }
179 }
180
181 func TestRepairMacDesktopAliasesRetargetsCustomNamedInstalledAlias(t *testing.T) {
182 root := t.TempDir()
183 desktop := filepath.Join(root, "Desktop")
184 if err := os.Mkdir(desktop, 0o755); err != nil {
185 t.Fatal(err)
186 }
187 oldApp := filepath.Join(root, "Reasonix-old.app")
188 currentApp := filepath.Join(root, "Reasonix.app")
189 writeReasonixTestBundle(t, oldApp)
190 writeReasonixTestBundle(t, currentApp)
191 alias := filepath.Join(desktop, "My Reasonix")
192 if err := writeMacAlias(oldApp, alias); err != nil {
193 t.Fatal(err)
194 }
195
196 if err := repairMacDesktopAliases(desktop, currentApp); err != nil {
197 t.Fatal(err)
198 }
199 resolved, err := resolveMacAlias(alias)
200 if err != nil {
201 t.Fatal(err)
202 }
203 want, err := filepath.EvalSymlinks(currentApp)
204 if err != nil {
205 t.Fatal(err)
206 }
207 if resolved != want {
208 t.Fatalf("custom alias target = %q, want %q", resolved, want)
209 }
210 }
211
212 func TestMacBundleOwnershipRejectsNonFileURL(t *testing.T) {
213 owned, err := macURLReferencesReasonixBundle("https://example.com/Reasonix.app")
214 if err != nil {
215 t.Fatal(err)
216 }
217 if owned {
218 t.Fatal("non-file URL was classified as a Reasonix application bundle")
219 }
220 }
221
222 func TestMacBundleOwnershipRecognizesInstalledReasonixBundle(t *testing.T) {
223 app := filepath.Join(t.TempDir(), "Reasonix.app")
224 writeReasonixTestBundle(t, app)
225 owned, err := macURLReferencesReasonixBundle((&url.URL{Scheme: "file", Path: app}).String())
226 if err != nil {
227 t.Fatal(err)
228 }
229 if !owned {
230 t.Fatal("installed Reasonix application bundle was not recognized")
231 }
232 }
233
234 func TestRepairMacDesktopAliasesAllowsEmptyFirstInstallDesktop(t *testing.T) {
235 root := t.TempDir()
236 desktop := filepath.Join(root, "Desktop")
237 if err := os.Mkdir(desktop, 0o755); err != nil {
238 t.Fatal(err)
239 }
240 currentApp := filepath.Join(root, "Reasonix.app")
241 writeReasonixTestBundle(t, currentApp)
242
243 if err := repairMacDesktopAliases(desktop, currentApp); err != nil {
244 t.Fatal(err)
245 }
246 entries, err := os.ReadDir(desktop)
247 if err != nil {
248 t.Fatal(err)
249 }
250 if len(entries) != 0 {
251 t.Fatalf("first-install desktop gained unexpected entries: %v", entries)
252 }
253 }
254
255 func TestRepairMacDesktopAliasesAllowsMissingFirstInstallDesktop(t *testing.T) {
256 root := t.TempDir()
257 currentApp := filepath.Join(root, "Reasonix.app")
258 writeReasonixTestBundle(t, currentApp)
259
260 if err := repairMacDesktopAliases(filepath.Join(root, "Desktop"), currentApp); err != nil {
261 t.Fatal(err)
262 }
263 }
264
264 lines GO