feat: support media account unbind requests

This commit is contained in:
2026-06-18 23:49:01 +08:00
parent fd37263116
commit 889a575188
7 changed files with 708 additions and 27 deletions
@@ -387,7 +387,7 @@ func (s *DesktopAccountService) Tombstone(ctx context.Context, client *repositor
}
func (s *DesktopAccountService) RequestDelete(ctx context.Context, actor auth.Actor, desktopID uuid.UUID, undo bool) (*DesktopAccountView, error) {
if actor.PrimaryWorkspaceID == 0 {
if actor.PrimaryWorkspaceID == 0 || actor.UserID == 0 {
return nil, response.ErrUnauthorized(40132, "workspace_scope_missing", "workspace context is required")
}
@@ -397,9 +397,9 @@ func (s *DesktopAccountService) RequestDelete(ctx context.Context, actor auth.Ac
)
if undo {
account, err = s.repo.ClearDeleteRequested(ctx, desktopID, actor.PrimaryWorkspaceID)
account, err = s.repo.ClearDeleteRequested(ctx, desktopID, actor.PrimaryWorkspaceID, actor.UserID)
} else {
account, err = s.repo.MarkDeleteRequested(ctx, desktopID, actor.PrimaryWorkspaceID)
account, err = s.repo.MarkDeleteRequested(ctx, desktopID, actor.PrimaryWorkspaceID, actor.UserID)
}
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
@@ -1,15 +1,73 @@
package app
import (
"context"
"testing"
"time"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/geo-platform/tenant-api/internal/shared/auth"
"github.com/geo-platform/tenant-api/internal/tenant/repository"
)
type desktopAccountRepoSpy struct {
markDesktopID uuid.UUID
markWorkspaceID int64
markUserID int64
}
func (r *desktopAccountRepoSpy) ListByClient(context.Context, int64, uuid.UUID) ([]repository.DesktopAccount, error) {
return nil, nil
}
func (r *desktopAccountRepoSpy) ListByUser(context.Context, int64, int64) ([]repository.DesktopAccount, error) {
return nil, nil
}
func (r *desktopAccountRepoSpy) GetByDesktopID(context.Context, uuid.UUID, int64) (*repository.DesktopAccount, error) {
return nil, nil
}
func (r *desktopAccountRepoSpy) GetByIdentity(context.Context, int64, uuid.UUID, string, string) (*repository.DesktopAccount, error) {
return nil, nil
}
func (r *desktopAccountRepoSpy) Upsert(context.Context, repository.UpsertDesktopAccountParams) (*repository.DesktopAccount, error) {
return nil, nil
}
func (r *desktopAccountRepoSpy) Patch(context.Context, repository.PatchDesktopAccountParams) (*repository.DesktopAccount, error) {
return nil, nil
}
func (r *desktopAccountRepoSpy) Tombstone(context.Context, uuid.UUID, int64, uuid.UUID, int64) (*repository.DesktopAccount, error) {
return nil, nil
}
func (r *desktopAccountRepoSpy) MarkDeleteRequested(_ context.Context, desktopID uuid.UUID, workspaceID, userID int64) (*repository.DesktopAccount, error) {
r.markDesktopID = desktopID
r.markWorkspaceID = workspaceID
r.markUserID = userID
now := time.Date(2026, 6, 18, 9, 30, 0, 0, time.UTC)
return &repository.DesktopAccount{
DesktopID: desktopID,
TenantID: 10,
WorkspaceID: workspaceID,
UserID: userID,
Platform: "toutiaohao",
PlatformUID: "122707592",
DisplayName: "Media Account",
Health: "live",
DeleteRequestedAt: &now,
}, nil
}
func (r *desktopAccountRepoSpy) ClearDeleteRequested(context.Context, uuid.UUID, int64, int64) (*repository.DesktopAccount, error) {
return nil, nil
}
func TestResolveDesktopClientOnline_PresenceHitWins(t *testing.T) {
now := time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
@@ -21,6 +79,26 @@ func TestResolveDesktopClientOnline_PresenceHitWins(t *testing.T) {
assert.True(t, online)
}
func TestRequestDeleteScopesToActorUser(t *testing.T) {
repo := &desktopAccountRepoSpy{}
service := &DesktopAccountService{repo: repo}
accountID := uuid.New()
view, err := service.RequestDelete(
context.Background(),
auth.Actor{UserID: 42, TenantID: 10, PrimaryWorkspaceID: 7},
accountID,
false,
)
assert.NoError(t, err)
assert.Equal(t, accountID, repo.markDesktopID)
assert.Equal(t, int64(7), repo.markWorkspaceID)
assert.Equal(t, int64(42), repo.markUserID)
assert.NotNil(t, view)
assert.NotNil(t, view.DeleteRequestedAt)
}
func TestResolveDesktopClientOnline_PresenceMissWithKnownPresenceIsOffline(t *testing.T) {
now := time.Date(2026, 4, 19, 21, 30, 0, 0, time.UTC)
lastSeen := now.Add(-desktopClientPresenceTTL / 2)