67be43319e
Desktop Client Build / Resolve Build Metadata (push) Successful in 1m13s
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Backend CI / Backend (push) Failing after 13m49s
Frontend CI / Frontend (push) Successful in 6m38s
- Added new fields to DesktopAccountInfo for tracking account session and task consumer online status, along with queued publish task count and oldest queued publish task timestamp. - Updated DesktopDispatchEvent to include server time for better synchronization. - Implemented separate presence management for task consumers, including marking presence and loading presence state. - Enhanced DesktopAccountService to apply publish queue summaries and manage task consumer presence. - Introduced new methods for replaying queued publish tasks in DesktopDispatchHandler. - Updated tests to cover new presence management logic and ensure correct behavior of account session and task consumer online status.
237 lines
6.2 KiB
Go
237 lines
6.2 KiB
Go
package app
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/geo-platform/tenant-api/internal/tenant/repository"
|
|
)
|
|
|
|
func TestResolveDesktopClientOnline_PresenceHitWins(t *testing.T) {
|
|
now := time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
|
|
|
|
online := resolveDesktopClientOnline(&repository.DesktopClient{
|
|
ID: uuid.New(),
|
|
LastSeenAt: nil,
|
|
}, true, true, now)
|
|
|
|
assert.True(t, online)
|
|
}
|
|
|
|
func TestResolveDesktopClientOnline_PresenceMissWithKnownPresenceIsOffline(t *testing.T) {
|
|
now := time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
|
|
lastSeen := now.Add(-desktopClientPresenceTTL / 2)
|
|
|
|
online := resolveDesktopClientOnline(&repository.DesktopClient{
|
|
ID: uuid.New(),
|
|
LastSeenAt: &lastSeen,
|
|
}, false, true, now)
|
|
|
|
assert.False(t, online)
|
|
}
|
|
|
|
func TestResolveDesktopClientOnline_FallsBackToRecentHeartbeatWhenPresenceUnknown(t *testing.T) {
|
|
now := time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
|
|
lastSeen := now.Add(-desktopClientPresenceTTL / 2)
|
|
|
|
online := resolveDesktopClientOnline(&repository.DesktopClient{
|
|
ID: uuid.New(),
|
|
LastSeenAt: &lastSeen,
|
|
}, false, false, now)
|
|
|
|
assert.True(t, online)
|
|
}
|
|
|
|
func TestResolveDesktopClientOnline_StaleHeartbeatIsOffline(t *testing.T) {
|
|
now := time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
|
|
lastSeen := now.Add(-(desktopClientPresenceTTL + time.Second))
|
|
|
|
online := resolveDesktopClientOnline(&repository.DesktopClient{
|
|
ID: uuid.New(),
|
|
LastSeenAt: &lastSeen,
|
|
}, false, false, now)
|
|
|
|
assert.False(t, online)
|
|
}
|
|
|
|
func TestBuildDesktopAccountView_StoredClientOwnershipWinsOverPresence(t *testing.T) {
|
|
service := &DesktopAccountService{now: func() time.Time {
|
|
return time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
|
|
}}
|
|
accountID := uuid.New()
|
|
staleClientID := uuid.New()
|
|
activeClientID := uuid.New()
|
|
lastSeen := time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
|
|
deviceName := "Desktop MacIntel"
|
|
|
|
view := service.buildDesktopAccountView(
|
|
&repository.DesktopAccount{
|
|
DesktopID: accountID,
|
|
ClientID: &staleClientID,
|
|
Platform: "toutiaohao",
|
|
PlatformUID: "platform:4181862206",
|
|
DisplayName: "ireader",
|
|
Health: "live",
|
|
},
|
|
map[uuid.UUID]*repository.DesktopClient{
|
|
activeClientID: {
|
|
ID: activeClientID,
|
|
LastSeenAt: &lastSeen,
|
|
DeviceName: &deviceName,
|
|
},
|
|
},
|
|
map[uuid.UUID]uuid.UUID{
|
|
accountID: activeClientID,
|
|
},
|
|
map[uuid.UUID]bool{
|
|
activeClientID: true,
|
|
},
|
|
map[uuid.UUID]bool{
|
|
activeClientID: true,
|
|
},
|
|
)
|
|
|
|
if assert.NotNil(t, view.ClientID) {
|
|
assert.Equal(t, staleClientID.String(), *view.ClientID)
|
|
}
|
|
if assert.NotNil(t, view.ClientOnline) {
|
|
assert.False(t, *view.ClientOnline)
|
|
}
|
|
if assert.NotNil(t, view.AccountSessionOnline) {
|
|
assert.False(t, *view.AccountSessionOnline)
|
|
}
|
|
if assert.NotNil(t, view.TaskConsumerOnline) {
|
|
assert.False(t, *view.TaskConsumerOnline)
|
|
}
|
|
assert.Equal(t, "4181862206", view.PlatformUID)
|
|
assert.Nil(t, view.ClientLastSeenAt)
|
|
assert.Nil(t, view.ClientDeviceName)
|
|
}
|
|
|
|
func TestBuildDesktopAccountView_FallsBackToStoredClientWhenNoPresence(t *testing.T) {
|
|
now := time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
|
|
service := &DesktopAccountService{now: func() time.Time { return now }}
|
|
accountID := uuid.New()
|
|
storedClientID := uuid.New()
|
|
lastSeen := now.Add(-desktopClientPresenceTTL / 2)
|
|
|
|
view := service.buildDesktopAccountView(
|
|
&repository.DesktopAccount{
|
|
DesktopID: accountID,
|
|
ClientID: &storedClientID,
|
|
Platform: "toutiaohao",
|
|
PlatformUID: "4181862206",
|
|
DisplayName: "ireader",
|
|
Health: "live",
|
|
},
|
|
map[uuid.UUID]*repository.DesktopClient{
|
|
storedClientID: {
|
|
ID: storedClientID,
|
|
LastSeenAt: &lastSeen,
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
|
|
if assert.NotNil(t, view.ClientID) {
|
|
assert.Equal(t, storedClientID.String(), *view.ClientID)
|
|
}
|
|
if assert.NotNil(t, view.ClientOnline) {
|
|
assert.True(t, *view.ClientOnline)
|
|
}
|
|
assert.Equal(t, &lastSeen, view.ClientLastSeenAt)
|
|
}
|
|
|
|
func TestBuildDesktopAccountView_SplitsHeartbeatAccountSessionAndTaskConsumer(t *testing.T) {
|
|
now := time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
|
|
service := &DesktopAccountService{now: func() time.Time { return now }}
|
|
accountID := uuid.New()
|
|
clientID := uuid.New()
|
|
lastSeen := now.Add(-time.Minute)
|
|
deviceName := "Windows Workstation"
|
|
|
|
view := service.buildDesktopAccountView(
|
|
&repository.DesktopAccount{
|
|
DesktopID: accountID,
|
|
ClientID: &clientID,
|
|
Platform: "sohuhao",
|
|
PlatformUID: "110424528162",
|
|
DisplayName: "全屋定制老炮",
|
|
Health: "live",
|
|
},
|
|
map[uuid.UUID]*repository.DesktopClient{
|
|
clientID: {
|
|
ID: clientID,
|
|
LastSeenAt: &lastSeen,
|
|
DeviceName: &deviceName,
|
|
},
|
|
},
|
|
map[uuid.UUID]uuid.UUID{
|
|
accountID: clientID,
|
|
},
|
|
map[uuid.UUID]bool{
|
|
clientID: true,
|
|
},
|
|
map[uuid.UUID]bool{
|
|
clientID: false,
|
|
},
|
|
)
|
|
|
|
if assert.NotNil(t, view.ClientOnline) {
|
|
assert.True(t, *view.ClientOnline)
|
|
}
|
|
if assert.NotNil(t, view.AccountSessionOnline) {
|
|
assert.True(t, *view.AccountSessionOnline)
|
|
}
|
|
if assert.NotNil(t, view.TaskConsumerOnline) {
|
|
assert.False(t, *view.TaskConsumerOnline)
|
|
}
|
|
assert.Equal(t, &lastSeen, view.ClientLastSeenAt)
|
|
assert.Equal(t, &deviceName, view.ClientDeviceName)
|
|
}
|
|
|
|
func TestShouldApplyDesktopAccountRuntimeHealth_IgnoresReportOlderThanVerifiedAt(t *testing.T) {
|
|
verifiedAt := time.Date(2026, 4, 30, 9, 30, 0, 0, time.UTC)
|
|
reportCheckedAt := verifiedAt.Add(-time.Minute)
|
|
|
|
shouldApply := shouldApplyDesktopAccountRuntimeHealth(
|
|
DesktopAccountView{
|
|
ID: uuid.NewString(),
|
|
Health: "live",
|
|
VerifiedAt: &verifiedAt,
|
|
},
|
|
bufferedDesktopAccountHealthReport{
|
|
Health: "expired",
|
|
AuthState: "expired",
|
|
CheckedAt: reportCheckedAt,
|
|
},
|
|
)
|
|
|
|
assert.False(t, shouldApply)
|
|
}
|
|
|
|
func TestShouldApplyDesktopAccountRuntimeHealth_AppliesReportAfterVerifiedAt(t *testing.T) {
|
|
verifiedAt := time.Date(2026, 4, 30, 9, 30, 0, 0, time.UTC)
|
|
reportCheckedAt := verifiedAt.Add(time.Minute)
|
|
|
|
shouldApply := shouldApplyDesktopAccountRuntimeHealth(
|
|
DesktopAccountView{
|
|
ID: uuid.NewString(),
|
|
Health: "live",
|
|
VerifiedAt: &verifiedAt,
|
|
},
|
|
bufferedDesktopAccountHealthReport{
|
|
Health: "expired",
|
|
AuthState: "expired",
|
|
CheckedAt: reportCheckedAt,
|
|
},
|
|
)
|
|
|
|
assert.True(t, shouldApply)
|
|
}
|