You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

169 lines
6.3 KiB

package comm
import "testing"
func TestAppReleaseNeedForceUpdate(t *testing.T) {
on := &AppRelease{ForceUpdate: true, MinVersion: "2.0.0"}
if !on.NeedForceUpdate("1.9.9") {
t.Fatal("低于最低版本应强更")
}
if on.NeedForceUpdate("2.0.0") || on.NeedForceUpdate("2.1.0") {
t.Fatal("达到或高于最低版本不该强更")
}
if on.NeedForceUpdate("") {
t.Fatal("客户端未上报版本时不该强更,否则老客户端会被全挡在门外")
}
off := &AppRelease{ForceUpdate: false, MinVersion: "2.0.0"}
if off.NeedForceUpdate("1.0.0") {
t.Fatal("强更开关关闭时不该强更")
}
noMin := &AppRelease{ForceUpdate: true}
if noMin.NeedForceUpdate("1.0.0") {
t.Fatal("线上版本与最低版本都没配时不该强更")
}
// 2026-09-23 口径:最低版本留空 = 线上版本,「开了强更就对所有低版本强更」
blankMin := &AppRelease{ForceUpdate: true, Version: "2.0.0"}
if !blankMin.NeedForceUpdate("1.9.9") {
t.Fatal("最低版本留空时应按线上版本强更")
}
if blankMin.NeedForceUpdate("2.0.0") {
t.Fatal("已是线上版本不该强更")
}
var nilRel *AppRelease
if nilRel.NeedForceUpdate("1.0.0") {
t.Fatal("nil 配置不该强更")
}
}
func TestAppReleaseNeedUpdate(t *testing.T) {
r := &AppRelease{Version: "1.2.0"}
if !r.NeedUpdate("1.1.9") {
t.Fatal("低于线上版本应提示有更新")
}
if r.NeedUpdate("1.2.0") || r.NeedUpdate("1.3.0") {
t.Fatal("不低于线上版本时不该提示更新")
}
if r.NeedUpdate("") {
t.Fatal("客户端未上报版本时不该提示更新")
}
if (&AppRelease{}).NeedUpdate("1.0.0") {
t.Fatal("未配线上版本时恒为 false")
}
}
func TestAppReleaseIsReviewing(t *testing.T) {
r := &AppRelease{ReviewVersion: "3.1.0"}
if !r.IsReviewing("3.1.0") {
t.Fatal("送审版本应识别为审核中")
}
if r.IsReviewing("3.0.0") || r.IsReviewing("3.2.0") {
t.Fatal("非送审版本不该识别为审核中")
}
if (&AppRelease{}).IsReviewing("3.1.0") {
t.Fatal("未配送审版本时恒为 false")
}
}
// 游客登录全版本一套:开就全开、关就全关,不再按版本白名单。
func TestAppReleaseShowTourists(t *testing.T) {
off := &AppRelease{Tourists: false, TouristsVersion: "1.0.2"}
for _, v := range []string{"1.0.2", "9.9.9", ""} {
if off.ShowTourists(v) {
t.Fatalf("总开关关掉时 %q 不该可见", v)
}
}
on := &AppRelease{Tourists: true}
for _, v := range []string{"1.0.2", "9.9.9", ""} {
if !on.ShowTourists(v) {
t.Fatalf("总开关打开时 %q 应可见", v)
}
}
// 历史字段 TouristsVersion 不再参与判定:开着时即便只填了旧白名单,也必须全版本可见。
legacy := &AppRelease{Tourists: true, TouristsVersion: "1.0.2"}
if !legacy.ShowTourists("1.0.3") || !legacy.ShowTourists("1.0.2") {
t.Fatal("打开后不得再按 TouristsVersion 只给某一版看")
}
var nilRel *AppRelease
if nilRel.ShowTourists("1.0.2") {
t.Fatal("未配置发版信息时不该显示游客登录")
}
}
// 下载地址必须允许按渠道覆盖:华为/小米/App Store 的商店链接各不相同,
// 客户端是直接把它当 URL 打开的,一套地址会把小米用户引到华为商店。
func TestAppReleaseDownloadAddress(t *testing.T) {
r := &AppRelease{Address: "https://default/app.apk"}
if got := r.DownloadAddress("https://xiaomi/store"); got != "https://xiaomi/store" {
t.Fatalf("渠道填了地址应以渠道为准,实际 %q", got)
}
if got := r.DownloadAddress(" "); got != "https://default/app.apk" {
t.Fatalf("渠道留空应回退应用默认地址,实际 %q", got)
}
var nilRel *AppRelease
if got := nilRel.DownloadAddress(""); got != "" {
t.Fatalf("两边都没有时应为空串,实际 %q", got)
}
if got := nilRel.DownloadAddress("https://only-channel"); got != "https://only-channel" {
t.Fatalf("发版配置缺失时仍应用渠道地址,实际 %q", got)
}
}
// iOS 与 Android 各一套版本号:iOS 没填时不回退 Android 的(否则又回到共用一个版本号的老问题)。
func TestAppReleasePlatformVersions(t *testing.T) {
r := &AppRelease{Version: "1.0.3", MinVersion: "1.0.1", IosVersion: "1.0.2", ForceUpdate: true}
if r.VersionFor(PlatformAndroid) != "1.0.3" || r.VersionFor(PlatformIOS) != "1.0.2" {
t.Fatal("两个平台应各取各的线上版本")
}
if r.MinVersionFor(PlatformAndroid) != "1.0.1" {
t.Fatal("Android 填了最低版本应取它")
}
if r.MinVersionFor(PlatformIOS) != "1.0.2" {
t.Fatal("iOS 最低版本留空应等于 iOS 线上版本")
}
if !r.NeedUpdateOn("1.0.2", PlatformAndroid) || r.NeedUpdateOn("1.0.2", PlatformIOS) {
t.Fatal("1.0.2 在 Android 上是旧版、在 iOS 上是最新")
}
noIos := &AppRelease{Version: "1.0.3", ForceUpdate: true}
if noIos.NeedUpdateOn("0.0.1", PlatformIOS) || noIos.NeedForceUpdateOn("0.0.1", PlatformIOS) {
t.Fatal("iOS 没填版本时不该拿 Android 的版本去判 iOS")
}
if PlatformOfChannel(ChannelGlobalApple) != PlatformIOS || PlatformOfChannel(ChannelChinaHuawei) != PlatformAndroid || PlatformOfChannel(ChannelGlobalGoogle) != PlatformAndroid {
t.Fatal("只有 App Store 渠道是 iOS")
}
}
func TestPickAppRelease(t *testing.T) {
rows := []*AppRelease{
{AppName: "", Version: "1.0.0"},
{AppName: "ym", Version: "2.0.0"},
}
if got := PickAppRelease(rows, "ym"); got == nil || got.Version != "2.0.0" {
t.Fatalf("应用行应覆盖全局行,实际 %+v", got)
}
if got := PickAppRelease(rows, "other"); got == nil || got.Version != "1.0.0" {
t.Fatalf("没有应用行时应回退全局行,实际 %+v", got)
}
if got := PickAppRelease([]*AppRelease{{AppName: "ym"}}, "other"); got != nil {
t.Fatalf("既无应用行也无全局行时应返回 nil,实际 %+v", got)
}
}
// 实名认证与游客登录同一个口子:两者对任何版本的结论必须一致(2026-09-23 口径)。
func TestAppReleaseShowIdVerifyFollowsTourists(t *testing.T) {
rels := []*AppRelease{
nil,
{Tourists: false, TouristsVersion: "1.0.2"},
{Tourists: true, TouristsVersion: ""},
{Tourists: true, TouristsVersion: "1.0.2"},
}
for i, r := range rels {
for _, v := range []string{"", "1.0.1", "1.0.2", "1.0.3"} {
if r.ShowIdVerify(v) != r.ShowTourists(v) {
t.Errorf("#%d v=%q: ShowIdVerify=%v 与 ShowTourists=%v 不一致", i, v, r.ShowIdVerify(v), r.ShowTourists(v))
}
}
}
}