11package integration
22
33import (
4- "bytes"
54 "context"
65 "crypto/tls"
7- "fmt"
8- "io"
96 "net"
107 "net/http"
118 "testing"
@@ -16,8 +13,6 @@ import (
1613 "github.com/stretchr/testify/require"
1714 employeev1 "github.com/wundergraph/cosmo/router-tests/testdata/connectrpc/client/employee.v1"
1815 "github.com/wundergraph/cosmo/router-tests/testdata/connectrpc/client/employee.v1/employeev1connect"
19- "github.com/wundergraph/cosmo/router/pkg/connectrpc"
20- "go.uber.org/zap"
2116 "golang.org/x/net/http2"
2217)
2318
@@ -26,49 +21,15 @@ import (
2621func TestConnectRPC_ClientProtocols (t * testing.T ) {
2722 t .Parallel ()
2823
29- // Create mock GraphQL server
30- graphqlServer := newMockGraphQLServer (func (w http.ResponseWriter , r * http.Request ) {
31- w .Header ().Set ("Content-Type" , "application/json" )
32- w .WriteHeader (http .StatusOK )
33- w .Write ([]byte (`{
34- "data": {
35- "employee": {
36- "id": 1,
37- "tag": "employee-1",
38- "details": {
39- "forename": "John",
40- "surname": "Doe",
41- "pets": [{"name": "Fluffy"}],
42- "location": {"key": {"name": "San Francisco"}}
43- }
44- }
45- }
46- }` ))
24+ // Use shared helper for employee GraphQL handler
25+ ts := NewTestConnectRPCServer (t , ConnectRPCServerOptions {
26+ GraphQLHandler : EmployeeGraphQLHandler (),
4727 })
48- defer graphqlServer .Close ()
49-
50- // Start ConnectRPC server
51- graphqlEndpoint := graphqlServer .URL + "/graphql"
52- fmt .Printf ("[Test] Mock GraphQL Server URL: %s\n " , graphqlServer .URL )
53- fmt .Printf ("[Test] GraphQL Endpoint configured: %s\n " , graphqlEndpoint )
5428
55- server , err := connectrpc .NewServer (connectrpc.ServerConfig {
56- ServicesDir : "testdata/connectrpc/services" ,
57- GraphQLEndpoint : graphqlEndpoint ,
58- ListenAddr : "localhost:0" ,
59- Logger : zap .NewNop (),
60- })
29+ err := ts .Start ()
6130 require .NoError (t , err )
6231
63- err = server .Start ()
64- require .NoError (t , err )
65- defer func () {
66- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
67- defer cancel ()
68- server .Stop (ctx )
69- }()
70-
71- baseURL := "http://" + server .Addr ().String ()
32+ baseURL := "http://" + ts .Addr ().String ()
7233
7334 t .Run ("Connect protocol" , func (t * testing.T ) {
7435 client := employeev1connect .NewEmployeeServiceClient (
@@ -151,34 +112,16 @@ func TestConnectRPC_ClientErrorHandling(t *testing.T) {
151112 t .Parallel ()
152113
153114 t .Run ("GraphQL error with no data returns CRITICAL" , func (t * testing.T ) {
154- graphqlServer := newMockGraphQLServer (func (w http.ResponseWriter , r * http.Request ) {
155- w .Header ().Set ("Content-Type" , "application/json" )
156- w .WriteHeader (http .StatusOK )
157- w .Write ([]byte (`{
158- "errors": [{"message": "Employee not found"}]
159- }` ))
115+ ts := NewTestConnectRPCServer (t , ConnectRPCServerOptions {
116+ GraphQLHandler : ErrorGraphQLHandler ("Employee not found" ),
160117 })
161- defer graphqlServer .Close ()
162-
163- server , err := connectrpc .NewServer (connectrpc.ServerConfig {
164- ServicesDir : "testdata/connectrpc/services" ,
165- GraphQLEndpoint : graphqlServer .URL + "/graphql" ,
166- ListenAddr : "localhost:0" ,
167- Logger : zap .NewNop (),
168- })
169- require .NoError (t , err )
170-
171- err = server .Start ()
118+
119+ err := ts .Start ()
172120 require .NoError (t , err )
173- defer func () {
174- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
175- defer cancel ()
176- server .Stop (ctx )
177- }()
178121
179122 client := employeev1connect .NewEmployeeServiceClient (
180123 http .DefaultClient ,
181- "http://" + server .Addr ().String (),
124+ "http://" + ts .Addr ().String (),
182125 )
183126
184127 req := connect .NewRequest (& employeev1.GetEmployeeByIdRequest {
@@ -196,7 +139,8 @@ func TestConnectRPC_ClientErrorHandling(t *testing.T) {
196139 })
197140
198141 t .Run ("GraphQL error with partial data returns NON-CRITICAL" , func (t * testing.T ) {
199- graphqlServer := newMockGraphQLServer (func (w http.ResponseWriter , r * http.Request ) {
142+ // Custom handler for partial data with errors
143+ handler := func (w http.ResponseWriter , r * http.Request ) {
200144 w .Header ().Set ("Content-Type" , "application/json" )
201145 w .WriteHeader (http .StatusOK )
202146 w .Write ([]byte (`{
@@ -212,29 +156,19 @@ func TestConnectRPC_ClientErrorHandling(t *testing.T) {
212156 "errors": [{"message": "Could not fetch pets"}]
213157 }
214158 }` ))
159+ }
160+
161+ ts := NewTestConnectRPCServer (t , ConnectRPCServerOptions {
162+ GraphQLHandler : handler ,
215163 })
216- defer graphqlServer .Close ()
217-
218- server , err := connectrpc .NewServer (connectrpc.ServerConfig {
219- ServicesDir : "testdata/connectrpc/services" ,
220- GraphQLEndpoint : graphqlServer .URL + "/graphql" ,
221- ListenAddr : "localhost:0" ,
222- Logger : zap .NewNop (),
223- })
164+
165+ err := ts .Start ()
224166 require .NoError (t , err )
225167
226- err = server .Start ()
227- require .NoError (t , err )
228- defer func () {
229- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
230- defer cancel ()
231- server .Stop (ctx )
232- }()
233-
234168 time .Sleep (100 * time .Millisecond )
235169 client := employeev1connect .NewEmployeeServiceClient (
236170 http .DefaultClient ,
237- "http://" + server .Addr ().String (),
171+ "http://" + ts .Addr ().String (),
238172 )
239173
240174 req := connect .NewRequest (& employeev1.GetEmployeeByIdRequest {
@@ -250,31 +184,16 @@ func TestConnectRPC_ClientErrorHandling(t *testing.T) {
250184 })
251185
252186 t .Run ("HTTP 404 maps to CodeNotFound" , func (t * testing.T ) {
253- graphqlServer := newMockGraphQLServer (func (w http.ResponseWriter , r * http.Request ) {
254- w .WriteHeader (http .StatusNotFound )
255- w .Write ([]byte ("Not Found" ))
256- })
257- defer graphqlServer .Close ()
258-
259- server , err := connectrpc .NewServer (connectrpc.ServerConfig {
260- ServicesDir : "testdata/connectrpc/services" ,
261- GraphQLEndpoint : graphqlServer .URL + "/graphql" ,
262- ListenAddr : "localhost:0" ,
263- Logger : zap .NewNop (),
187+ ts := NewTestConnectRPCServer (t , ConnectRPCServerOptions {
188+ GraphQLHandler : HTTPErrorHandler (http .StatusNotFound , "Not Found" ),
264189 })
190+
191+ err := ts .Start ()
265192 require .NoError (t , err )
266193
267- err = server .Start ()
268- require .NoError (t , err )
269- defer func () {
270- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
271- defer cancel ()
272- server .Stop (ctx )
273- }()
274-
275194 client := employeev1connect .NewEmployeeServiceClient (
276195 http .DefaultClient ,
277- "http://" + server .Addr ().String (),
196+ "http://" + ts .Addr ().String (),
278197 )
279198
280199 req := connect .NewRequest (& employeev1.GetEmployeeByIdRequest {
@@ -290,31 +209,16 @@ func TestConnectRPC_ClientErrorHandling(t *testing.T) {
290209 })
291210
292211 t .Run ("HTTP 500 maps to CodeInternal" , func (t * testing.T ) {
293- graphqlServer := newMockGraphQLServer (func (w http.ResponseWriter , r * http.Request ) {
294- w .WriteHeader (http .StatusInternalServerError )
295- w .Write ([]byte ("Internal Server Error" ))
296- })
297- defer graphqlServer .Close ()
298-
299- server , err := connectrpc .NewServer (connectrpc.ServerConfig {
300- ServicesDir : "testdata/connectrpc/services" ,
301- GraphQLEndpoint : graphqlServer .URL + "/graphql" ,
302- ListenAddr : "localhost:0" ,
303- Logger : zap .NewNop (),
212+ ts := NewTestConnectRPCServer (t , ConnectRPCServerOptions {
213+ GraphQLHandler : HTTPErrorHandler (http .StatusInternalServerError , "Internal Server Error" ),
304214 })
215+
216+ err := ts .Start ()
305217 require .NoError (t , err )
306218
307- err = server .Start ()
308- require .NoError (t , err )
309- defer func () {
310- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
311- defer cancel ()
312- server .Stop (ctx )
313- }()
314-
315219 client := employeev1connect .NewEmployeeServiceClient (
316220 http .DefaultClient ,
317- "http://" + server .Addr ().String (),
221+ "http://" + ts .Addr ().String (),
318222 )
319223
320224 req := connect .NewRequest (& employeev1.GetEmployeeByIdRequest {
@@ -335,7 +239,7 @@ func TestConnectRPC_ClientConcurrency(t *testing.T) {
335239 t .Parallel ()
336240
337241 var requestCount int
338- graphqlServer := newMockGraphQLServer ( func (w http.ResponseWriter , r * http.Request ) {
242+ handler := func (w http.ResponseWriter , r * http.Request ) {
339243 requestCount ++
340244 w .Header ().Set ("Content-Type" , "application/json" )
341245 w .WriteHeader (http .StatusOK )
@@ -351,28 +255,18 @@ func TestConnectRPC_ClientConcurrency(t *testing.T) {
351255 }
352256 }
353257 }` ))
258+ }
259+
260+ ts := NewTestConnectRPCServer (t , ConnectRPCServerOptions {
261+ GraphQLHandler : handler ,
354262 })
355- defer graphqlServer .Close ()
356-
357- server , err := connectrpc .NewServer (connectrpc.ServerConfig {
358- ServicesDir : "testdata/connectrpc/services" ,
359- GraphQLEndpoint : graphqlServer .URL + "/graphql" ,
360- ListenAddr : "localhost:0" ,
361- Logger : zap .NewNop (),
362- })
363- require .NoError (t , err )
364-
365- err = server .Start ()
263+
264+ err := ts .Start ()
366265 require .NoError (t , err )
367- defer func () {
368- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
369- defer cancel ()
370- server .Stop (ctx )
371- }()
372266
373267 client := employeev1connect .NewEmployeeServiceClient (
374268 http .DefaultClient ,
375- "http://" + server .Addr ().String (),
269+ "http://" + ts .Addr ().String (),
376270 )
377271
378272 // Make 10 concurrent requests
@@ -396,62 +290,4 @@ func TestConnectRPC_ClientConcurrency(t *testing.T) {
396290 }
397291
398292 assert .Equal (t , numRequests , requestCount , "should have made all requests" )
399- }
400-
401- // mockGraphQLServer is a simple mock HTTP server for testing
402- type mockGraphQLServer struct {
403- server * http.Server
404- handler http.HandlerFunc
405- URL string
406- }
407-
408- func newMockGraphQLServer (handler http.HandlerFunc ) * mockGraphQLServer {
409- m := & mockGraphQLServer {
410- handler : handler ,
411- }
412-
413- mux := http .NewServeMux ()
414- mux .HandleFunc ("/graphql" , func (w http.ResponseWriter , r * http.Request ) {
415- // Log the incoming request for debugging
416- body , _ := io .ReadAll (r .Body )
417- r .Body .Close ()
418- r .Body = io .NopCloser (bytes .NewBuffer (body ))
419-
420- fmt .Printf ("[MockGraphQL] Request: %s %s\n " , r .Method , r .URL .Path )
421- fmt .Printf ("[MockGraphQL] Headers: %v\n " , r .Header )
422- fmt .Printf ("[MockGraphQL] Body: %s\n " , string (body ))
423-
424- if m .handler != nil {
425- m .handler (w , r )
426- }
427-
428- fmt .Printf ("[MockGraphQL] Response sent\n \n " )
429- })
430-
431- m .server = & http.Server {
432- Handler : mux ,
433- Addr : "127.0.0.1:0" ,
434- }
435-
436- listener , err := net .Listen ("tcp" , m .server .Addr )
437- if err != nil {
438- panic (err )
439- }
440-
441- m .URL = "http://" + listener .Addr ().String ()
442-
443- go m .server .Serve (listener )
444-
445- // Give the server a moment to start
446- time .Sleep (10 * time .Millisecond )
447-
448- return m
449- }
450-
451- func (m * mockGraphQLServer ) Close () {
452- if m .server != nil {
453- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
454- defer cancel ()
455- m .server .Shutdown (ctx )
456- }
457293}
0 commit comments