返回 DeepSeek-Reasonix
shortcut_command_windows_test.go
根目录 / internal / desktoplauncher / shortcut_command_windows_test.go
1 //go:build windows
2
3 package desktoplauncher
4
5 import (
6 "context"
7 "encoding/json"
8 "os"
9 "os/exec"
10 "path/filepath"
11 "testing"
12 "time"
13 )
14
15 func TestLauncherMaintenanceRepairsWithoutStartingDesktop(t *testing.T) {
16 root := t.TempDir()
17 exe, err := os.Executable()
18 if err != nil {
19 t.Fatal(err)
20 }
21 data, err := os.ReadFile(exe)
22 if err != nil {
23 t.Fatal(err)
24 }
25 launcher := filepath.Join(root, "reasonix-launcher.exe")
26 if err := os.WriteFile(launcher, data, 0o700); err != nil {
27 t.Fatal(err)
28 }
29 target := filepath.Join(root, "versions", "v1.38.6", "app", "Reasonix.exe")
30 if err := os.MkdirAll(filepath.Dir(target), 0o700); err != nil {
31 t.Fatal(err)
32 }
33 if err := os.WriteFile(target, []byte("not executable: maintenance must not start a shell"), 0o600); err != nil {
34 t.Fatal(err)
35 }
36 link := filepath.Join(root, "Reasonix.lnk")
37 script := filepath.Join(root, "shortcut.ps1")
38 const source = `param($Link, $Target, $Action)
39 $ErrorActionPreference = 'Stop'
40 $shortcut = (New-Object -ComObject WScript.Shell).CreateShortcut($Link)
41 if ($Action -eq 'create') {
42 $shortcut.TargetPath = $Target
43 $shortcut.Arguments = '--session "workspace name"'
44 $shortcut.Save()
45 } else {
46 $item = (New-Object -ComObject Shell.Application).NameSpace((Split-Path $Link)).ParseName((Split-Path $Link -Leaf))
47 @{ Target = $shortcut.TargetPath; Arguments = $shortcut.Arguments; ID = $item.ExtendedProperty('System.AppUserModel.ID') } | ConvertTo-Json -Compress
48 }
49 `
50 if err := os.WriteFile(script, []byte(source), 0o600); err != nil {
51 t.Fatal(err)
52 }
53 run := func(binary string, args ...string) []byte {
54 t.Helper()
55 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
56 defer cancel()
57 cmd := exec.CommandContext(ctx, binary, args...)
58 cmd.Env = append(os.Environ(), consoleTestEnv+"="+root)
59 output, err := cmd.CombinedOutput()
60 if err != nil {
61 t.Fatalf("%s: %v\n%s", filepath.Base(binary), err, output)
62 }
63 return output
64 }
65 run("powershell.exe", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", script, link, target, "create")
66 run(launcher, "--repair-shortcuts", link)
67 output := run("powershell.exe", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", script, link, target, "read")
68 var got struct{ Target, Arguments, ID string }
69 if err := json.Unmarshal(output, &got); err != nil {
70 t.Fatalf("read shortcut: %v: %s", err, output)
71 }
72 targetInfo, targetErr := os.Stat(got.Target)
73 launcherInfo, launcherErr := os.Stat(launcher)
74 if targetErr != nil || launcherErr != nil || !os.SameFile(targetInfo, launcherInfo) || got.ID != "io.reasonix.desktop" || got.Arguments != `--session "workspace name"` {
75 t.Fatalf("maintenance shortcut = %+v", got)
76 }
77 }
78
78 lines GO