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  }