package main import ( "testing" "time" "git.ipao.vip/rogee/creator-hub/internal/creator" "git.ipao.vip/rogee/creator-hub/internal/hub" ) func TestCreatorUpdateHubPublishesAndUnsubscribes(t *testing.T) { hub := &creatorUpdateHub{subscribers: make(map[chan struct{}]struct{})} updates, unsubscribe := hub.subscribe() hub.publish() select { case <-updates: default: t.Fatal("publish did not notify subscriber") } unsubscribe() hub.publish() select { case _, ok := <-updates: if ok { t.Fatal("unsubscribed channel received an update") } default: } } func TestGatewayGenerationPayloadIncludesCurrentProxyExit(t *testing.T) { payload := gatewayGenerationPayload(hub.EnvironmentContext{ BindingVersion: 3, RuntimeID: "runtime", RuntimeNetworkID: "network", Exit: hub.NetworkExit{ID: "exit-current"}, }) if payload["binding_version"] != int64(3) || payload["runtime_id"] != "runtime" || payload["network_id"] != "network" || payload["network_exit_id"] != "exit-current" { t.Fatalf("unexpected generation payload: %#v", payload) } } func TestCreatorGatewayEventNeedsBaseline(t *testing.T) { if ok, reason := creatorGatewayEventNeedsBaseline(creatorGatewayEvent{Kind: "notice"}, true); !ok || reason != "缺少平台事件时间" { t.Fatalf("missing platform time must be held at baseline: %v %q", ok, reason) } if ok, reason := creatorGatewayEventNeedsBaseline(creatorGatewayEvent{Kind: "notice", Notice: &creatorGatewayEventNotice{PlatformEventAt: "2024-01-01T00:00:00Z"}}, false); !ok || reason != "监听边界未确认" { t.Fatalf("unconfirmed listener boundary must be held: %v %q", ok, reason) } if ok, reason := creatorGatewayEventNeedsBaseline(creatorGatewayEvent{Kind: "notice", Notice: &creatorGatewayEventNotice{PlatformEventAt: "2024-01-01T00:00:00Z"}}, true); ok || reason != "" { t.Fatalf("confirmed event boundary should be actionable: %v %q", ok, reason) } } func TestCreatorEventBeforeBoundary(t *testing.T) { boundary := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC) before := creatorGatewayEvent{Notice: &creatorGatewayEventNotice{PlatformEventAt: "2023-12-31T23:59:59Z"}} after := creatorGatewayEvent{Notice: &creatorGatewayEventNotice{PlatformEventAt: "2024-01-01T00:00:01Z"}} invalid := creatorGatewayEvent{Notice: &creatorGatewayEventNotice{PlatformEventAt: "not-a-time"}} if !creatorEventBeforeBoundary(before, boundary) || !creatorEventBeforeBoundary(invalid, boundary) || creatorEventBeforeBoundary(after, boundary) { t.Fatalf("unexpected boundary classification") } } func TestCreatorEventFromGatewayNotice(t *testing.T) { event, err := creatorEventFromGatewayNotice("account-1", creatorGatewayEventNotice{ EventKey: "9007199254740993", EventType: "comment", InteractorUID: "7654321", CommentID: "987654", WorkID: "123456", PlatformEventAt: "2023-11-14T22:13:20+00:00", GatewayReceivedAt: "2023-11-14T22:13:21+00:00", }) if err != nil { t.Fatal(err) } if event.Platform != "douyin" || event.ReceivingAccountID != "account-1" || event.EventKey != "9007199254740993" || event.InteractorUID != "7654321" || event.CommentID != "987654" || event.WorkID != "123456" { t.Fatalf("unexpected event: %+v", event) } if event.PlatformEventAt == nil || event.PlatformEventAt.UTC().Format("2006-01-02T15:04:05Z07:00") != "2023-11-14T22:13:20Z" { t.Fatalf("unexpected event time: %+v", event.PlatformEventAt) } if event.GatewayReceivedAt == nil || event.GatewayReceivedAt.UTC().Format("2006-01-02T15:04:05Z07:00") != "2023-11-14T22:13:21Z" { t.Fatalf("unexpected gateway receipt time: %v", event.GatewayReceivedAt) } } func TestCreatorEventFromGatewayNoticeRejectsInvalidIdentity(t *testing.T) { _, err := creatorEventFromGatewayNotice("account-1", creatorGatewayEventNotice{ EventKey: "1", EventType: "follow", InteractorUID: "not-a-uid", }) if err == nil { t.Fatal("expected invalid interactor UID") } } func TestCreatorEventFromGatewayNoticeRejectsInvalidGatewayReceiptTime(t *testing.T) { _, err := creatorEventFromGatewayNotice("account-1", creatorGatewayEventNotice{ EventKey: "1", EventType: "like", GatewayReceivedAt: "not-a-time", }) if err == nil { t.Fatal("expected invalid gateway receipt time") } } func TestCreatorEventFromGatewayNoticePreservesMessageType(t *testing.T) { result, err := creatorEventFromGatewayNotice("account-1", creatorGatewayEventNotice{ EventKey: "123", EventType: "dm", InteractorUID: "456", MessageType: creator.MessageTypeImage, }) if err != nil || result.MessageType != creator.MessageTypeImage { t.Fatalf("message type was not preserved: result=%#v err=%v", result, err) } } func TestCreatorEventFromGatewayNoticeRejectsInvalidTime(t *testing.T) { _, err := creatorEventFromGatewayNotice("account-1", creatorGatewayEventNotice{ EventKey: "1", EventType: "like", PlatformEventAt: "not-a-time", }) if err == nil { t.Fatal("expected invalid platform event time") } }