Skip to content

Commit 6000ed5

Browse files
authored
Add graphql_nodes tests (#40)
* feat:add graphql_nodes tests Signed-off-by: nabil salah <nabil.salah203@gmail.com> * fix: linting Signed-off-by: nabil salah <nabil.salah203@gmail.com> --------- Signed-off-by: nabil salah <nabil.salah203@gmail.com>
1 parent 677070f commit 6000ed5

1 file changed

Lines changed: 278 additions & 0 deletions

File tree

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
package graphql
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
"net/http/httptest"
8+
"testing"
9+
"time"
10+
11+
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
const (
16+
realEndpoint = "https://graphql.dev.threefold.me/graphql"
17+
)
18+
19+
func mockGraphQLServer(t *testing.T, statusCode int, responseBody string) *httptest.Server {
20+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
21+
w.Header().Set("Content-Type", "application/json")
22+
w.WriteHeader(statusCode)
23+
fmt.Fprintln(w, responseBody)
24+
}))
25+
t.Cleanup(server.Close)
26+
return server
27+
}
28+
29+
func TestGetUpNodes_WithFilters(t *testing.T) {
30+
31+
gql, err := NewGraphQl(realEndpoint)
32+
require.NoError(t, err)
33+
ctx := context.Background()
34+
35+
t.Run("with node limit", func(t *testing.T) {
36+
nodes, err := gql.GetUpNodes(ctx, 5, 0, 0, false, false)
37+
require.NoError(t, err)
38+
39+
assert.LessOrEqual(t, len(nodes), 5)
40+
})
41+
42+
t.Run("with ipv4 filter", func(t *testing.T) {
43+
nodes, err := gql.GetUpNodes(ctx, 0, 0, 0, true, false)
44+
require.NoError(t, err)
45+
46+
for _, node := range nodes {
47+
assert.NotEmpty(t, node.PublicConfig.Ipv4)
48+
}
49+
})
50+
51+
t.Run("with ipv6 filter", func(t *testing.T) {
52+
nodes, err := gql.GetUpNodes(ctx, 0, 0, 0, false, true)
53+
require.NoError(t, err)
54+
55+
for _, node := range nodes {
56+
assert.NotEmpty(t, node.PublicConfig.Ipv6)
57+
}
58+
})
59+
}
60+
61+
func TestGetItemTotalCount(t *testing.T) {
62+
successResponse := `{
63+
"data": {
64+
"items": {
65+
"count": 42
66+
}
67+
}
68+
}`
69+
70+
server := mockGraphQLServer(t, http.StatusOK, successResponse)
71+
72+
t.Run("get count", func(t *testing.T) {
73+
gql, err := NewGraphQl(server.URL)
74+
require.NoError(t, err)
75+
76+
ctx := context.Background()
77+
count, err := gql.getItemTotalCount(ctx, "nodes", "where: {}")
78+
79+
require.NoError(t, err)
80+
assert.Equal(t, 42, count)
81+
})
82+
}
83+
84+
// TestExec tests the exec method directly
85+
func TestExec(t *testing.T) {
86+
successResponse := `{
87+
"data": {
88+
"test": "success"
89+
}
90+
}`
91+
92+
failureResponse := `{
93+
"errors": [
94+
{"message": "something went wrong"}
95+
]
96+
}`
97+
98+
successServer := mockGraphQLServer(t, http.StatusOK, successResponse)
99+
failureServer := mockGraphQLServer(t, http.StatusInternalServerError, failureResponse)
100+
101+
t.Run("success on first url", func(t *testing.T) {
102+
gql, err := NewGraphQl(successServer.URL)
103+
require.NoError(t, err)
104+
105+
result := struct {
106+
Test string
107+
}{}
108+
109+
err = gql.exec(context.Background(), "query { test }", &result, nil)
110+
require.NoError(t, err)
111+
assert.Equal(t, "success", result.Test)
112+
})
113+
114+
t.Run("fallback to second url", func(t *testing.T) {
115+
gql, err := NewGraphQl(failureServer.URL, successServer.URL)
116+
require.NoError(t, err)
117+
118+
result := struct {
119+
Test string
120+
}{}
121+
122+
err = gql.exec(context.Background(), "query { test }", &result, nil)
123+
require.NoError(t, err)
124+
assert.Equal(t, "success", result.Test)
125+
})
126+
127+
t.Run("all urls fail", func(t *testing.T) {
128+
gql, err := NewGraphQl(failureServer.URL, failureServer.URL)
129+
require.NoError(t, err)
130+
131+
result := struct {
132+
Test string
133+
}{}
134+
135+
err = gql.exec(context.Background(), "query { test }", &result, nil)
136+
require.Error(t, err)
137+
})
138+
}
139+
140+
func TestIntegration_NodeFiltering(t *testing.T) {
141+
142+
gql, err := NewGraphQl(realEndpoint)
143+
require.NoError(t, err)
144+
145+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
146+
defer cancel()
147+
148+
t.Run("nodes with IPv4 only", func(t *testing.T) {
149+
nodes, err := gql.GetUpNodes(ctx, 20, 0, 0, true, false)
150+
require.NoError(t, err)
151+
for i, node := range nodes {
152+
assert.NotEmpty(t, node.PublicConfig.Ipv4, "Node %d should have IPv4", i)
153+
}
154+
})
155+
156+
t.Run("nodes with IPv6 only", func(t *testing.T) {
157+
nodes, err := gql.GetUpNodes(ctx, 20, 0, 0, false, true)
158+
require.NoError(t, err)
159+
for i, node := range nodes {
160+
assert.NotEmpty(t, node.PublicConfig.Ipv6, "Node %d should have IPv6", i)
161+
}
162+
})
163+
164+
t.Run("nodes with both IPv4 and IPv6", func(t *testing.T) {
165+
nodes, err := gql.GetUpNodes(ctx, 10, 0, 0, true, true)
166+
require.NoError(t, err)
167+
for i, node := range nodes {
168+
assert.NotEmpty(t, node.PublicConfig.Ipv4, "Node %d should have IPv4", i)
169+
assert.NotEmpty(t, node.PublicConfig.Ipv6, "Node %d should have IPv6", i)
170+
}
171+
})
172+
}
173+
174+
func TestIntegration_PaginationAndLimits(t *testing.T) {
175+
176+
gql, err := NewGraphQl(realEndpoint)
177+
require.NoError(t, err)
178+
179+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
180+
defer cancel()
181+
182+
t.Run("different_limits", func(t *testing.T) {
183+
limits := []int{1, 5, 10, 20, 50}
184+
185+
for _, limit := range limits {
186+
nodes, err := gql.GetUpNodes(ctx, limit, 0, 0, false, false)
187+
require.NoError(t, err)
188+
assert.LessOrEqual(t, len(nodes), limit,
189+
"Returned %d nodes but limit was %d", len(nodes), limit)
190+
}
191+
})
192+
}
193+
194+
func TestIntegration_ErrorHandling(t *testing.T) {
195+
196+
t.Run("invalid_endpoint", func(t *testing.T) {
197+
gql, err := NewGraphQl("https://invalid-endpoint-that-does-not-exist.com/graphql")
198+
require.NoError(t, err)
199+
200+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
201+
defer cancel()
202+
203+
_, err = gql.GetUpNodes(ctx, 5, 0, 0, false, false)
204+
require.Error(t, err)
205+
})
206+
207+
t.Run("timeout_handling", func(t *testing.T) {
208+
gql, err := NewGraphQl(realEndpoint)
209+
require.NoError(t, err)
210+
211+
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Microsecond)
212+
defer cancel()
213+
214+
_, err = gql.GetUpNodes(ctx, 5, 0, 0, false, false)
215+
require.Error(t, err)
216+
})
217+
218+
t.Run("fallback_to_valid_endpoint", func(t *testing.T) {
219+
gql, err := NewGraphQl(
220+
"https://invalid-endpoint.com/graphql",
221+
realEndpoint,
222+
)
223+
require.NoError(t, err)
224+
225+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
226+
defer cancel()
227+
228+
nodes, err := gql.GetUpNodes(ctx, 5, 0, 0, false, false)
229+
require.NoError(t, err)
230+
assert.GreaterOrEqual(t, len(nodes), 0)
231+
})
232+
}
233+
234+
func TestIntegration_DataValidation(t *testing.T) {
235+
236+
gql, err := NewGraphQl(realEndpoint)
237+
require.NoError(t, err)
238+
239+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
240+
defer cancel()
241+
242+
nodes, err := gql.GetUpNodes(ctx, 20, 0, 0, false, false)
243+
require.NoError(t, err)
244+
245+
t.Run("node_id_validation", func(t *testing.T) {
246+
nodeIDs := make(map[uint32]bool)
247+
248+
for i, node := range nodes {
249+
assert.Greater(t, node.NodeID, uint32(0), "Node %d has invalid ID", i)
250+
251+
assert.False(t, nodeIDs[node.NodeID], "Duplicate node ID %d found", node.NodeID)
252+
nodeIDs[node.NodeID] = true
253+
}
254+
255+
})
256+
257+
t.Run("public_config_validation", func(t *testing.T) {
258+
var ipv4Count, ipv6Count int
259+
260+
for i, node := range nodes {
261+
hasIPv4 := node.PublicConfig.Ipv4 != ""
262+
hasIPv6 := node.PublicConfig.Ipv6 != ""
263+
264+
if hasIPv4 {
265+
ipv4Count++
266+
assert.Contains(t, node.PublicConfig.Ipv4, ".",
267+
"Node %d IPv4 doesn't look like an IP: %s", i, node.PublicConfig.Ipv4)
268+
}
269+
270+
if hasIPv6 {
271+
ipv6Count++
272+
assert.Contains(t, node.PublicConfig.Ipv6, ":",
273+
"Node %d IPv6 doesn't look like an IP: %s", i, node.PublicConfig.Ipv6)
274+
}
275+
}
276+
277+
})
278+
}

0 commit comments

Comments
 (0)