69 lines · 2.6 KB · Go
RawDownload
package homeplugins import (	"context"	"errors"	"io"	"net/http"	"net/http/httptest"	"strings"	"sync/atomic"	"testing"	"time" 	"github.com/router-for-me/CLIProxyAPI/v7/internal/config"	internalpluginstore "github.com/router-for-me/CLIProxyAPI/v7/internal/pluginstore"	sdkpluginstore "github.com/router-for-me/CLIProxyAPI/v7/sdk/pluginstore") type networkScopeDoer func(*http.Request) (*http.Response, error) func (f networkScopeDoer) Do(req *http.Request) (*http.Response, error) { return f(req) } func TestPluginStoreClientsShareProxyCooldown(t *testing.T) {	var proxyCalls atomic.Int32	proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {		proxyCalls.Add(1)		w.WriteHeader(http.StatusBadGateway)	}))	defer proxy.Close() 	const tokenEnv = "HOME_PLUGIN_NETWORK_SCOPE_TEST_TOKEN"	t.Setenv(tokenEnv, t.Name())	auth := []sdkpluginstore.ResolvedAuthConfig{{		Match: "https://api.github.com/", Type: sdkpluginstore.AuthTypeGitHubToken,		Token: sdkpluginstore.Secret(t.Name()),	}}	expiresAt := time.Now().Add(time.Hour)	plugin := sdkpluginstore.Plugin{Repository: "https://github.com/test/home-network-scope"}	// Seed the same process-wide cooldown used by management and Home clients.	seed := sdkpluginstore.NewClientWithResolvedAuthExpiry(networkScopeDoer(func(*http.Request) (*http.Response, error) {		return &http.Response{StatusCode: http.StatusTooManyRequests, Header: http.Header{"Retry-After": {"3600"}}, Body: io.NopCloser(strings.NewReader("limited"))}, nil	}), "", auth, expiresAt).WithNetworkScope(proxy.URL)	_, errRelease := seed.FetchLatestRelease(context.Background(), plugin)	var rateLimit *internalpluginstore.RateLimitError	if !errors.As(errRelease, &rateLimit) {		t.Fatalf("seed cooldown: %v", errRelease)	} 	cfg := &config.Config{}	cfg.ProxyURL = " " + proxy.URL + " "	cfg.Plugins.StoreAuth = []sdkpluginstore.AuthConfig{{		Match: "https://api.github.com/", Type: sdkpluginstore.AuthTypeGitHubToken, TokenEnv: tokenEnv,	}}	for name, client := range map[string]sdkpluginstore.Client{		"configured auth": newPluginStoreClient(cfg),		"resolved auth":   newResolvedPluginStoreClient(cfg, auth, expiresAt),	} {		t.Run(name, func(t *testing.T) {			_, errRelease := client.FetchLatestRelease(context.Background(), plugin)			var rateLimit *internalpluginstore.RateLimitError			if !errors.As(errRelease, &rateLimit) {				t.Fatalf("Home client did not inherit the proxy cooldown: %v", errRelease)			}		})	}	if proxyCalls.Load() != 0 {		t.Fatalf("cooldown made %d proxy requests, want 0", proxyCalls.Load())	}}