Files
MyGoNavi/internal/app/connection_package_i18n_test.go
2026-06-22 15:12:42 +08:00

154 lines
5.5 KiB
Go

package app
import (
"errors"
"os"
"strings"
"testing"
"GoNavi-Wails/shared/i18n"
)
func connectionPackageFunctionSource(t *testing.T, source string, signature string) string {
t.Helper()
start := strings.Index(source, signature)
if start < 0 {
t.Fatalf("source missing function signature %q", signature)
}
rest := source[start+len(signature):]
end := strings.Index(rest, "\nfunc ")
if end < 0 {
return source[start:]
}
return source[start : start+len(signature)+end]
}
func TestConnectionPackageInternalSentinelsDoNotUseLegacyChineseText(t *testing.T) {
sourceBytes, err := os.ReadFile("connection_package_types.go")
if err != nil {
t.Fatalf("read connection_package_types.go: %v", err)
}
source := string(sourceBytes)
for _, literal := range []string{
"恢复包密码不能为空",
"文件密码错误或文件已损坏",
"不支持的连接恢复包格式",
"连接导入文件过大",
"连接恢复包过大",
} {
if strings.Contains(source, literal) {
t.Fatalf("connection_package_types.go still contains legacy Chinese sentinel text %q", literal)
}
}
}
func TestImportConnectionsPayloadLocalizesPasswordRequiredErrorInGerman(t *testing.T) {
app := NewAppWithSecretStore(newFakeAppSecretStore())
app.configDir = t.TempDir()
app.SetLanguage(string(i18n.LanguageDeDE))
raw := `{
"schemaVersion": 1,
"kind": "gonavi_connection_package",
"cipher": "AES-256-GCM",
"kdf": {
"name": "Argon2id",
"memoryKiB": 65536,
"timeCost": 3,
"parallelism": 4,
"salt": "salt"
},
"nonce": "nonce",
"payload": "payload"
}`
_, err := app.ImportConnectionsPayload(raw, "")
if !errors.Is(err, errConnectionPackagePasswordRequired) {
t.Fatalf("expected errConnectionPackagePasswordRequired, got %v", err)
}
want := app.appText("file.backend.error.connection_package_password_required", nil)
if err == nil || err.Error() != want {
t.Fatalf("expected German password-required message %q, got %q", want, errorMessage(err))
}
if strings.Contains(err.Error(), "恢复包密码不能为空") {
t.Fatalf("expected no legacy Chinese password-required text in de-DE mode, got %q", err.Error())
}
}
func TestImportConnectionsPayloadLocalizesOversizedImportErrorInGerman(t *testing.T) {
app := NewAppWithSecretStore(newFakeAppSecretStore())
app.configDir = t.TempDir()
app.SetLanguage(string(i18n.LanguageDeDE))
_, err := app.ImportConnectionsPayload(strings.Repeat("A", connectionImportMaxFileBytes+1), "")
if !errors.Is(err, errConnectionImportFileTooLarge) {
t.Fatalf("expected errConnectionImportFileTooLarge, got %v", err)
}
want := app.appText("file.backend.error.connection_import_file_too_large", nil)
if err == nil || err.Error() != want {
t.Fatalf("expected German oversized-import message %q, got %q", want, errorMessage(err))
}
if strings.Contains(err.Error(), "连接导入文件过大") {
t.Fatalf("expected no legacy Chinese oversized-import text in de-DE mode, got %q", err.Error())
}
}
func TestImportConnectionsPayloadLocalizesMySQLWorkbenchParseFailureInGerman(t *testing.T) {
app := NewAppWithSecretStore(newFakeAppSecretStore())
app.configDir = t.TempDir()
app.SetLanguage(string(i18n.LanguageDeDE))
raw := `<data grt_format="4.0"><value struct-name="db.mgmt.Connection"></data>`
_, parseErr := parseMySQLWorkbenchXML(raw)
if parseErr == nil {
t.Fatal("expected invalid MySQL Workbench XML to fail parsing")
}
_, err := app.ImportConnectionsPayload(raw, "")
want := app.appText("file.backend.error.mysql_workbench_parse_failed", map[string]any{"detail": parseErr.Error()})
if err == nil || err.Error() != want {
t.Fatalf("expected German MySQL Workbench parse error %q, got %q", want, errorMessage(err))
}
if strings.Contains(err.Error(), "解析 MySQL Workbench XML 失败") {
t.Fatalf("expected no legacy Chinese MySQL Workbench parse text in de-DE mode, got %q", err.Error())
}
}
func TestImportConnectionsPayloadLocalizesMySQLWorkbenchNoConnectionsErrorInGerman(t *testing.T) {
app := NewAppWithSecretStore(newFakeAppSecretStore())
app.configDir = t.TempDir()
app.SetLanguage(string(i18n.LanguageDeDE))
raw := `<data grt_format="4.0"><value struct-name="db.mgmt.Connection"></value></data>`
_, err := app.ImportConnectionsPayload(raw, "")
want := app.appText("file.backend.error.mysql_workbench_no_connections", nil)
if err == nil || err.Error() != want {
t.Fatalf("expected German MySQL Workbench no-connections error %q, got %q", want, errorMessage(err))
}
if strings.Contains(err.Error(), "未在 XML 中找到有效的连接配置") {
t.Fatalf("expected no legacy Chinese MySQL Workbench no-connections text in de-DE mode, got %q", err.Error())
}
}
func TestConnectionPackageDialogBoundariesUseLocalizedMessageHelpers(t *testing.T) {
sourceBytes, err := os.ReadFile("methods_file.go")
if err != nil {
t.Fatalf("read methods_file.go: %v", err)
}
source := string(sourceBytes)
importFunction := connectionPackageFunctionSource(t, source, "func (a *App) ImportConfigFile() connection.QueryResult")
if !strings.Contains(importFunction, "localizedConnectionPackageMessage(") {
t.Fatal("ImportConfigFile should localize connection-package sentinel errors before returning QueryResult.Message")
}
exportFunction := connectionPackageFunctionSource(t, source, "func (a *App) ExportConnectionsPackage(options ConnectionExportOptions) connection.QueryResult")
if !strings.Contains(exportFunction, "localizedConnectionPackageExportMessage(") {
t.Fatal("ExportConnectionsPackage should map export oversize errors through a dedicated localized message helper")
}
}