Skip to content

Commit

Permalink
simplify code and add more test for better coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
bubbajoe committed May 12, 2024
1 parent 5dd3fd9 commit 2fbe229
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 62 deletions.
13 changes: 8 additions & 5 deletions cmd/dgate-cli/commands/run_cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ func TestCommands_ClientError(t *testing.T) {
if assert.NotNil(t, err, "no error on %s:%s", action, resource) {
assert.Equal(t, "error", err.Error())
}
if action == "delete" && resource == "document" {
mockClient.On("DeleteAllDocument", "test", "test").
Return(errors.New("error"))
err = Run(mockClient, version)
if assert.NotNil(t, err, "no error on %s:%s", action, resource) {
assert.Equal(t, "error", err.Error())
}
}
}
}
}
Expand All @@ -186,11 +194,6 @@ func (m *mockDGClient) Init(baseUrl string, opts ...dgclient.Options) error {
return args.Error(0)
}

func (m *mockDGClient) BaseUrl() string {
args := m.Called()
return args.String(0)
}

func (m *mockDGClient) GetRoute(name, namespace string) (*spec.Route, error) {
args := m.Called(name, namespace)
if args.Get(0) == nil {
Expand Down
48 changes: 16 additions & 32 deletions pkg/dgclient/dgclient.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dgclient

import (
"errors"
"fmt"
"net/http"
"net/url"
Expand All @@ -10,8 +11,6 @@ import (

type DGateClient interface {
Init(baseUrl string, opts ...Options) error
BaseUrl() string

DGateNamespaceClient
DGateModuleClient
DGateRouteClient
Expand Down Expand Up @@ -42,25 +41,25 @@ func (d *dgateClient) Init(baseUrl string, opts ...Options) error {
return err
}

if bUrl.Scheme == "" {
bUrl.Scheme = "http"
} else if bUrl.Host == "" {
return url.InvalidHostError("host is empty")
if bUrl.Host == "" {
return errors.New("host is empty")
} else {
d.baseUrl = bUrl
}

d.client = http.DefaultClient
d.baseUrl = bUrl

for _, opt := range opts {
opt(d)
if opt != nil {
opt(d)
}
}
if d.client == nil {
d.client = http.DefaultClient
} else if d.client.Transport == nil {
d.client.Transport = http.DefaultTransport

Check warning on line 58 in pkg/dgclient/dgclient.go

View check run for this annotation

Codecov / codecov/patch

pkg/dgclient/dgclient.go#L58

Added line #L58 was not covered by tests
}
return nil
}

func (d *dgateClient) BaseUrl() string {
return d.baseUrl.String()
}

func WithHttpClient(client *http.Client) Options {
return func(dc DGateClient) {
if d, ok := dc.(*dgateClient); ok {
Expand Down Expand Up @@ -99,14 +98,8 @@ func (ct *customTransport) RoundTrip(req *http.Request) (*http.Response, error)
}

func WithBasicAuth(username, password string) Options {
if username == "" || password == "" {
return nil
}
return func(dc DGateClient) {
if d, ok := dc.(*dgateClient); ok {
if d.client.Transport == nil {
d.client.Transport = http.DefaultTransport
}
if ct, ok := d.client.Transport.(*customTransport); ok {
ct.Username = username
ct.Password = password
Expand All @@ -124,25 +117,19 @@ func WithBasicAuth(username, password string) Options {
func WithFollowRedirect(follow bool) Options {
return func(dc DGateClient) {
if d, ok := dc.(*dgateClient); ok {
if follow {
return
}
d.client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
if follow {
return nil
}
return http.ErrUseLastResponse
}
}
}
}

func WithUserAgent(ua string) Options {
if ua == "" {
return nil
}
return func(dc DGateClient) {
if d, ok := dc.(*dgateClient); ok {
if d.client.Transport == nil {
d.client.Transport = http.DefaultTransport
}
if ct, ok := d.client.Transport.(*customTransport); ok {
ct.UserAgent = ua
ct.Transport = http.DefaultTransport
Expand All @@ -159,9 +146,6 @@ func WithUserAgent(ua string) Options {
func WithVerboseLogging(on bool) Options {
return func(dc DGateClient) {
if d, ok := dc.(*dgateClient); ok {
if d.client.Transport == nil {
d.client.Transport = http.DefaultTransport
}
if ct, ok := d.client.Transport.(*customTransport); ok {
ct.VerboseLog = on
} else {
Expand Down
204 changes: 204 additions & 0 deletions pkg/dgclient/dgclient_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package dgclient_test

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/dgate-io/dgate/pkg/dgclient"
"github.com/stretchr/testify/assert"
)

func TestDGClient_OptionsWithRedirect(t *testing.T) {
var client = dgclient.NewDGateClient()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/api/v1/service/test" {
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
if r.Method == http.MethodGet {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"name":"test"}`))
}
}))
defer server.Close()

err := client.Init(server.URL,
dgclient.WithHttpClient(server.Client()),
dgclient.WithFollowRedirect(true),
)
if err != nil {
t.Fatal(err)
}

_, err = client.GetService("test", "default")
if err != nil {
t.Fatal(err)
}
}

func TestDGClient_OptionsRedirectError(t *testing.T) {
var client = dgclient.NewDGateClient()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if user, pass, _ := r.BasicAuth(); user != "user" || pass != "password" {
w.WriteHeader(http.StatusUnauthorized)
return
}
if r.URL.Path == "/api/v1/service/test" {
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
if r.Method == http.MethodGet {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"name":"test"}`))
}
}))
defer server.Close()

err := client.Init(server.URL,
dgclient.WithHttpClient(server.Client()),
dgclient.WithBasicAuth("user", "password"),
dgclient.WithFollowRedirect(false),
)
if err != nil {
t.Fatal(err)
}

_, err = client.GetService("test", "default")
if err == nil {
t.Fatal("expected error")
}
}

func TestDGClient_OptionsWithBasicAuth(t *testing.T) {
var client = dgclient.NewDGateClient()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if user, pass, _ := r.BasicAuth(); user != "user" || pass != "password" {
w.WriteHeader(http.StatusUnauthorized)
return
}
if r.Method == http.MethodGet {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"name":"test"}`))
}
}))
defer server.Close()

err := client.Init(server.URL,
dgclient.WithHttpClient(server.Client()),
dgclient.WithVerboseLogging(true),
dgclient.WithBasicAuth("user", "password"),
)
if err != nil {
t.Fatal(err)
}

_, err = client.GetService("test", "default")
if err != nil {
t.Fatal(err)
}
}

func TestDGClient_OptionsBasicAuthError(t *testing.T) {
var client = dgclient.NewDGateClient()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if user, pass, _ := r.BasicAuth(); user != "user" || pass != "password" {
w.WriteHeader(http.StatusUnauthorized)
return
}
if r.Method == http.MethodGet {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"name":"test"}`))
}
}))
defer server.Close()

err := client.Init(server.URL,
dgclient.WithHttpClient(server.Client()),
dgclient.WithBasicAuth("user", "wrongpassword"),
dgclient.WithVerboseLogging(true),
)
if err != nil {
t.Fatal(err)
}

_, err = client.GetService("test", "default")
if err == nil {
t.Fatal("expected error")
}
}

func TestDGClient_OptionsWithUserAgent(t *testing.T) {
var client = dgclient.NewDGateClient()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.UserAgent() != "test" {
w.WriteHeader(http.StatusBadRequest)
return
}
if r.Method == http.MethodGet {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"name":"test"}`))
}
}))
defer server.Close()

err := client.Init(server.URL,
dgclient.WithHttpClient(server.Client()),
dgclient.WithVerboseLogging(true),
dgclient.WithUserAgent("test"),
)
if err != nil {
t.Fatal(err)
}

_, err = client.GetService("test", "default")
if err != nil {
t.Fatal(err)
}
}

func TestDGClient_OptionsWithUserAgent2(t *testing.T) {
var client = dgclient.NewDGateClient()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.UserAgent() != "test" {
w.WriteHeader(http.StatusBadRequest)
return
}
if r.Method == http.MethodGet {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"name":"test"}`))
}
}))
defer server.Close()

err := client.Init(server.URL,
dgclient.WithHttpClient(server.Client()),
dgclient.WithUserAgent("test"),
dgclient.WithVerboseLogging(true),
)
if err != nil {
t.Fatal(err)
}

_, err = client.GetService("test", "default")
if err != nil {
t.Fatal(err)
}
}

func TestDGClient_Init_ParseURLError(t *testing.T) {
var client = dgclient.NewDGateClient()
err := client.Init("://#/:asdm")
if err == nil {
t.Fatal("expected error")
}
}

func TestDGClient_Init_EmptyHostError(t *testing.T) {
var client = dgclient.NewDGateClient()
err := client.Init("")
if err == nil {
t.Fatal("expected error")
}
assert.Equal(t, "host is empty", err.Error())
}
9 changes: 6 additions & 3 deletions pkg/modules/extractors/extractors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"net/http"
"net/url"
"strings"
"time"

"github.com/dgate-io/dgate/pkg/eventloop"
Expand Down Expand Up @@ -83,7 +84,6 @@ func DefaultFetchUpstreamFunction() FetchUpstreamUrlFunc {
}
}

// const _ goja.AsyncContextTracker = ExtractorContextTracker{""}
func ExtractFetchUpstreamFunction(
loop *eventloop.EventLoop,
) (fetchUpstream FetchUpstreamUrlFunc, err error) {
Expand All @@ -101,6 +101,9 @@ func ExtractFetchUpstreamFunction(
if goja.IsUndefined(res) || goja.IsNull(res) || upstreamUrlString == "" {
return nil, errors.New("fetchUpstream returned an invalid URL")
}
if !strings.Contains(upstreamUrlString, "://") {
upstreamUrlString += "http://"

Check warning on line 105 in pkg/modules/extractors/extractors.go

View check run for this annotation

Codecov / codecov/patch

pkg/modules/extractors/extractors.go#L104-L105

Added lines #L104 - L105 were not covered by tests
}
upstreamUrl, err := url.Parse(upstreamUrlString)
if err != nil {
return nil, err
Expand All @@ -121,7 +124,7 @@ func ExtractRequestModifierFunction(
if call, ok := goja.AssertFunction(rt.Get("requestModifier")); ok {
requestModifier = func(modCtx *types.ModuleContext) error {
_, err := RunAndWaitForResult(
rt, call, types.ToValue(rt, modCtx),
rt, call, rt.ToValue(modCtx),

Check warning on line 127 in pkg/modules/extractors/extractors.go

View check run for this annotation

Codecov / codecov/patch

pkg/modules/extractors/extractors.go#L127

Added line #L127 was not covered by tests
)
return err
}
Expand All @@ -137,7 +140,7 @@ func ExtractResponseModifierFunction(
responseModifier = func(modCtx *types.ModuleContext, res *http.Response) error {
modCtx = types.ModuleContextWithResponse(modCtx, res)
_, err := RunAndWaitForResult(
rt, call, types.ToValue(rt, modCtx),
rt, call, rt.ToValue(modCtx),

Check warning on line 143 in pkg/modules/extractors/extractors.go

View check run for this annotation

Codecov / codecov/patch

pkg/modules/extractors/extractors.go#L143

Added line #L143 was not covered by tests
)
return err
}
Expand Down
Loading

0 comments on commit 2fbe229

Please sign in to comment.