From be0a395447d788419e83acdfd693e48a1a1706bf Mon Sep 17 00:00:00 2001 From: Levi Date: Sat, 14 Nov 2026 11:48:16 +0800 Subject: [PATCH] test: stabilize webhook synchronization and local cookie navigation (#1671) --- internal/webview/integrationtest/contract.go | 13 +++--- .../rpcprovider/provider_integration_test.go | 1 - pkg/download/webhook_test.go | 42 ++++++++++++------- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/internal/webview/integrationtest/contract.go b/internal/webview/integrationtest/contract.go index a9a1ea8c..b0b5879f 100644 --- a/internal/webview/integrationtest/contract.go +++ b/internal/webview/integrationtest/contract.go @@ -25,7 +25,6 @@ const defaultAvailabilityTimeout = time.Minute type ContractOptions struct { AvailabilityTimeout time.Duration CookieDomainMode CookieDomainMode - CookieTestURL string } type CookieDomainMode int @@ -44,7 +43,7 @@ func RunProviderContract(t *testing.T, provider enginewebview.Provider, opts Con } waitForProviderAvailable(t, provider, timeout) - page, server, testURL := openTestPage(t, provider, enginewebview.OpenOptions{ + page, _, testURL := openTestPage(t, provider, enginewebview.OpenOptions{ Headless: true, Title: "Gopeed WebView Integration", Width: 640, @@ -155,11 +154,9 @@ func RunProviderContract(t *testing.T, provider enginewebview.Provider, opts Con t.Fatal("expected missing selector wait to time out") } - cookieTestURL := opts.CookieTestURL - if cookieTestURL == "" { - cookieTestURL = testURL - } - runCookieLifecycleAssertions(t, page, server, cookieTestURL, opts.CookieDomainMode) + // Keep cookie navigation on the same local fixture as the DOM assertions: + // this contract must not depend on public DNS, TLS, or site availability. + runCookieLifecycleAssertions(t, page, testURL, opts.CookieDomainMode) } func waitForProviderAvailable(t *testing.T, provider enginewebview.Provider, timeout time.Duration) { @@ -270,7 +267,7 @@ func openTestPage(t *testing.T, provider enginewebview.Provider, opts enginewebv return page, server, server.URL } -func runCookieLifecycleAssertions(t *testing.T, page *enginewebview.PageHandle, _ *httptest.Server, testURL string, domainMode CookieDomainMode) { +func runCookieLifecycleAssertions(t *testing.T, page *enginewebview.PageHandle, testURL string, domainMode CookieDomainMode) { t.Helper() parsedURL, err := url.Parse(testURL) diff --git a/internal/webview/rpcprovider/provider_integration_test.go b/internal/webview/rpcprovider/provider_integration_test.go index 4efe1c5f..1c229439 100644 --- a/internal/webview/rpcprovider/provider_integration_test.go +++ b/internal/webview/rpcprovider/provider_integration_test.go @@ -26,7 +26,6 @@ func TestProviderContract(t *testing.T) { }) integrationtest.RunProviderContract(t, provider, integrationtest.ContractOptions{ CookieDomainMode: integrationtest.CookieDomainModeRequired, - CookieTestURL: "https://example.com/", }) } diff --git a/pkg/download/webhook_test.go b/pkg/download/webhook_test.go index 29c92aeb..fe351131 100644 --- a/pkg/download/webhook_test.go +++ b/pkg/download/webhook_test.go @@ -190,14 +190,14 @@ func TestWebhook_NoWebhookConfigured(t *testing.T) { } func TestWebhook_MultipleUrls(t *testing.T) { - count := 0 + received := make(chan string, 2) server1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - count++ + received <- "server1" w.WriteHeader(http.StatusOK) })) defer server1.Close() server2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - count++ + received <- "server2" w.WriteHeader(http.StatusOK) })) defer server2.Close() @@ -219,11 +219,21 @@ func TestWebhook_MultipleUrls(t *testing.T) { // Trigger webhook downloader.triggerWebhooks(WebhookEventDownloadDone, task, nil) - // Wait for webhooks - time.Sleep(500 * time.Millisecond) - - if count != 2 { - t.Errorf("Expected 2 webhook calls, got %d", count) + // Wait for each destination, rather than racing on a shared counter or + // assuming that both requests finish within a fixed sleep. + timer := time.NewTimer(2 * time.Second) + defer timer.Stop() + seen := make(map[string]bool) + for len(seen) < 2 { + select { + case server := <-received: + if seen[server] { + t.Fatalf("Duplicate webhook call to %s", server) + } + seen[server] = true + case <-timer.C: + t.Fatalf("Timeout waiting for both webhook destinations; received: %v", seen) + } } }) } @@ -629,9 +639,9 @@ func TestWebhook_SendWebhookToUrl_VariousStatusCodes(t *testing.T) { } func TestWebhook_TriggerWebhooks_EmptyUrlSkipped(t *testing.T) { - requestCount := 0 + received := make(chan struct{}, 2) server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - requestCount++ + received <- struct{}{} w.WriteHeader(http.StatusOK) })) defer server.Close() @@ -650,10 +660,14 @@ func TestWebhook_TriggerWebhooks_EmptyUrlSkipped(t *testing.T) { downloader.triggerWebhooks(WebhookEventDownloadDone, task, nil) - time.Sleep(500 * time.Millisecond) - - if requestCount != 2 { - t.Errorf("Expected 2 requests (empty URL should be skipped), got %d", requestCount) + timer := time.NewTimer(2 * time.Second) + defer timer.Stop() + for count := 0; count < 2; count++ { + select { + case <-received: + case <-timer.C: + t.Fatalf("Expected 2 requests (empty URL should be skipped), got %d", count) + } } }) }