github.com/influxdata/influxdb/v2@v2.7.6/remotes/transport/http_test.go (about) 1 package transport 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "net/http" 7 "net/http/httptest" 8 "testing" 9 10 "github.com/golang/mock/gomock" 11 "github.com/influxdata/influxdb/v2" 12 "github.com/influxdata/influxdb/v2/kit/platform" 13 "github.com/influxdata/influxdb/v2/remotes/mock" 14 "github.com/stretchr/testify/assert" 15 tmock "github.com/stretchr/testify/mock" 16 "github.com/stretchr/testify/require" 17 "go.uber.org/zap/zaptest" 18 ) 19 20 //go:generate go run github.com/golang/mock/mockgen -package mock -destination ../mock/service.go github.com/influxdata/influxdb/v2/remotes/transport RemoteConnectionService 21 22 var ( 23 orgStr = "1234123412341234" 24 orgID, _ = platform.IDFromString(orgStr) 25 remoteOrgStr = "9876987698769876" 26 remoteOrgID, _ = platform.IDFromString(remoteOrgStr) 27 idStr = "4321432143214321" 28 id, _ = platform.IDFromString(idStr) 29 testConn = influxdb.RemoteConnection{ 30 ID: *id, 31 OrgID: *orgID, 32 Name: "example", 33 RemoteURL: "https://influxdb.cloud", 34 RemoteOrgID: remoteOrgID, 35 AllowInsecureTLS: true, 36 } 37 ) 38 39 func TestRemoteConnectionHandler(t *testing.T) { 40 t.Run("get remotes happy path", func(t *testing.T) { 41 ts, svc := newTestServer(t) 42 defer ts.Close() 43 44 req := newTestRequest(t, "GET", ts.URL, nil) 45 46 q := req.URL.Query() 47 q.Add("orgID", orgStr) 48 q.Add("name", testConn.Name) 49 q.Add("remoteURL", testConn.RemoteURL) 50 req.URL.RawQuery = q.Encode() 51 52 expected := influxdb.RemoteConnections{Remotes: []influxdb.RemoteConnection{testConn}} 53 54 svc.EXPECT(). 55 ListRemoteConnections(gomock.Any(), tmock.MatchedBy(func(in influxdb.RemoteConnectionListFilter) bool { 56 return assert.Equal(t, *orgID, in.OrgID) && 57 assert.Equal(t, testConn.Name, *in.Name) && 58 assert.Equal(t, testConn.RemoteURL, *in.RemoteURL) 59 })).Return(&expected, nil) 60 61 res := doTestRequest(t, req, http.StatusOK, true) 62 63 var got influxdb.RemoteConnections 64 require.NoError(t, json.NewDecoder(res.Body).Decode(&got)) 65 require.Equal(t, expected, got) 66 }) 67 68 t.Run("create remote happy path", func(t *testing.T) { 69 ts, svc := newTestServer(t) 70 defer ts.Close() 71 72 body := influxdb.CreateRemoteConnectionRequest{ 73 OrgID: testConn.OrgID, 74 Name: testConn.Name, 75 RemoteURL: testConn.RemoteURL, 76 RemoteToken: "my super secret token", 77 RemoteOrgID: testConn.RemoteOrgID, 78 AllowInsecureTLS: testConn.AllowInsecureTLS, 79 } 80 81 req := newTestRequest(t, "POST", ts.URL, &body) 82 83 svc.EXPECT().CreateRemoteConnection(gomock.Any(), body).Return(&testConn, nil) 84 85 res := doTestRequest(t, req, http.StatusCreated, true) 86 87 var got influxdb.RemoteConnection 88 require.NoError(t, json.NewDecoder(res.Body).Decode(&got)) 89 require.Equal(t, testConn, got) 90 }) 91 92 t.Run("get remote happy path", func(t *testing.T) { 93 ts, svc := newTestServer(t) 94 defer ts.Close() 95 96 req := newTestRequest(t, "GET", ts.URL+"/"+id.String(), nil) 97 98 svc.EXPECT().GetRemoteConnection(gomock.Any(), *id).Return(&testConn, nil) 99 100 res := doTestRequest(t, req, http.StatusOK, true) 101 102 var got influxdb.RemoteConnection 103 require.NoError(t, json.NewDecoder(res.Body).Decode(&got)) 104 require.Equal(t, testConn, got) 105 }) 106 107 t.Run("delete remote happy path", func(t *testing.T) { 108 ts, svc := newTestServer(t) 109 defer ts.Close() 110 111 req := newTestRequest(t, "DELETE", ts.URL+"/"+id.String(), nil) 112 113 svc.EXPECT().DeleteRemoteConnection(gomock.Any(), *id).Return(nil) 114 115 doTestRequest(t, req, http.StatusNoContent, false) 116 }) 117 118 t.Run("update remote happy path", func(t *testing.T) { 119 ts, svc := newTestServer(t) 120 defer ts.Close() 121 122 newToken := "a new even more secret token" 123 body := influxdb.UpdateRemoteConnectionRequest{RemoteToken: &newToken} 124 125 req := newTestRequest(t, "PATCH", ts.URL+"/"+id.String(), &body) 126 127 svc.EXPECT().UpdateRemoteConnection(gomock.Any(), *id, body).Return(&testConn, nil) 128 129 res := doTestRequest(t, req, http.StatusOK, true) 130 131 var got influxdb.RemoteConnection 132 require.NoError(t, json.NewDecoder(res.Body).Decode(&got)) 133 require.Equal(t, testConn, got) 134 }) 135 136 t.Run("invalid remote IDs return 400", func(t *testing.T) { 137 ts, _ := newTestServer(t) 138 defer ts.Close() 139 140 req1 := newTestRequest(t, "GET", ts.URL+"/foo", nil) 141 req2 := newTestRequest(t, "PATCH", ts.URL+"/foo", &influxdb.UpdateRemoteConnectionRequest{}) 142 req3 := newTestRequest(t, "DELETE", ts.URL+"/foo", nil) 143 144 for _, req := range []*http.Request{req1, req2, req3} { 145 t.Run(req.Method, func(t *testing.T) { 146 doTestRequest(t, req, http.StatusBadRequest, true) 147 }) 148 } 149 }) 150 151 t.Run("invalid org ID to GET /remotes returns 400", func(t *testing.T) { 152 ts, _ := newTestServer(t) 153 defer ts.Close() 154 155 req := newTestRequest(t, "GET", ts.URL, nil) 156 q := req.URL.Query() 157 q.Add("orgID", "foo") 158 req.URL.RawQuery = q.Encode() 159 160 doTestRequest(t, req, http.StatusBadRequest, true) 161 }) 162 163 t.Run("invalid request bodies return 400", func(t *testing.T) { 164 ts, _ := newTestServer(t) 165 defer ts.Close() 166 167 body := "o no not an object" 168 req1 := newTestRequest(t, "POST", ts.URL, &body) 169 req2 := newTestRequest(t, "PATCH", ts.URL+"/"+id.String(), &body) 170 171 for _, req := range []*http.Request{req1, req2} { 172 t.Run(req.Method, func(t *testing.T) { 173 doTestRequest(t, req, http.StatusBadRequest, true) 174 }) 175 } 176 }) 177 } 178 179 func newTestServer(t *testing.T) (*httptest.Server, *mock.MockRemoteConnectionService) { 180 ctrlr := gomock.NewController(t) 181 svc := mock.NewMockRemoteConnectionService(ctrlr) 182 server := newRemoteConnectionHandler(zaptest.NewLogger(t), svc) 183 return httptest.NewServer(server), svc 184 } 185 186 func newTestRequest(t *testing.T, method, path string, body interface{}) *http.Request { 187 dat, err := json.Marshal(body) 188 require.NoError(t, err) 189 190 req, err := http.NewRequest(method, path, bytes.NewBuffer(dat)) 191 require.NoError(t, err) 192 193 req.Header.Add("Content-Type", "application/json") 194 195 return req 196 } 197 198 func doTestRequest(t *testing.T, req *http.Request, wantCode int, needJSON bool) *http.Response { 199 res, err := http.DefaultClient.Do(req) 200 require.NoError(t, err) 201 require.Equal(t, wantCode, res.StatusCode) 202 if needJSON { 203 require.Equal(t, "application/json; charset=utf-8", res.Header.Get("Content-Type")) 204 } 205 return res 206 }