Use the mocks for tests and benchmarks.

This commit is contained in:
2024-09-13 21:27:34 +01:00
parent 7a791965ca
commit 50c1033ad1
5 changed files with 126 additions and 158 deletions
+5
View File
@@ -1,6 +1,7 @@
package gql package gql
import ( import (
"net/http"
"time" "time"
"github.com/gookit/goutil/envutil" "github.com/gookit/goutil/envutil"
@@ -38,3 +39,7 @@ func (b *BaseClient) SetOutput(responseType string) {
// TODO: implement // TODO: implement
b.responseType = responseType b.responseType = responseType
} }
func (b *BaseClient) SetHTTPClient(client *http.Client) {
b.client = client
}
+67
View File
@@ -0,0 +1,67 @@
// mock_server.go
package gql
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"golang.org/x/net/http2"
)
func StartMockServer() *httptest.Server {
// Create your handler
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Your existing handler code
bodyBytes, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
var req struct {
Query string `json:"query"`
Variables map[string]interface{} `json:"variables"`
}
err = json.Unmarshal(bodyBytes, &req)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
// Simple validation to check for unbalanced braces as a syntax error
if !strings.HasPrefix(strings.TrimSpace(req.Query), "query") || !strings.HasSuffix(strings.TrimSpace(req.Query), "}") {
resp := []byte(`{"errors":[{"message":"Syntax Error: Invalid query"}]}`)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
w.Write(resp)
return
}
var resp []byte
if strings.Contains(req.Query, "viewer") {
resp = []byte(`{"data":{"viewer":{"login":"mockuser"}}}`)
} else if strings.Contains(req.Query, "dragons") {
resp = []byte(`{"data":{"dragons":[{"name":"Mock Dragon 1"},{"name":"Mock Dragon 2"}]}}`)
} else {
resp = []byte(`{"errors":[{"message":"Unknown query"}]}`)
w.WriteHeader(http.StatusBadRequest)
}
w.Header().Set("Content-Type", "application/json")
w.Write(resp)
})
// Create an unstarted server
server := httptest.NewUnstartedServer(handler)
// Configure the server to support HTTP/2
http2.ConfigureServer(server.Config, &http2.Server{})
server.TLS = server.Config.TLSConfig
// Start the server with TLS
server.StartTLS()
return server
}
+19 -2
View File
@@ -36,10 +36,15 @@ func Benchmark_convertToJson(bn *testing.B) {
b.convertToJSON(query) b.convertToJSON(query)
} }
} }
func Benchmark_Query(bn *testing.B) { func Benchmark_Query(bn *testing.B) {
mockServer := StartMockServer()
bn.Cleanup(func() {
mockServer.Close()
})
b := NewConnection() b := NewConnection()
query := `query { viewer { login } }` b.SetEndpoint(mockServer.URL)
query := "query { viewer { login } }"
variables := map[string]interface{}{ variables := map[string]interface{}{
"var1": "value1", "var1": "value1",
} }
@@ -54,7 +59,13 @@ func Benchmark_Query(bn *testing.B) {
} }
func Benchmark_QueryNoCacheNoRetry(bn *testing.B) { func Benchmark_QueryNoCacheNoRetry(bn *testing.B) {
mockServer := StartMockServer()
bn.Cleanup(func() {
mockServer.Close()
})
b := NewConnection() b := NewConnection()
b.SetEndpoint(mockServer.URL)
query := `query { viewer { login } }` query := `query { viewer { login } }`
variables := map[string]interface{}{ variables := map[string]interface{}{
"var1": "value1", "var1": "value1",
@@ -69,7 +80,13 @@ func Benchmark_QueryNoCacheNoRetry(bn *testing.B) {
} }
func Benchmark_QueryWithEmptyVariables(bn *testing.B) { func Benchmark_QueryWithEmptyVariables(bn *testing.B) {
mockServer := StartMockServer()
bn.Cleanup(func() {
mockServer.Close()
})
b := NewConnection() b := NewConnection()
b.SetEndpoint(mockServer.URL)
query := `query { viewer { login } }` query := `query { viewer { login } }`
headers := map[string]interface{}{ headers := map[string]interface{}{
"Authorization": "Bearer token", "Authorization": "Bearer token",
+20 -155
View File
@@ -115,182 +115,48 @@ func (suite *Tests) TestBaseClient_Query() {
args args args args
wantReturned_value any wantReturned_value any
name string name string
graphQLServer string
wantType string wantType string
wantErr bool wantErr bool
}{ }{
{ {
name: "TestBaseClient_Query_spacex_working", name: "TestBaseClient_Query_viewer",
graphQLServer: "https://spacex-production.up.railway.app/",
args: args{ args: args{
query: `query Dragons { query: "query { viewer { login } }",
dragons {
name
}
}`,
variables: nil, variables: nil,
headers: map[string]interface{}{ headers: map[string]interface{}{
"x-apollo-operation-name": "Dragons/github.com/lukaszraczylo/go-simple-graphql", "x-apollo-operation-name": "ViewerQuery",
"content-type": "application/json", "content-type": "application/json",
}, },
}, },
wantReturned_value: string(`{"dragons":[{"name":"Dragon 1"},{"name":"Dragon 2"}]}`), wantReturned_value: `{"viewer":{"login":"mockuser"}}`, // Adjusted expected value
wantErr: false, wantErr: false,
}, },
{ {
name: "TestBaseClient_Query_spacex_invalid_query", name: "TestBaseClient_Query_dragons",
graphQLServer: "https://spacex-production.up.railway.app/",
args: args{ args: args{
query: `query Dragons { query: `query Dragons {
dragons { dragons {
name name
} }
`, }`,
variables: nil, variables: nil,
headers: map[string]interface{}{ headers: map[string]interface{}{
"x-apollo-operation-name": "Dragons/github.com/lukaszraczylo/go-simple-graphql", "x-apollo-operation-name": "DragonsQuery",
"content-type": "application/json", "content-type": "application/json",
}, },
}, },
wantReturned_value: nil, wantReturned_value: `{"dragons":[{"name":"Mock Dragon 1"},{"name":"Mock Dragon 2"}]}`, // Adjusted expected value
wantErr: true,
},
{
name: "TestBaseClient_Query_tgbotapp_working",
graphQLServer: "https://telegram-bot.app/v1/graphql",
args: args{
query: `query {
__type(name: "Query") {
name
}
}`,
},
wantReturned_value: string(`{"__type":null}`),
wantErr: false, wantErr: false,
}, },
{ {
name: "TestBaseClient_Query_tgbotapp_invalid_query", name: "TestBaseClient_Query_invalid_query",
graphQLServer: "https://telegram-bot.app/v1/graphql",
args: args{ args: args{
query: `query { query: "query { potato { login } ",
__type(name: "Query") { variables: nil,
name headers: map[string]interface{}{
} "x-apollo-operation-name": "InvalidQuery",
`, "content-type": "application/json",
},
wantReturned_value: nil,
wantErr: true,
},
{
name: "TestBaseClient_Query_tgbotapp_invalid_wrong_field",
graphQLServer: "https://telegram-bot.app/v1/graphql",
args: args{
query: `query {
__type(name: "Query") {
name2
}
}`,
},
wantReturned_value: nil,
wantErr: true,
},
{
name: "TestBaseClient_Query_tgbotapp_wrong_url",
graphQLServer: "https://telegram-bot.app/v0/graphql",
args: args{
query: `query {
__type(name: "Query") {
name
}
}`,
},
wantReturned_value: nil,
wantErr: true,
},
{
name: "TestBaseClient_Query_tgbotapp_valid_query_mapstring",
graphQLServer: "https://telegram-bot.app/v1/graphql",
wantType: "mapstring",
args: args{
query: `query {
__type(name: "Query") {
name
}
}`,
},
wantReturned_value: map[string]interface{}{"__type": nil},
wantErr: false,
},
{
name: "TestBaseClient_Query_tgbotapp_valid_query_byte",
graphQLServer: "https://telegram-bot.app/v1/graphql",
wantType: "byte",
args: args{
query: `query {
__type(name: "Query") {
name
}
}`,
},
wantReturned_value: []byte(`{"__type":null}`),
wantErr: false,
},
{
name: "TestBaseClient_Query_tgbotapp_valid_query_string",
graphQLServer: "https://telegram-bot.app/v1/graphql",
wantType: "string",
args: args{
query: `query {
__type(name: "Query") {
name
}
}`,
},
wantReturned_value: string(`{"__type":null}`),
wantErr: false,
},
{
name: "TestBaseClient_Query_tgbotapp_valid_query_invalid_type",
graphQLServer: "https://telegram-bot.app/v1/graphql",
wantType: "potato",
args: args{
query: `query {
__type(name: "Query") {
name
}
}`,
},
wantReturned_value: nil,
wantErr: true,
},
{
name: "TestBaseClient_Query_tgbotapp_valid_query_cache",
graphQLServer: "https://telegram-bot.app/v1/graphql",
args: args{
query: `query {
__type(name: "Query") {
name
}
}`,
variables: map[string]interface{}{
"gqlcache": true,
},
},
wantReturned_value: string(`{"__type":null}`),
wantErr: false,
},
{
name: "TestBaseClient_Query_tgbotapp_valid_query_with_retry",
graphQLServer: "https://telegram-bot.app/v0/graphql",
wantType: "byte",
args: args{
query: `query {
__type(name: "Query") {
name
}
}`,
variables: map[string]interface{}{
"gqlretries": true,
}, },
}, },
wantReturned_value: nil, wantReturned_value: nil,
@@ -300,9 +166,8 @@ func (suite *Tests) TestBaseClient_Query() {
for _, tt := range tests { for _, tt := range tests {
suite.T().Run(tt.name, func(t *testing.T) { suite.T().Run(tt.name, func(t *testing.T) {
b := NewConnection() b := NewConnection()
if tt.graphQLServer != "" { b.SetEndpoint(mockServer.URL)
b.SetEndpoint(tt.graphQLServer) b.SetHTTPClient(mockServer.Client())
}
if tt.wantType != "" { if tt.wantType != "" {
b.SetOutput(tt.wantType) b.SetOutput(tt.wantType)
} }
+15 -1
View File
@@ -1,6 +1,7 @@
package gql package gql
import ( import (
"net/http/httptest"
"testing" "testing"
assertions "github.com/stretchr/testify/assert" assertions "github.com/stretchr/testify/assert"
@@ -12,9 +13,22 @@ type Tests struct {
} }
var ( var (
assert *assertions.Assertions assert *assertions.Assertions
mockServer *httptest.Server
) )
func (suite *Tests) SetupSuite() {
// Start mock GraphQL server
mockServer = StartMockServer()
}
func (suite *Tests) TearDownSuite() {
// Close the mock server
if mockServer != nil {
mockServer.Close()
}
}
func (suite *Tests) SetupTest() { func (suite *Tests) SetupTest() {
assert = assertions.New(suite.T()) assert = assertions.New(suite.T())
} }