103 lines · 3.2 KB · Go
RawDownload
package pluginhost import (	"context"	"encoding/json"	"net/http"	"testing" 	"github.com/router-for-me/CLIProxyAPI/v7/sdk/pluginabi") type staticEnvelopePluginClient struct {	raw []byte} func (c staticEnvelopePluginClient) Call(context.Context, string, []byte) ([]byte, error) {	return c.raw, nil} func (c staticEnvelopePluginClient) Shutdown() {} func TestDecodeEnvelopeResultPreservesPluginHTTPStatus(t *testing.T) {	_, errDecode := decodeEnvelopeResult[rpcEmptyResponse](pluginabi.Envelope{		OK: false,		Error: &pluginabi.Error{			Code:       "plugin_error",			Message:    "license required",			HTTPStatus: http.StatusForbidden,		},	})	if errDecode == nil {		t.Fatal("decodeEnvelopeResult returned nil error")	}	if got := errDecode.Error(); got != "license required" {		t.Fatalf("error = %q, want license required", got)	}	statusProvider, ok := errDecode.(interface{ StatusCode() int })	if !ok {		t.Fatalf("error %T does not expose StatusCode", errDecode)	}	if got := statusProvider.StatusCode(); got != http.StatusForbidden {		t.Fatalf("status = %d, want %d", got, http.StatusForbidden)	}} func TestCallPluginReturnsPluginErrorWithoutMethodWrapper(t *testing.T) {	raw, errMarshal := json.Marshal(pluginabi.Envelope{		OK: false,		Error: &pluginabi.Error{			Code:       "plugin_error",			Message:    "license required",			HTTPStatus: http.StatusForbidden,		},	})	if errMarshal != nil {		t.Fatalf("marshal envelope: %v", errMarshal)	}	_, errCall := callPlugin[rpcEmptyResponse](context.Background(), staticEnvelopePluginClient{raw: raw}, pluginabi.MethodExecutorExecuteStream, rpcEmptyResponse{})	if errCall == nil {		t.Fatal("callPlugin returned nil error")	}	if got := errCall.Error(); got != "license required" {		t.Fatalf("error = %q, want license required", got)	}	statusProvider, ok := errCall.(interface{ StatusCode() int })	if !ok {		t.Fatalf("error %T does not expose StatusCode", errCall)	}	if got := statusProvider.StatusCode(); got != http.StatusForbidden {		t.Fatalf("status = %d, want %d", got, http.StatusForbidden)	}} func TestIsPluginErrorEnvelopeAcceptsNonzeroReturnEnvelope(t *testing.T) {	raw := marshalRPCError("plugin_error", "upstream failed")	if !isPluginErrorEnvelope(raw) {		t.Fatalf("isPluginErrorEnvelope(%s) = false, want true", raw)	}	if isPluginErrorEnvelope([]byte(`not json`)) {		t.Fatal("isPluginErrorEnvelope accepted invalid JSON")	}} func TestCallPluginPreservesStatusFromNewErrorEnvelope(t *testing.T) {	raw, errMarshal := pluginabi.NewErrorEnvelope("insufficient_quota", "plan limit reached", http.StatusForbidden)	if errMarshal != nil {		t.Fatalf("NewErrorEnvelope() error = %v", errMarshal)	}	_, errCall := callPlugin[rpcEmptyResponse](context.Background(), staticEnvelopePluginClient{raw: raw}, pluginabi.MethodExecutorExecute, rpcEmptyResponse{})	if errCall == nil {		t.Fatal("callPlugin returned nil error")	}	if got := errCall.Error(); got != "plan limit reached" {		t.Fatalf("error = %q, want plan limit reached", got)	}	statusProvider, ok := errCall.(interface{ StatusCode() int })	if !ok {		t.Fatalf("error %T does not expose StatusCode", errCall)	}	if got := statusProvider.StatusCode(); got != http.StatusForbidden {		t.Fatalf("status = %d, want %d", got, http.StatusForbidden)	}}