Files
MyGoNavi/internal/app/window_zoom_windows_test.go
Syngnat 0cde96844d 🐛 fix(windows): 修复在线更新挂起与 WebView2 启动闪退
- 隐藏并释放 Windows 更新脚本进程,避免在线更新打开 cmd 并挂起
- 为更新脚本等待宿主进程退出增加超时保护
- 收窄自动 WebView2 zoom reset 触发条件并补充异常兜底
- 补充 Windows 更新启动与窗口缩放回归测试
Refs #468
2026-05-16 22:13:24 +08:00

110 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//go:build windows
package app
import (
"context"
"strings"
"sync/atomic"
"testing"
)
// fakeChromium 模仿 *edge.Chromium 的接口:只需要 exported 的 PutZoomFactor(float64) 方法。
// 用于在不依赖真实 wails / WebView2 的情况下验证反射路径。
type fakeChromium struct {
called atomic.Int32
last atomic.Value // float64
}
func (f *fakeChromium) PutZoomFactor(factor float64) {
f.called.Add(1)
f.last.Store(factor)
}
// fakeFrontend 模仿 wails 的 internal/frontend/desktop/windows.Frontend
// unexported 字段 chromium 是 *fakeChromium 类型exported method PutZoomFactor
// 反射代码不依赖具体类型名,只检查 method signature。
type fakeFrontend struct {
chromium *fakeChromium
}
type panicChromium struct{}
func (p *panicChromium) PutZoomFactor(float64) {
panic("webview2 zoom reset failed")
}
type panicFrontend struct {
chromium *panicChromium
}
// 测试必须用 wails 一致的 string key "frontend" 作为 context.WithValue 的 key
// 否则反射拿不到。go vet 会警告 string key用本地 stringContextKey 帮助函数封装来抑制。
// 这层封装等价于直接传字符串字面量,行为完全一致。
func stringContextKey(key string) any {
type contextKeyAlias = string
return contextKeyAlias(key)
}
func TestResetWebViewZoomFactorCallsPutZoomFactor(t *testing.T) {
chromium := &fakeChromium{}
ctx := context.WithValue(context.Background(), stringContextKey("frontend"), &fakeFrontend{chromium: chromium})
if err := resetWebViewZoomFactor(ctx, 1.0); err != nil {
t.Fatalf("expected reset to succeed against fake frontend, got %v", err)
}
if got := chromium.called.Load(); got != 1 {
t.Fatalf("expected PutZoomFactor called exactly once, got %d", got)
}
if got, _ := chromium.last.Load().(float64); got != 1.0 {
t.Fatalf("expected factor 1.0, got %v", got)
}
}
func TestResetWebViewZoomFactorErrorsWhenChromiumFieldMissing(t *testing.T) {
type fakeFrontendWithoutChromium struct {
other string
}
ctx := context.WithValue(context.Background(), stringContextKey("frontend"), &fakeFrontendWithoutChromium{})
err := resetWebViewZoomFactor(ctx, 1.0)
if err == nil {
t.Fatal("expected error when chromium field is missing, got nil")
}
if !strings.Contains(err.Error(), "chromium") {
t.Fatalf("expected error to mention chromium, got %v", err)
}
}
func TestResetWebViewZoomFactorErrorsWhenChromiumNil(t *testing.T) {
ctx := context.WithValue(context.Background(), stringContextKey("frontend"), &fakeFrontend{chromium: nil})
err := resetWebViewZoomFactor(ctx, 1.0)
if err == nil {
t.Fatal("expected error when chromium is nil, got nil")
}
if !strings.Contains(err.Error(), "nil") {
t.Fatalf("expected error to mention nil, got %v", err)
}
}
func TestResetWebViewZoomFactorErrorsWhenFrontendMissing(t *testing.T) {
err := resetWebViewZoomFactor(context.Background(), 1.0)
if err == nil {
t.Fatal("expected error when frontend not in ctx, got nil")
}
if !strings.Contains(err.Error(), "frontend") {
t.Fatalf("expected error to mention frontend, got %v", err)
}
}
func TestResetWebViewZoomFactorRecoversFromPutZoomFactorPanic(t *testing.T) {
ctx := context.WithValue(context.Background(), stringContextKey("frontend"), &panicFrontend{chromium: &panicChromium{}})
err := resetWebViewZoomFactor(ctx, 1.0)
if err == nil {
t.Fatal("expected panic to be converted to error, got nil")
}
if !strings.Contains(err.Error(), "panic") {
t.Fatalf("expected error to mention panic, got %v", err)
}
}