gobot.io/x/gobot@v1.16.0/api/api_test.go (about) 1 package api 2 3 import ( 4 "bufio" 5 "bytes" 6 "encoding/json" 7 "fmt" 8 "log" 9 "net/http" 10 "net/http/httptest" 11 "testing" 12 "time" 13 14 "gobot.io/x/gobot" 15 "gobot.io/x/gobot/gobottest" 16 ) 17 18 func initTestAPI() *API { 19 log.SetOutput(NullReadWriteCloser{}) 20 g := gobot.NewMaster() 21 a := NewAPI(g) 22 a.start = func(m *API) {} 23 a.Start() 24 a.Debug() 25 26 g.AddRobot(newTestRobot("Robot1")) 27 g.AddRobot(newTestRobot("Robot2")) 28 g.AddRobot(newTestRobot("Robot3")) 29 g.AddCommand("TestFunction", func(params map[string]interface{}) interface{} { 30 message := params["message"].(string) 31 return fmt.Sprintf("hey %v", message) 32 }) 33 34 return a 35 } 36 37 func TestStartWithoutDefaults(t *testing.T) { 38 log.SetOutput(NullReadWriteCloser{}) 39 g := gobot.NewMaster() 40 a := NewAPI(g) 41 a.start = func(m *API) {} 42 43 a.Get("/", func(res http.ResponseWriter, req *http.Request) {}) 44 a.StartWithoutDefaults() 45 46 request, _ := http.NewRequest("GET", "/", nil) 47 response := httptest.NewRecorder() 48 a.ServeHTTP(response, request) 49 gobottest.Assert(t, response.Code, 200) 50 } 51 52 func TestRobeaux(t *testing.T) { 53 a := initTestAPI() 54 // html assets 55 request, _ := http.NewRequest("GET", "/index.html", nil) 56 response := httptest.NewRecorder() 57 a.ServeHTTP(response, request) 58 gobottest.Assert(t, response.Code, 200) 59 // js assets 60 request, _ = http.NewRequest("GET", "/js/script.js", nil) 61 response = httptest.NewRecorder() 62 a.ServeHTTP(response, request) 63 gobottest.Assert(t, response.Code, 200) 64 // css assets 65 request, _ = http.NewRequest("GET", "/css/application.css", nil) 66 response = httptest.NewRecorder() 67 a.ServeHTTP(response, request) 68 gobottest.Assert(t, response.Code, 200) 69 // unknown asset 70 request, _ = http.NewRequest("GET", "/js/fake/file.js", nil) 71 response = httptest.NewRecorder() 72 a.ServeHTTP(response, request) 73 gobottest.Assert(t, response.Code, 404) 74 } 75 76 func TestIndex(t *testing.T) { 77 a := initTestAPI() 78 request, _ := http.NewRequest("GET", "/", nil) 79 response := httptest.NewRecorder() 80 81 a.ServeHTTP(response, request) 82 83 gobottest.Assert(t, http.StatusMovedPermanently, response.Code) 84 gobottest.Assert(t, "/index.html", response.HeaderMap["Location"][0]) 85 } 86 87 func TestMcp(t *testing.T) { 88 a := initTestAPI() 89 request, _ := http.NewRequest("GET", "/api/", nil) 90 response := httptest.NewRecorder() 91 a.ServeHTTP(response, request) 92 93 var body map[string]interface{} 94 json.NewDecoder(response.Body).Decode(&body) 95 gobottest.Refute(t, body["MCP"].(map[string]interface{})["robots"], nil) 96 gobottest.Refute(t, body["MCP"].(map[string]interface{})["commands"], nil) 97 } 98 99 func TestMcpCommands(t *testing.T) { 100 a := initTestAPI() 101 request, _ := http.NewRequest("GET", "/api/commands", nil) 102 response := httptest.NewRecorder() 103 a.ServeHTTP(response, request) 104 105 var body map[string]interface{} 106 json.NewDecoder(response.Body).Decode(&body) 107 gobottest.Assert(t, body["commands"], []interface{}{"TestFunction"}) 108 } 109 110 func TestExecuteMcpCommand(t *testing.T) { 111 var body interface{} 112 a := initTestAPI() 113 114 // known command 115 request, _ := http.NewRequest("GET", 116 "/api/commands/TestFunction", 117 bytes.NewBufferString(`{"message":"Beep Boop"}`), 118 ) 119 request.Header.Add("Content-Type", "application/json") 120 response := httptest.NewRecorder() 121 a.ServeHTTP(response, request) 122 123 json.NewDecoder(response.Body).Decode(&body) 124 gobottest.Assert(t, body.(map[string]interface{})["result"], "hey Beep Boop") 125 126 // unknown command 127 request, _ = http.NewRequest("GET", 128 "/api/commands/TestFuntion1", 129 bytes.NewBufferString(`{"message":"Beep Boop"}`), 130 ) 131 request.Header.Add("Content-Type", "application/json") 132 response = httptest.NewRecorder() 133 a.ServeHTTP(response, request) 134 135 json.NewDecoder(response.Body).Decode(&body) 136 gobottest.Assert(t, body.(map[string]interface{})["error"], "Unknown Command") 137 } 138 139 func TestRobots(t *testing.T) { 140 a := initTestAPI() 141 request, _ := http.NewRequest("GET", "/api/robots", nil) 142 response := httptest.NewRecorder() 143 a.ServeHTTP(response, request) 144 145 var body map[string]interface{} 146 json.NewDecoder(response.Body).Decode(&body) 147 gobottest.Assert(t, len(body["robots"].([]interface{})), 3) 148 } 149 150 func TestRobot(t *testing.T) { 151 a := initTestAPI() 152 153 // known robot 154 request, _ := http.NewRequest("GET", "/api/robots/Robot1", nil) 155 response := httptest.NewRecorder() 156 a.ServeHTTP(response, request) 157 158 var body map[string]interface{} 159 json.NewDecoder(response.Body).Decode(&body) 160 gobottest.Assert(t, body["robot"].(map[string]interface{})["name"].(string), "Robot1") 161 162 // unknown robot 163 request, _ = http.NewRequest("GET", "/api/robots/UnknownRobot1", nil) 164 a.ServeHTTP(response, request) 165 166 json.NewDecoder(response.Body).Decode(&body) 167 gobottest.Assert(t, body["error"], "No Robot found with the name UnknownRobot1") 168 } 169 170 func TestRobotDevices(t *testing.T) { 171 a := initTestAPI() 172 173 // known robot 174 request, _ := http.NewRequest("GET", "/api/robots/Robot1/devices", nil) 175 response := httptest.NewRecorder() 176 a.ServeHTTP(response, request) 177 178 var body map[string]interface{} 179 json.NewDecoder(response.Body).Decode(&body) 180 gobottest.Assert(t, len(body["devices"].([]interface{})), 3) 181 182 // unknown robot 183 request, _ = http.NewRequest("GET", "/api/robots/UnknownRobot1/devices", nil) 184 a.ServeHTTP(response, request) 185 186 json.NewDecoder(response.Body).Decode(&body) 187 gobottest.Assert(t, body["error"], "No Robot found with the name UnknownRobot1") 188 } 189 190 func TestRobotCommands(t *testing.T) { 191 a := initTestAPI() 192 193 // known robot 194 request, _ := http.NewRequest("GET", "/api/robots/Robot1/commands", nil) 195 response := httptest.NewRecorder() 196 a.ServeHTTP(response, request) 197 198 var body map[string]interface{} 199 json.NewDecoder(response.Body).Decode(&body) 200 gobottest.Assert(t, body["commands"], []interface{}{"robotTestFunction"}) 201 202 // unknown robot 203 request, _ = http.NewRequest("GET", "/api/robots/UnknownRobot1/commands", nil) 204 a.ServeHTTP(response, request) 205 206 json.NewDecoder(response.Body).Decode(&body) 207 gobottest.Assert(t, body["error"], "No Robot found with the name UnknownRobot1") 208 } 209 210 func TestExecuteRobotCommand(t *testing.T) { 211 var body interface{} 212 a := initTestAPI() 213 // known command 214 request, _ := http.NewRequest("GET", 215 "/api/robots/Robot1/commands/robotTestFunction", 216 bytes.NewBufferString(`{"message":"Beep Boop", "robot":"Robot1"}`), 217 ) 218 request.Header.Add("Content-Type", "application/json") 219 response := httptest.NewRecorder() 220 a.ServeHTTP(response, request) 221 222 json.NewDecoder(response.Body).Decode(&body) 223 gobottest.Assert(t, body.(map[string]interface{})["result"], "hey Robot1, Beep Boop") 224 225 // unknown command 226 request, _ = http.NewRequest("GET", 227 "/api/robots/Robot1/commands/robotTestFuntion1", 228 bytes.NewBufferString(`{"message":"Beep Boop"}`), 229 ) 230 request.Header.Add("Content-Type", "application/json") 231 response = httptest.NewRecorder() 232 a.ServeHTTP(response, request) 233 234 json.NewDecoder(response.Body).Decode(&body) 235 gobottest.Assert(t, body.(map[string]interface{})["error"], "Unknown Command") 236 237 // uknown robot 238 request, _ = http.NewRequest("GET", 239 "/api/robots/UnknownRobot1/commands/robotTestFuntion1", 240 bytes.NewBufferString(`{"message":"Beep Boop"}`), 241 ) 242 request.Header.Add("Content-Type", "application/json") 243 a.ServeHTTP(response, request) 244 245 json.NewDecoder(response.Body).Decode(&body) 246 gobottest.Assert(t, body.(map[string]interface{})["error"], "No Robot found with the name UnknownRobot1") 247 } 248 249 func TestRobotDevice(t *testing.T) { 250 a := initTestAPI() 251 252 // known device 253 request, _ := http.NewRequest("GET", 254 "/api/robots/Robot1/devices/Device1", 255 nil, 256 ) 257 response := httptest.NewRecorder() 258 a.ServeHTTP(response, request) 259 260 var body map[string]interface{} 261 json.NewDecoder(response.Body).Decode(&body) 262 gobottest.Assert(t, body["device"].(map[string]interface{})["name"].(string), "Device1") 263 264 // unknown device 265 request, _ = http.NewRequest("GET", 266 "/api/robots/Robot1/devices/UnknownDevice1", nil) 267 a.ServeHTTP(response, request) 268 269 json.NewDecoder(response.Body).Decode(&body) 270 gobottest.Assert(t, body["error"], "No Device found with the name UnknownDevice1") 271 } 272 273 func TestRobotDeviceCommands(t *testing.T) { 274 a := initTestAPI() 275 276 // known device 277 request, _ := http.NewRequest("GET", 278 "/api/robots/Robot1/devices/Device1/commands", 279 nil, 280 ) 281 response := httptest.NewRecorder() 282 a.ServeHTTP(response, request) 283 284 var body map[string]interface{} 285 json.NewDecoder(response.Body).Decode(&body) 286 gobottest.Assert(t, len(body["commands"].([]interface{})), 2) 287 288 // unknown device 289 request, _ = http.NewRequest("GET", 290 "/api/robots/Robot1/devices/UnknownDevice1/commands", 291 nil, 292 ) 293 a.ServeHTTP(response, request) 294 json.NewDecoder(response.Body).Decode(&body) 295 gobottest.Assert(t, body["error"], "No Device found with the name UnknownDevice1") 296 } 297 298 func TestExecuteRobotDeviceCommand(t *testing.T) { 299 var body interface{} 300 a := initTestAPI() 301 302 // known command 303 request, _ := http.NewRequest("GET", 304 "/api/robots/Robot1/devices/Device1/commands/TestDriverCommand", 305 bytes.NewBufferString(`{"name":"human"}`), 306 ) 307 request.Header.Add("Content-Type", "application/json") 308 response := httptest.NewRecorder() 309 a.ServeHTTP(response, request) 310 311 json.NewDecoder(response.Body).Decode(&body) 312 gobottest.Assert(t, body.(map[string]interface{})["result"].(string), "hello human") 313 314 // unknown command 315 request, _ = http.NewRequest("GET", 316 "/api/robots/Robot1/devices/Device1/commands/DriverCommand1", 317 bytes.NewBufferString(`{"name":"human"}`), 318 ) 319 request.Header.Add("Content-Type", "application/json") 320 response = httptest.NewRecorder() 321 a.ServeHTTP(response, request) 322 323 json.NewDecoder(response.Body).Decode(&body) 324 gobottest.Assert(t, body.(map[string]interface{})["error"], "Unknown Command") 325 326 // unknown device 327 request, _ = http.NewRequest("GET", 328 "/api/robots/Robot1/devices/UnknownDevice1/commands/DriverCommand1", 329 bytes.NewBufferString(`{"name":"human"}`), 330 ) 331 request.Header.Add("Content-Type", "application/json") 332 a.ServeHTTP(response, request) 333 334 json.NewDecoder(response.Body).Decode(&body) 335 gobottest.Assert(t, body.(map[string]interface{})["error"], "No Device found with the name UnknownDevice1") 336 337 } 338 339 func TestRobotConnections(t *testing.T) { 340 a := initTestAPI() 341 342 // known robot 343 request, _ := http.NewRequest("GET", "/api/robots/Robot1/connections", nil) 344 response := httptest.NewRecorder() 345 a.ServeHTTP(response, request) 346 347 var body map[string]interface{} 348 json.NewDecoder(response.Body).Decode(&body) 349 gobottest.Assert(t, len(body["connections"].([]interface{})), 3) 350 351 // unknown robot 352 request, _ = http.NewRequest("GET", "/api/robots/UnknownRobot1/connections", nil) 353 a.ServeHTTP(response, request) 354 355 json.NewDecoder(response.Body).Decode(&body) 356 gobottest.Assert(t, body["error"], "No Robot found with the name UnknownRobot1") 357 } 358 359 func TestRobotConnection(t *testing.T) { 360 a := initTestAPI() 361 362 // known connection 363 request, _ := http.NewRequest("GET", 364 "/api/robots/Robot1/connections/Connection1", 365 nil, 366 ) 367 response := httptest.NewRecorder() 368 a.ServeHTTP(response, request) 369 370 var body map[string]interface{} 371 json.NewDecoder(response.Body).Decode(&body) 372 gobottest.Assert(t, body["connection"].(map[string]interface{})["name"].(string), "Connection1") 373 374 // unknown connection 375 request, _ = http.NewRequest("GET", 376 "/api/robots/Robot1/connections/UnknownConnection1", 377 nil, 378 ) 379 a.ServeHTTP(response, request) 380 json.NewDecoder(response.Body).Decode(&body) 381 gobottest.Assert(t, body["error"], "No Connection found with the name UnknownConnection1") 382 } 383 384 func TestRobotDeviceEvent(t *testing.T) { 385 a := initTestAPI() 386 server := httptest.NewServer(a) 387 defer server.Close() 388 389 eventsURL := "/api/robots/Robot1/devices/Device1/events/" 390 391 // known event 392 respc := make(chan *http.Response, 1) 393 go func() { 394 resp, _ := http.Get(server.URL + eventsURL + "TestEvent") 395 respc <- resp 396 }() 397 398 event := a.master.Robot("Robot1"). 399 Device("Device1").(gobot.Eventer). 400 Event("TestEvent") 401 402 go func() { 403 time.Sleep(time.Millisecond * 5) 404 a.master.Robot("Robot1"). 405 Device("Device1").(gobot.Eventer).Publish(event, "event-data") 406 }() 407 408 done := false 409 410 for !done { 411 select { 412 case resp := <-respc: 413 reader := bufio.NewReader(resp.Body) 414 data, _ := reader.ReadString('\n') 415 gobottest.Assert(t, data, "data: \"event-data\"\n") 416 done = true 417 case <-time.After(100 * time.Millisecond): 418 t.Error("Not receiving data") 419 done = true 420 } 421 } 422 423 server.CloseClientConnections() 424 425 // unknown event 426 response, _ := http.Get(server.URL + eventsURL + "UnknownEvent") 427 428 var body map[string]interface{} 429 json.NewDecoder(response.Body).Decode(&body) 430 gobottest.Assert(t, body["error"], "No Event found with the name UnknownEvent") 431 } 432 433 func TestAPIRouter(t *testing.T) { 434 a := initTestAPI() 435 436 a.Head("/test", func(res http.ResponseWriter, req *http.Request) {}) 437 request, _ := http.NewRequest("HEAD", "/test", nil) 438 response := httptest.NewRecorder() 439 a.ServeHTTP(response, request) 440 gobottest.Assert(t, response.Code, 200) 441 442 a.Get("/test", func(res http.ResponseWriter, req *http.Request) {}) 443 request, _ = http.NewRequest("GET", "/test", nil) 444 response = httptest.NewRecorder() 445 a.ServeHTTP(response, request) 446 gobottest.Assert(t, response.Code, 200) 447 448 a.Post("/test", func(res http.ResponseWriter, req *http.Request) {}) 449 request, _ = http.NewRequest("POST", "/test", nil) 450 response = httptest.NewRecorder() 451 a.ServeHTTP(response, request) 452 gobottest.Assert(t, response.Code, 200) 453 454 a.Put("/test", func(res http.ResponseWriter, req *http.Request) {}) 455 request, _ = http.NewRequest("PUT", "/test", nil) 456 response = httptest.NewRecorder() 457 a.ServeHTTP(response, request) 458 gobottest.Assert(t, response.Code, 200) 459 460 a.Delete("/test", func(res http.ResponseWriter, req *http.Request) {}) 461 request, _ = http.NewRequest("DELETE", "/test", nil) 462 response = httptest.NewRecorder() 463 a.ServeHTTP(response, request) 464 gobottest.Assert(t, response.Code, 200) 465 466 a.Options("/test", func(res http.ResponseWriter, req *http.Request) {}) 467 request, _ = http.NewRequest("OPTIONS", "/test", nil) 468 response = httptest.NewRecorder() 469 a.ServeHTTP(response, request) 470 gobottest.Assert(t, response.Code, 200) 471 }