feat(desktop): add client release updater
Desktop Client Build / Resolve Build Metadata (push) Successful in 19s
Frontend CI / Frontend (push) Successful in 3m20s
Backend CI / Backend (push) Successful in 16m48s
Desktop Client Build / Build Desktop Client (push) Successful in 24m46s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 37s
Desktop Client Build / Resolve Build Metadata (push) Successful in 19s
Frontend CI / Frontend (push) Successful in 3m20s
Backend CI / Backend (push) Successful in 16m48s
Desktop Client Build / Build Desktop Client (push) Successful in 24m46s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 37s
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,194 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/ops/domain"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNormalizeDesktopClientReleaseInputOSS(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
customURL := "https://download.example.com/client.dmg"
|
||||
ossKey := "desktop/stable/client.dmg"
|
||||
got, err := normalizeDesktopClientReleaseInput(DesktopClientReleaseInput{
|
||||
Platform: " Darwin ",
|
||||
Arch: "",
|
||||
Channel: "",
|
||||
Version: "1.2.3",
|
||||
DownloadSource: "oss",
|
||||
OSSObjectKey: &ossKey,
|
||||
CustomDownloadURL: &customURL,
|
||||
Enabled: true,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "darwin", got.Platform)
|
||||
require.Equal(t, "universal", got.Arch)
|
||||
require.Equal(t, "stable", got.Channel)
|
||||
require.Equal(t, DesktopClientDownloadSourceOSS, got.DownloadSource)
|
||||
require.NotNil(t, got.OSSObjectKey)
|
||||
require.Equal(t, "desktop/stable/client.dmg", *got.OSSObjectKey)
|
||||
require.Nil(t, got.CustomDownloadURL)
|
||||
}
|
||||
|
||||
func TestNormalizeDesktopClientReleaseInputCustom(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
customURL := "https://download.example.com/client.exe"
|
||||
ossKey := "desktop/stable/client.exe"
|
||||
got, err := normalizeDesktopClientReleaseInput(DesktopClientReleaseInput{
|
||||
Platform: "win32",
|
||||
Arch: "x64",
|
||||
Channel: "stable",
|
||||
Version: "1.2.3",
|
||||
DownloadSource: "custom",
|
||||
OSSObjectKey: &ossKey,
|
||||
CustomDownloadURL: &customURL,
|
||||
Enabled: true,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, DesktopClientDownloadSourceCustom, got.DownloadSource)
|
||||
require.Nil(t, got.OSSObjectKey)
|
||||
require.NotNil(t, got.CustomDownloadURL)
|
||||
require.Equal(t, customURL, *got.CustomDownloadURL)
|
||||
}
|
||||
|
||||
func TestNormalizeDesktopClientReleaseInputRejectsInvalidDownloadTargets(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
invalidOSSKey := "../client.dmg"
|
||||
_, err := normalizeDesktopClientReleaseInput(DesktopClientReleaseInput{
|
||||
Platform: "darwin",
|
||||
Version: "1.2.3",
|
||||
DownloadSource: "oss",
|
||||
OSSObjectKey: &invalidOSSKey,
|
||||
})
|
||||
require.Error(t, err)
|
||||
|
||||
invalidURL := "javascript:alert(1)"
|
||||
_, err = normalizeDesktopClientReleaseInput(DesktopClientReleaseInput{
|
||||
Platform: "win32",
|
||||
Version: "1.2.3",
|
||||
DownloadSource: "custom",
|
||||
CustomDownloadURL: &invalidURL,
|
||||
})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestDesktopClientReleaseVersionPolicy(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Positive(t, compareVersionStrings("1.2.10", "1.2.9"))
|
||||
require.Negative(t, compareVersionStrings("1.2.9", "1.2.10"))
|
||||
|
||||
minVersion := "1.2.0"
|
||||
require.True(t, minSupportedVersionRequiresUpdate(&minVersion, "1.1.9"))
|
||||
require.False(t, minSupportedVersionRequiresUpdate(&minVersion, "1.2.0"))
|
||||
}
|
||||
|
||||
func TestNormalizeDesktopClientReleaseUploadInput(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
target, fileName, err := normalizeDesktopClientReleaseUploadInput(DesktopClientReleaseUploadInput{
|
||||
Platform: "darwin",
|
||||
Arch: "arm64",
|
||||
Channel: "stable",
|
||||
Version: "1.2.3",
|
||||
FileName: "省心推-1.2.3-arm64.dmg",
|
||||
Content: []byte("package"),
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "darwin", target.Platform)
|
||||
require.Equal(t, "arm64", target.Arch)
|
||||
require.Equal(t, "stable", target.Channel)
|
||||
require.Equal(t, "省心推-1.2.3-arm64.dmg", fileName)
|
||||
}
|
||||
|
||||
func TestNormalizeDesktopClientReleaseUploadInputDecodesFileName(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, fileName, err := normalizeDesktopClientReleaseUploadInput(DesktopClientReleaseUploadInput{
|
||||
Platform: "darwin",
|
||||
Arch: "arm64",
|
||||
Channel: "stable",
|
||||
Version: "1.2.3",
|
||||
FileName: "%E7%9C%81%E5%BF%83%E6%8E%A8-mac-0.1.19.zip",
|
||||
Content: []byte("package"),
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "省心推-mac-0.1.19.zip", fileName)
|
||||
}
|
||||
|
||||
func TestNormalizeDesktopClientReleaseUploadInputRejectsInvalidFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, _, err := normalizeDesktopClientReleaseUploadInput(DesktopClientReleaseUploadInput{
|
||||
Platform: "darwin",
|
||||
Arch: "arm64",
|
||||
Channel: "stable",
|
||||
Version: "1.2.3",
|
||||
FileName: "client.txt",
|
||||
Content: []byte("package"),
|
||||
})
|
||||
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestBuildDesktopClientUpdaterFeedYAMLUsesSignedURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fileName := "省心推-mac-1.2.3.zip"
|
||||
sha256 := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
size := int64(1024)
|
||||
publishedAt := time.Date(2026, 5, 25, 10, 30, 0, 0, time.UTC)
|
||||
content, err := buildDesktopClientUpdaterFeedYAML(&domain.DesktopClientRelease{
|
||||
Platform: "darwin",
|
||||
Version: "1.2.3",
|
||||
PublishedAt: &publishedAt,
|
||||
UpdatedAt: publishedAt,
|
||||
}, desktopClientReleaseAsset{
|
||||
FileName: &fileName,
|
||||
FileSizeBytes: &size,
|
||||
SHA256: &sha256,
|
||||
}, "https://oss.example.com/desktop/%E7%9C%81%E5%BF%83%E6%8E%A8.zip?Expires=123&Signature=abc")
|
||||
|
||||
require.NoError(t, err)
|
||||
text := string(content)
|
||||
require.Contains(t, text, "version: 1.2.3")
|
||||
require.Contains(t, text, "sha2: "+sha256)
|
||||
require.Contains(t, text, "size: 1024")
|
||||
require.Contains(t, text, "Expires=123")
|
||||
require.Contains(t, text, "Signature=abc")
|
||||
require.NotContains(t, text, "%25E7")
|
||||
}
|
||||
|
||||
func TestValidateDesktopClientUpdaterPackage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
zipName := "省心推-mac-1.2.3.zip"
|
||||
require.NoError(t, validateDesktopClientUpdaterPackage("darwin", &zipName, ""))
|
||||
|
||||
dmgName := "省心推-mac-1.2.3.dmg"
|
||||
require.Error(t, validateDesktopClientUpdaterPackage("darwin", &dmgName, ""))
|
||||
|
||||
exeURL := "https://download.example.com/%E7%9C%81%E5%BF%83%E6%8E%A8%20Setup%201.2.3.exe"
|
||||
require.NoError(t, validateDesktopClientUpdaterPackage("win32", nil, exeURL))
|
||||
}
|
||||
|
||||
func TestBuildDesktopClientReleaseObjectKeyReusesContentAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sum := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
|
||||
first := buildDesktopClientReleaseObjectKey(sum, "省心推 Setup 1.2.3.exe")
|
||||
second := buildDesktopClientReleaseObjectKey(sum, "renamed.exe")
|
||||
|
||||
require.Equal(t, first, second)
|
||||
require.Equal(t, "desktop-client/releases/blobs/"+sum+".exe", first)
|
||||
}
|
||||
Reference in New Issue
Block a user