github.com/iron-io/functions@v0.0.0-20180820112432-d59d7d1c40b2/api/server/apps_test.go (about) 1 // +build server 2 3 package server 4 5 import ( 6 "bytes" 7 "log" 8 "net/http" 9 "strings" 10 "testing" 11 12 "github.com/Sirupsen/logrus" 13 "github.com/gin-gonic/gin" 14 "github.com/iron-io/functions/api/datastore" 15 "github.com/iron-io/functions/api/models" 16 "github.com/iron-io/functions/api/mqs" 17 "github.com/iron-io/functions/api/runner/task" 18 ) 19 20 func setLogBuffer() *bytes.Buffer { 21 var buf bytes.Buffer 22 buf.WriteByte('\n') 23 logrus.SetOutput(&buf) 24 gin.DefaultErrorWriter = &buf 25 gin.DefaultWriter = &buf 26 log.SetOutput(&buf) 27 return &buf 28 } 29 30 func mockTasksConduit() chan task.Request { 31 tasks := make(chan task.Request) 32 go func() { 33 for range tasks { 34 } 35 }() 36 return tasks 37 } 38 39 func TestAppCreate(t *testing.T) { 40 buf := setLogBuffer() 41 tasks := mockTasksConduit() 42 defer close(tasks) 43 for i, test := range []struct { 44 mock models.Datastore 45 path string 46 body string 47 expectedCode int 48 expectedError error 49 }{ 50 // errors 51 {datastore.NewMock(), "/v1/apps", ``, http.StatusBadRequest, models.ErrInvalidJSON}, 52 {datastore.NewMock(), "/v1/apps", `{}`, http.StatusBadRequest, models.ErrAppsMissingNew}, 53 {datastore.NewMock(), "/v1/apps", `{ "name": "Test" }`, http.StatusBadRequest, models.ErrAppsMissingNew}, 54 {datastore.NewMock(), "/v1/apps", `{ "app": { "name": "" } }`, http.StatusInternalServerError, models.ErrAppsValidationMissingName}, 55 {datastore.NewMock(), "/v1/apps", `{ "app": { "name": "1234567890123456789012345678901" } }`, http.StatusInternalServerError, models.ErrAppsValidationTooLongName}, 56 {datastore.NewMock(), "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName}, 57 {datastore.NewMock(), "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName}, 58 59 // success 60 {datastore.NewMock(), "/v1/apps", `{ "app": { "name": "teste" } }`, http.StatusOK, nil}, 61 } { 62 rnr, cancel := testRunner(t) 63 srv := testServer(test.mock, &mqs.Mock{}, rnr, tasks) 64 router := srv.Router 65 66 body := bytes.NewBuffer([]byte(test.body)) 67 _, rec := routerRequest(t, router, "POST", test.path, body) 68 69 if rec.Code != test.expectedCode { 70 t.Log(buf.String()) 71 t.Errorf("Test %d: Expected status code to be %d but was %d", 72 i, test.expectedCode, rec.Code) 73 } 74 75 if test.expectedError != nil { 76 resp := getErrorResponse(t, rec) 77 78 if !strings.Contains(resp.Error.Message, test.expectedError.Error()) { 79 t.Log(buf.String()) 80 t.Errorf("Test %d: Expected error message to have `%s`", 81 i, test.expectedError.Error()) 82 } 83 } 84 cancel() 85 } 86 } 87 88 func TestAppDelete(t *testing.T) { 89 buf := setLogBuffer() 90 tasks := mockTasksConduit() 91 defer close(tasks) 92 93 for i, test := range []struct { 94 ds models.Datastore 95 path string 96 body string 97 expectedCode int 98 expectedError error 99 }{ 100 {datastore.NewMock(), "/v1/apps/myapp", "", http.StatusNotFound, nil}, 101 {datastore.NewMockInit( 102 []*models.App{{ 103 Name: "myapp", 104 }}, nil, 105 ), "/v1/apps/myapp", "", http.StatusOK, nil}, 106 } { 107 rnr, cancel := testRunner(t) 108 srv := testServer(test.ds, &mqs.Mock{}, rnr, tasks) 109 110 _, rec := routerRequest(t, srv.Router, "DELETE", test.path, nil) 111 112 if rec.Code != test.expectedCode { 113 t.Log(buf.String()) 114 t.Errorf("Test %d: Expected status code to be %d but was %d", 115 i, test.expectedCode, rec.Code) 116 } 117 118 if test.expectedError != nil { 119 resp := getErrorResponse(t, rec) 120 121 if !strings.Contains(resp.Error.Message, test.expectedError.Error()) { 122 t.Log(buf.String()) 123 t.Errorf("Test %d: Expected error message to have `%s`", 124 i, test.expectedError.Error()) 125 } 126 } 127 cancel() 128 } 129 } 130 131 func TestAppList(t *testing.T) { 132 buf := setLogBuffer() 133 tasks := mockTasksConduit() 134 defer close(tasks) 135 136 rnr, cancel := testRunner(t) 137 defer cancel() 138 srv := testServer(datastore.NewMock(), &mqs.Mock{}, rnr, tasks) 139 140 for i, test := range []struct { 141 path string 142 body string 143 expectedCode int 144 expectedError error 145 }{ 146 {"/v1/apps", "", http.StatusOK, nil}, 147 } { 148 _, rec := routerRequest(t, srv.Router, "GET", test.path, nil) 149 150 if rec.Code != test.expectedCode { 151 t.Log(buf.String()) 152 t.Errorf("Test %d: Expected status code to be %d but was %d", 153 i, test.expectedCode, rec.Code) 154 } 155 156 if test.expectedError != nil { 157 resp := getErrorResponse(t, rec) 158 159 if !strings.Contains(resp.Error.Message, test.expectedError.Error()) { 160 t.Log(buf.String()) 161 t.Errorf("Test %d: Expected error message to have `%s`", 162 i, test.expectedError.Error()) 163 } 164 } 165 } 166 } 167 168 func TestAppGet(t *testing.T) { 169 buf := setLogBuffer() 170 tasks := mockTasksConduit() 171 defer close(tasks) 172 173 rnr, cancel := testRunner(t) 174 defer cancel() 175 srv := testServer(datastore.NewMock(), &mqs.Mock{}, rnr, tasks) 176 177 for i, test := range []struct { 178 path string 179 body string 180 expectedCode int 181 expectedError error 182 }{ 183 {"/v1/apps/myapp", "", http.StatusNotFound, nil}, 184 } { 185 _, rec := routerRequest(t, srv.Router, "GET", test.path, nil) 186 187 if rec.Code != test.expectedCode { 188 t.Log(buf.String()) 189 t.Errorf("Test %d: Expected status code to be %d but was %d", 190 i, test.expectedCode, rec.Code) 191 } 192 193 if test.expectedError != nil { 194 resp := getErrorResponse(t, rec) 195 196 if !strings.Contains(resp.Error.Message, test.expectedError.Error()) { 197 t.Log(buf.String()) 198 t.Errorf("Test %d: Expected error message to have `%s`", 199 i, test.expectedError.Error()) 200 } 201 } 202 } 203 } 204 205 func TestAppUpdate(t *testing.T) { 206 buf := setLogBuffer() 207 tasks := mockTasksConduit() 208 defer close(tasks) 209 210 for i, test := range []struct { 211 mock models.Datastore 212 path string 213 body string 214 expectedCode int 215 expectedError error 216 }{ 217 // errors 218 {datastore.NewMock(), "/v1/apps/myapp", ``, http.StatusBadRequest, models.ErrInvalidJSON}, 219 220 // success 221 {datastore.NewMockInit( 222 []*models.App{{ 223 Name: "myapp", 224 }}, nil, 225 ), "/v1/apps/myapp", `{ "app": { "config": { "test": "1" } } }`, http.StatusOK, nil}, 226 227 // Addresses #380 228 {datastore.NewMockInit( 229 []*models.App{{ 230 Name: "myapp", 231 }}, nil, 232 ), "/v1/apps/myapp", `{ "app": { "name": "othername" } }`, http.StatusBadRequest, nil}, 233 } { 234 rnr, cancel := testRunner(t) 235 srv := testServer(test.mock, &mqs.Mock{}, rnr, tasks) 236 237 body := bytes.NewBuffer([]byte(test.body)) 238 _, rec := routerRequest(t, srv.Router, "PATCH", test.path, body) 239 240 if rec.Code != test.expectedCode { 241 t.Log(buf.String()) 242 t.Errorf("Test %d: Expected status code to be %d but was %d", 243 i, test.expectedCode, rec.Code) 244 } 245 246 if test.expectedError != nil { 247 resp := getErrorResponse(t, rec) 248 249 if !strings.Contains(resp.Error.Message, test.expectedError.Error()) { 250 t.Log(buf.String()) 251 t.Errorf("Test %d: Expected error message to have `%s`", 252 i, test.expectedError.Error()) 253 } 254 } 255 256 cancel() 257 } 258 }