...

Source file src/github.com/99designs/gqlgen/graphql/handler/transport/sse_test.go

Documentation: github.com/99designs/gqlgen/graphql/handler/transport

     1  package transport_test
     2  
     3  import (
     4  	"bufio"
     5  	"io"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"strings"
     9  	"sync"
    10  	"testing"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"github.com/99designs/gqlgen/graphql/handler/testserver"
    16  	"github.com/99designs/gqlgen/graphql/handler/transport"
    17  )
    18  
    19  func TestSSE(t *testing.T) {
    20  	initialize := func() *testserver.TestServer {
    21  		h := testserver.New()
    22  		h.AddTransport(transport.SSE{})
    23  		return h
    24  	}
    25  
    26  	initializeWithServer := func() (*testserver.TestServer, *httptest.Server) {
    27  		h := initialize()
    28  		return h, httptest.NewServer(h)
    29  	}
    30  
    31  	createHTTPTestRequest := func(query string) *http.Request {
    32  		req := httptest.NewRequest(http.MethodPost, "/graphql", strings.NewReader(query))
    33  		req.Header.Set("Accept", "text/event-stream")
    34  		req.Header.Set("content-type", "application/json; charset=utf-8")
    35  		return req
    36  	}
    37  
    38  	createHTTPRequest := func(url string, query string) *http.Request {
    39  		req, err := http.NewRequest("POST", url, strings.NewReader(query))
    40  		require.NoError(t, err, "Request threw error -> %s", err)
    41  		req.Header.Set("Accept", "text/event-stream")
    42  		req.Header.Set("content-type", "application/json; charset=utf-8")
    43  		return req
    44  	}
    45  
    46  	readLine := func(br *bufio.Reader) string {
    47  		bs, err := br.ReadString('\n')
    48  		require.NoError(t, err)
    49  		return bs
    50  	}
    51  
    52  	t.Run("stream failure", func(t *testing.T) {
    53  		h := initialize()
    54  		req := httptest.NewRequest(http.MethodPost, "/graphql", strings.NewReader(`{"query":"subscription { name }"}`))
    55  		req.Header.Set("content-type", "application/json; charset=utf-8")
    56  		w := httptest.NewRecorder()
    57  		h.ServeHTTP(w, req)
    58  		assert.Equal(t, 400, w.Code, "Request return wrong status -> %d", w.Code)
    59  		assert.Equal(t, `{"errors":[{"message":"transport not supported"}],"data":null}`, w.Body.String())
    60  	})
    61  
    62  	t.Run("decode failure", func(t *testing.T) {
    63  		h := initialize()
    64  		req := createHTTPTestRequest("notjson")
    65  		w := httptest.NewRecorder()
    66  		h.ServeHTTP(w, req)
    67  		assert.Equal(t, 400, w.Code, "Request return wrong status -> %d", w.Code)
    68  		assert.Equal(t, `{"errors":[{"message":"json request body could not be decoded: invalid character 'o' in literal null (expecting 'u') body:notjson"}],"data":null}`, w.Body.String())
    69  	})
    70  
    71  	t.Run("parse failure", func(t *testing.T) {
    72  		h := initialize()
    73  		req := createHTTPTestRequest(`{"query":"subscription {{ name }"}`)
    74  		w := httptest.NewRecorder()
    75  		h.ServeHTTP(w, req)
    76  
    77  		assert.Equal(t, 200, w.Code, "Request return wrong status -> %d", w.Code)
    78  		assert.Equal(t, "keep-alive", w.Header().Get("Connection"))
    79  		assert.Equal(t, "text/event-stream", w.Header().Get("Content-Type"))
    80  
    81  		br := bufio.NewReader(w.Body)
    82  
    83  		assert.Equal(t, ":\n", readLine(br))
    84  		assert.Equal(t, "\n", readLine(br))
    85  		assert.Equal(t, "event: next\n", readLine(br))
    86  		assert.Equal(t, "data: {\"errors\":[{\"message\":\"Expected Name, found {\",\"locations\":[{\"line\":1,\"column\":15}],\"extensions\":{\"code\":\"GRAPHQL_PARSE_FAILED\"}}],\"data\":null}\n", readLine(br))
    87  		assert.Equal(t, "\n", readLine(br))
    88  		assert.Equal(t, "event: complete\n", readLine(br))
    89  		assert.Equal(t, "\n", readLine(br))
    90  
    91  		_, err := br.ReadByte()
    92  		assert.Equal(t, err, io.EOF)
    93  	})
    94  
    95  	t.Run("subscribe", func(t *testing.T) {
    96  		handler, srv := initializeWithServer()
    97  		defer srv.Close()
    98  
    99  		var wg sync.WaitGroup
   100  		wg.Add(1)
   101  		go func() {
   102  			defer wg.Done()
   103  			handler.SendNextSubscriptionMessage()
   104  		}()
   105  
   106  		client := &http.Client{}
   107  		req := createHTTPRequest(srv.URL, `{"query":"subscription { name }"}`)
   108  		res, err := client.Do(req)
   109  		require.NoError(t, err, "Request threw error -> %s", err)
   110  		defer func() {
   111  			require.NoError(t, res.Body.Close())
   112  		}()
   113  
   114  		assert.Equal(t, 200, res.StatusCode, "Request return wrong status -> %d", res.Status)
   115  		assert.Equal(t, "keep-alive", res.Header.Get("Connection"))
   116  		assert.Equal(t, "text/event-stream", res.Header.Get("Content-Type"))
   117  
   118  		br := bufio.NewReader(res.Body)
   119  
   120  		assert.Equal(t, ":\n", readLine(br))
   121  		assert.Equal(t, "\n", readLine(br))
   122  		assert.Equal(t, "event: next\n", readLine(br))
   123  		assert.Equal(t, "data: {\"data\":{\"name\":\"test\"}}\n", readLine(br))
   124  		assert.Equal(t, "\n", readLine(br))
   125  
   126  		wg.Add(1)
   127  		go func() {
   128  			defer wg.Done()
   129  			handler.SendNextSubscriptionMessage()
   130  		}()
   131  
   132  		assert.Equal(t, "event: next\n", readLine(br))
   133  		assert.Equal(t, "data: {\"data\":{\"name\":\"test\"}}\n", readLine(br))
   134  		assert.Equal(t, "\n", readLine(br))
   135  
   136  		wg.Add(1)
   137  		go func() {
   138  			defer wg.Done()
   139  			handler.SendCompleteSubscriptionMessage()
   140  		}()
   141  
   142  		assert.Equal(t, "event: complete\n", readLine(br))
   143  		assert.Equal(t, "\n", readLine(br))
   144  
   145  		_, err = br.ReadByte()
   146  		assert.Equal(t, err, io.EOF)
   147  
   148  		wg.Wait()
   149  	})
   150  }
   151  

View as plain text