203 lines
5.6 KiB
Go
203 lines
5.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/DATA-DOG/go-sqlmock"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// helper to build gin engine with given handler without auth for focused handler tests
|
|
func newTestRouter(h *Handler, register func(*gin.Engine)) *gin.Engine {
|
|
gin.SetMode(gin.TestMode)
|
|
r := gin.New()
|
|
register(r)
|
|
return r
|
|
}
|
|
|
|
// helper to set up sqlmock-backed handler
|
|
func newMockHandler(t *testing.T) (*Handler, sqlmock.Sqlmock, func()) {
|
|
t.Helper()
|
|
db, mock, err := sqlmock.New()
|
|
if err != nil {
|
|
t.Fatalf("sqlmock: %v", err)
|
|
}
|
|
h := &Handler{DB: db, JWTSecret: "secret"}
|
|
cleanup := func() { db.Close() }
|
|
return h, mock, cleanup
|
|
}
|
|
|
|
func TestCreateSensor(t *testing.T) {
|
|
h, mock, cleanup := newMockHandler(t)
|
|
defer cleanup()
|
|
|
|
mock.ExpectExec("INSERT INTO sensors").
|
|
WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), "temp", "bool", 1).
|
|
WillReturnResult(sqlmock.NewResult(0, 1))
|
|
|
|
r := newTestRouter(h, func(r *gin.Engine) {
|
|
r.POST("/sensors", h.CreateSensor)
|
|
})
|
|
|
|
body := map[string]interface{}{
|
|
"device_id": "11111111-1111-1111-1111-111111111111",
|
|
"name": "temp",
|
|
"type": "bool",
|
|
"data_type_id": 1,
|
|
}
|
|
buf, _ := json.Marshal(body)
|
|
req := httptest.NewRequest(http.MethodPost, "/sensors", bytes.NewReader(buf))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusCreated {
|
|
t.Fatalf("expected 201 got %d, body=%s", w.Code, w.Body.String())
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGetSensors(t *testing.T) {
|
|
h, mock, cleanup := newMockHandler(t)
|
|
defer cleanup()
|
|
|
|
rows := sqlmock.NewRows([]string{"id", "device_id", "name", "type", "data_type_id", "created_at", "updated_at"}).
|
|
AddRow("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "temp", "bool", 1, time.Now(), time.Now())
|
|
|
|
mock.ExpectQuery(`SELECT BIN_TO_UUID\(id\)`).WillReturnRows(rows)
|
|
|
|
r := newTestRouter(h, func(r *gin.Engine) {
|
|
r.GET("/sensors", h.GetSensors)
|
|
})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/sensors", nil)
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("expected 200 got %d, body=%s", w.Code, w.Body.String())
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCreateActor(t *testing.T) {
|
|
h, mock, cleanup := newMockHandler(t)
|
|
defer cleanup()
|
|
|
|
mock.ExpectExec("INSERT INTO actors").
|
|
WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), "led", "switch", 1).
|
|
WillReturnResult(sqlmock.NewResult(0, 1))
|
|
|
|
r := newTestRouter(h, func(r *gin.Engine) {
|
|
r.POST("/actors", h.CreateActor)
|
|
})
|
|
|
|
body := map[string]interface{}{
|
|
"device_id": "11111111-1111-1111-1111-111111111111",
|
|
"name": "led",
|
|
"type": "switch",
|
|
"data_type_id": 1,
|
|
}
|
|
buf, _ := json.Marshal(body)
|
|
req := httptest.NewRequest(http.MethodPost, "/actors", bytes.NewReader(buf))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusCreated {
|
|
t.Fatalf("expected 201 got %d, body=%s", w.Code, w.Body.String())
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGetActors(t *testing.T) {
|
|
h, mock, cleanup := newMockHandler(t)
|
|
defer cleanup()
|
|
|
|
rows := sqlmock.NewRows([]string{"id", "device_id", "name", "type", "data_type_id", "created_at", "updated_at"}).
|
|
AddRow("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "led", "switch", 1, time.Now(), time.Now())
|
|
|
|
mock.ExpectQuery(`SELECT BIN_TO_UUID\(id\).*FROM actors`).WillReturnRows(rows)
|
|
|
|
r := newTestRouter(h, func(r *gin.Engine) {
|
|
r.GET("/actors", h.GetActors)
|
|
})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/actors", nil)
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("expected 200 got %d, body=%s", w.Code, w.Body.String())
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCreateSensorReading(t *testing.T) {
|
|
h, mock, cleanup := newMockHandler(t)
|
|
defer cleanup()
|
|
|
|
mock.ExpectExec("INSERT INTO sensor_readings").
|
|
WithArgs(sqlmock.AnyArg(), 42.0, sqlmock.AnyArg()).
|
|
WillReturnResult(sqlmock.NewResult(10, 1))
|
|
|
|
r := newTestRouter(h, func(r *gin.Engine) {
|
|
r.POST("/sensor-readings", h.CreateSensorReading)
|
|
})
|
|
|
|
body := map[string]interface{}{
|
|
"sensor_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
|
|
"value": 42.0,
|
|
}
|
|
buf, _ := json.Marshal(body)
|
|
req := httptest.NewRequest(http.MethodPost, "/sensor-readings", bytes.NewReader(buf))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusCreated {
|
|
t.Fatalf("expected 201 got %d, body=%s", w.Code, w.Body.String())
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGetSensorReadings(t *testing.T) {
|
|
h, mock, cleanup := newMockHandler(t)
|
|
defer cleanup()
|
|
|
|
rows := sqlmock.NewRows([]string{"id", "sensor_id", "value", "value_at"}).
|
|
AddRow(int64(1), "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", 1.23, time.Now())
|
|
|
|
mock.ExpectQuery(`SELECT id, BIN_TO_UUID\(sensor_id\)`).WillReturnRows(rows)
|
|
|
|
r := newTestRouter(h, func(r *gin.Engine) {
|
|
r.GET("/sensor-readings", h.GetSensorReadings)
|
|
})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/sensor-readings", nil)
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("expected 200 got %d, body=%s", w.Code, w.Body.String())
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("expectations: %v", err)
|
|
}
|
|
}
|