Skip to content

Commit 62746fe

Browse files
committed
feat: increase cov
1 parent e32535d commit 62746fe

File tree

1 file changed

+124
-142
lines changed

1 file changed

+124
-142
lines changed

handler_test.go

Lines changed: 124 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -2,199 +2,181 @@ package vibeGraphql
22

33
import (
44
"bytes"
5-
"encoding/json"
65
"mime/multipart"
76
"net/http"
87
"net/http/httptest"
98
"testing"
109
)
1110

12-
func TestBuildValue_Object(t *testing.T) {
13-
objValue := &Value{
14-
Kind: "Object",
15-
ObjectFields: map[string]*Value{
16-
"key": {Kind: "String", Literal: "value"},
17-
"num": {Kind: "Int", Literal: "42"},
18-
},
19-
}
20-
result := buildValue(objValue, nil)
21-
m, ok := result.(map[string]interface{})
22-
if !ok {
23-
t.Fatalf("expected map[string]interface{}, got %T", result)
11+
func TestResolveArgument_Variable_Found(t *testing.T) {
12+
vars := map[string]interface{}{
13+
"var1": "variableValue",
2414
}
25-
if m["key"] != "value" {
26-
t.Errorf("expected key 'value', got %v", m["key"])
15+
arg := &Argument{Value: &Value{Kind: "Variable", Literal: "var1"}}
16+
result, err := resolveArgument(arg, vars)
17+
if err != nil {
18+
t.Fatalf("unexpected error: %v", err)
2719
}
28-
// buildValue for Int converts to int.
29-
if m["num"] != 42 {
30-
t.Errorf("expected num 42, got %v", m["num"])
20+
if result != "variableValue" {
21+
t.Errorf("expected 'variableValue', got %v", result)
3122
}
3223
}
3324

34-
func TestGraphqlHandler_InvalidJSON(t *testing.T) {
35-
req := httptest.NewRequest("POST", "/graphql", bytes.NewBuffer([]byte("invalid json")))
36-
w := httptest.NewRecorder()
25+
func TestResolveArgument_Variable_NotFound(t *testing.T) {
26+
arg := &Argument{Value: &Value{Kind: "Variable", Literal: "missingVar"}}
27+
_, err := resolveArgument(arg, nil)
28+
if err == nil {
29+
t.Error("expected an error for missing variable, got nil")
30+
}
31+
}
3732

38-
GraphqlHandler(w, req)
39-
resp := w.Result()
40-
defer resp.Body.Close()
33+
// ---------- Additional test for reflectResolve ----------
4134

42-
if resp.StatusCode != http.StatusBadRequest {
43-
t.Errorf("expected status 400 for invalid JSON, got %d", resp.StatusCode)
44-
}
35+
// DummyStruct is used to test reflective field resolution.
36+
type DummyStruct struct {
37+
FieldA string `json:"fieldA"`
38+
FieldB int
4539
}
4640

47-
func TestGraphqlHandler_NoQuery(t *testing.T) {
48-
// Send a JSON payload without the "query" field.
49-
payload := map[string]interface{}{
50-
"notQuery": "test",
51-
}
52-
body, err := json.Marshal(payload)
41+
func TestReflectResolve(t *testing.T) {
42+
dummy := DummyStruct{FieldA: "valueA", FieldB: 99}
43+
// Test by using the JSON tag.
44+
field := &Field{Name: "fieldA"}
45+
res, err := reflectResolve(dummy, field)
5346
if err != nil {
54-
t.Fatalf("failed to marshal payload: %v", err)
47+
t.Fatalf("unexpected error: %v", err)
5548
}
56-
57-
req := httptest.NewRequest("POST", "/graphql", bytes.NewBuffer(body))
58-
w := httptest.NewRecorder()
59-
60-
GraphqlHandler(w, req)
61-
resp := w.Result()
62-
defer resp.Body.Close()
63-
64-
// When query is missing, the parser will likely create an empty document and return an error.
65-
if resp.StatusCode != http.StatusInternalServerError {
66-
t.Errorf("expected status 500 for missing query, got %d", resp.StatusCode)
49+
if res != "valueA" {
50+
t.Errorf("expected 'valueA', got %v", res)
6751
}
68-
}
6952

70-
func TestGraphqlUploadHandler_MissingOperations(t *testing.T) {
71-
// Simulate a multipart request missing the "operations" field.
72-
var buf bytes.Buffer
73-
writer := multipart.NewWriter(&buf)
74-
// Create a dummy file field.
75-
part, err := writer.CreateFormFile("file1", "dummy.txt")
53+
// Test by matching struct field name directly (case-insensitive).
54+
field = &Field{Name: "FIELDB"}
55+
res, err = reflectResolve(dummy, field)
7656
if err != nil {
77-
t.Fatalf("failed to create form file: %v", err)
57+
t.Fatalf("unexpected error: %v", err)
58+
}
59+
if res != 99 {
60+
t.Errorf("expected 99, got %v", res)
7861
}
79-
part.Write([]byte("dummy content"))
80-
writer.Close()
81-
82-
req := httptest.NewRequest("POST", "/graphql/upload", &buf)
83-
req.Header.Set("Content-Type", "multipart/form-data; boundary="+writer.Boundary())
84-
85-
w := httptest.NewRecorder()
86-
GraphqlUploadHandler(w, req)
87-
resp := w.Result()
88-
defer resp.Body.Close()
8962

90-
if resp.StatusCode != http.StatusBadRequest {
91-
t.Errorf("expected status 400 for missing operations field, got %d", resp.StatusCode)
63+
// Test with a non-existent field.
64+
field = &Field{Name: "nonexistent"}
65+
_, err = reflectResolve(dummy, field)
66+
if err == nil {
67+
t.Error("expected error for nonexistent field, got nil")
9268
}
9369
}
9470

95-
func TestGraphqlUploadHandler_InvalidMap(t *testing.T) {
96-
// Simulate a multipart request with invalid JSON in the "map" field.
97-
var buf bytes.Buffer
98-
writer := multipart.NewWriter(&buf)
99-
// Write a valid operations field.
100-
writer.WriteField("operations", `{"query": "{ hello }", "variables": {}}`)
101-
// Write an invalid map field.
102-
writer.WriteField("map", "not a valid json")
103-
writer.Close()
71+
// ---------- Additional test for executeSelectionSet with nested selections ----------
10472

105-
req := httptest.NewRequest("POST", "/graphql/upload", &buf)
106-
req.Header.Set("Content-Type", "multipart/form-data; boundary="+writer.Boundary())
73+
// DummyUser is used to simulate nested field resolution.
74+
type DummyUser struct {
75+
Name string `json:"name"`
76+
Age int `json:"age"`
77+
}
78+
79+
func TestExecuteSelectionSet_Nested(t *testing.T) {
80+
// Create a dummy user.
81+
user := DummyUser{Name: "Alice", Age: 30}
10782

108-
w := httptest.NewRecorder()
109-
GraphqlUploadHandler(w, req)
110-
resp := w.Result()
111-
defer resp.Body.Close()
83+
// Manually create a selection set requesting "name" and "age".
84+
selectionSet := &SelectionSet{
85+
Selections: []Selection{
86+
&Field{Name: "name"},
87+
&Field{Name: "age"},
88+
},
89+
}
11290

113-
if resp.StatusCode != http.StatusBadRequest {
114-
t.Errorf("expected status 400 for invalid map JSON, got %d", resp.StatusCode)
91+
// Call executeSelectionSet with the dummy user as source.
92+
result, err := executeSelectionSet(user, selectionSet, nil)
93+
if err != nil {
94+
t.Fatalf("unexpected error: %v", err)
11595
}
116-
}
11796

118-
func TestSetNestedValueAndArrayValue(t *testing.T) {
119-
var vars = make(map[string]interface{})
120-
// Test setting a nested value.
121-
setNestedValue(vars, "user.name", "Alice")
122-
if vars["user"] == nil {
123-
t.Fatal("expected nested map for user")
97+
// Verify that the resulting map contains the expected values.
98+
if result["name"] != "Alice" {
99+
t.Errorf("expected name 'Alice', got %v", result["name"])
124100
}
125-
userMap, ok := vars["user"].(map[string]interface{})
126-
if !ok {
127-
t.Fatalf("expected map for user, got %T", vars["user"])
101+
if result["age"] != 30 {
102+
t.Errorf("expected age 30, got %v", result["age"])
128103
}
129-
if userMap["name"] != "Alice" {
130-
t.Errorf("expected user.name to be 'Alice', got %v", userMap["name"])
104+
}
105+
106+
// ---------- Additional test for buildArgs ----------
107+
108+
func TestBuildArgs(t *testing.T) {
109+
// Create a field with arguments.
110+
field := &Field{
111+
Name: "dummy",
112+
Arguments: []Argument{
113+
{Name: "arg1", Value: &Value{Kind: "String", Literal: "hello"}},
114+
{Name: "arg2", Value: &Value{Kind: "Int", Literal: "42"}},
115+
},
131116
}
132117

133-
// Test setting an array value.
134-
setNestedArrayValue(vars, "files.0", "file1.txt")
135-
arr, ok := vars["files"].([]interface{})
136-
if !ok {
137-
t.Fatalf("expected files to be an array, got %T", vars["files"])
118+
args := buildArgs(field, nil)
119+
if args["arg1"] != "hello" {
120+
t.Errorf("expected arg1 to be 'hello', got %v", args["arg1"])
138121
}
139-
if arr[0] != "file1.txt" {
140-
t.Errorf("expected files[0] to be 'file1.txt', got %v", arr[0])
122+
if args["arg2"] != 42 {
123+
t.Errorf("expected arg2 to be 42, got %v", args["arg2"])
141124
}
142125
}
143126

144-
func TestExecuteDocument_NoDefinitions(t *testing.T) {
145-
// Create a Document with no definitions.
146-
doc := &Document{}
127+
// ---------- Additional test for executeDocument error handling ----------
128+
129+
func TestExecuteDocument_UnsupportedDefinition(t *testing.T) {
130+
// Create a Document with an unsupported definition type.
131+
doc := &Document{
132+
Definitions: []Definition{
133+
// Using a dummy implementation of Definition.
134+
struct{ Node }{},
135+
},
136+
}
147137
_, err := executeDocument(doc, nil)
148138
if err == nil {
149-
t.Error("expected error for document with no definitions, got nil")
139+
t.Error("expected error for unsupported definition type, got nil")
150140
}
151141
}
152142

153-
func TestResolveField_NoResolver(t *testing.T) {
154-
// Ensure that resolveField returns an error when no resolver is registered.
155-
field := &Field{Name: "nonexistent"}
156-
_, err := resolveField(nil, field, nil)
157-
if err == nil {
158-
t.Error("expected error for unresolved field, got nil")
159-
}
160-
}
143+
// ---------- Additional multipart upload tests can be added if needed ----------
161144

162-
func dummyHelloResolver(source interface{}, args map[string]interface{}) (interface{}, error) {
163-
return "world", nil
164-
}
145+
// For example, you might simulate a successful file upload with valid operations and map fields.
146+
// (This would likely require a temporary file or buffer with the correct multipart data.)
147+
// Here’s an example placeholder test that you can expand upon:
165148

166-
func TestGraphqlHandler(t *testing.T) {
167-
// Register the dummy resolver for the "hello" field.
168-
QueryResolvers["hello"] = dummyHelloResolver
149+
func TestGraphqlUploadHandler_Success(t *testing.T) {
150+
// Register a dummy resolver for "hello"
151+
QueryResolvers["hello"] = func(source interface{}, args map[string]interface{}) (interface{}, error) {
152+
return "world", nil
153+
}
169154

170-
// Create a GraphQL query that requests the "hello" field.
171-
reqBody, err := json.Marshal(map[string]interface{}{
172-
"query": "query { hello }",
173-
})
155+
var buf bytes.Buffer
156+
writer := multipart.NewWriter(&buf)
157+
// Write valid operations field.
158+
writer.WriteField("operations", `{"query": "{ hello }", "variables": {}}`)
159+
// Write a valid map field.
160+
writer.WriteField("map", `{"file1": ["variables.file"]}`)
161+
// Create a dummy file.
162+
part, err := writer.CreateFormFile("file1", "dummy.txt")
174163
if err != nil {
175-
t.Fatalf("failed to marshal request body: %v", err)
164+
t.Fatalf("failed to create form file: %v", err)
176165
}
177-
req := httptest.NewRequest("POST", "/graphql", bytes.NewBuffer(reqBody))
178-
req.Header.Set("Content-Type", "application/json")
166+
part.Write([]byte("dummy content"))
167+
writer.Close()
179168

180-
// Create a ResponseRecorder to capture the response.
181-
rr := httptest.NewRecorder()
182-
GraphqlHandler(rr, req)
169+
// Use the proper upload endpoint.
170+
req := httptest.NewRequest("POST", "/graphql/upload", &buf)
171+
req.Header.Set("Content-Type", "multipart/form-data; boundary="+writer.Boundary())
183172

173+
rr := httptest.NewRecorder()
174+
GraphqlUploadHandler(rr, req)
184175
res := rr.Result()
185-
if res.StatusCode != http.StatusOK {
186-
t.Errorf("expected status OK, got %v", res.StatusCode)
187-
}
176+
defer res.Body.Close()
188177

189-
var result map[string]interface{}
190-
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
191-
t.Fatalf("failed to decode response body: %v", err)
192-
}
193-
data, ok := result["data"].(map[string]interface{})
194-
if !ok {
195-
t.Fatalf("expected response to contain 'data' field")
196-
}
197-
if data["hello"] != "world" {
198-
t.Errorf("expected field 'hello' to be 'world', got %v", data["hello"])
178+
// Expect 200 OK since the query resolves correctly.
179+
if res.StatusCode != http.StatusOK {
180+
t.Errorf("expected status 200, got %d", res.StatusCode)
199181
}
200182
}

0 commit comments

Comments
 (0)