evcc-io/util/service/modbus_test.go

147 lines
4.4 KiB
Go

package service
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/spf13/cast"
"github.com/stretchr/testify/assert"
)
func TestGetParams_DirectURI(t *testing.T) {
// Verify that direct URI parameter works
req := httptest.NewRequest("GET", "/read?uri=192.168.1.1:502&address=100&type=holding&encoding=uint16", nil)
w := httptest.NewRecorder()
modbusRead(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.NotEmpty(t, w.Body.String())
}
func TestGetParams_WithScale(t *testing.T) {
// Test with scale parameter
req := httptest.NewRequest("GET", "/read?uri=192.168.1.1:502&id=1&address=1068&type=holding&encoding=float32s&scale=0.001", nil)
w := httptest.NewRecorder()
modbusRead(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.NotEmpty(t, w.Body.String())
}
func TestGetParams_WithResultType(t *testing.T) {
// Test with resulttype parameter
req := httptest.NewRequest("GET", "/read?uri=192.168.1.1:502&id=1&address=1068&type=holding&encoding=float32s&resulttype=int", nil)
w := httptest.NewRecorder()
modbusRead(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.NotEmpty(t, w.Body.String())
}
func TestGetParams_CompleteRequest(t *testing.T) {
// Test complete request with all parameters
req := httptest.NewRequest("GET", "/read?uri=192.168.1.1:502&id=1&address=1068&type=holding&encoding=float32s&scale=0.001&resulttype=int", nil)
w := httptest.NewRecorder()
modbusRead(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.NotEmpty(t, w.Body.String())
}
func TestGetParams_RS485Serial(t *testing.T) {
// Test RS485 serial connection with device parameter
req := httptest.NewRequest("GET", "/read?device=/dev/ttyUSB0&baudrate=9600&comset=8N1&id=1&address=1068&type=holding&encoding=float32s&scale=0.001", nil)
w := httptest.NewRecorder()
modbusRead(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.NotEmpty(t, w.Body.String())
}
func TestGetParams_RS485Serial_WithResultType(t *testing.T) {
// Test RS485 serial with resulttype parameter
req := httptest.NewRequest("GET", "/read?device=/dev/ttyUSB0&baudrate=19200&comset=8N1&id=1&address=100&type=holding&encoding=uint16&resulttype=int", nil)
w := httptest.NewRecorder()
modbusRead(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.NotEmpty(t, w.Body.String())
}
func TestGetParams_MissingConnection(t *testing.T) {
// Test that either uri or device is required
req := httptest.NewRequest("GET", "/read?id=1&address=100&type=holding&encoding=uint16", nil)
w := httptest.NewRecorder()
modbusRead(w, req)
// Should return 400 error
assert.Equal(t, http.StatusBadRequest, w.Code)
assert.Contains(t, w.Body.String(), "uri or device")
}
func TestGetParams_MissingAddress(t *testing.T) {
// Test that address parameter is required
req := httptest.NewRequest("GET", "/read?uri=192.168.1.1:502&type=holding&encoding=uint16", nil)
w := httptest.NewRecorder()
modbusRead(w, req)
assert.Equal(t, http.StatusBadRequest, w.Code)
assert.Contains(t, w.Body.String(), "address")
}
func TestGetParams_AddressZero(t *testing.T) {
// Test that address=0 is valid (not treated as missing)
req := httptest.NewRequest("GET", "/read?uri=192.168.1.1:502&address=0&type=holding&encoding=uint16", nil)
w := httptest.NewRecorder()
modbusRead(w, req)
// Should NOT return 400 - address 0 is valid, will fail at connection
assert.Equal(t, http.StatusInternalServerError, w.Code)
}
func TestApplyCast(t *testing.T) {
tests := []struct {
name string
value any
castType string
expected any
}{
// Int conversions
{"float to int", 42.7, "int", int64(42)},
{"string to int", "42", "int", int64(42)},
{"int to int", 42, "int", int64(42)},
{"negative float to int", -42.9, "int", int64(-42)},
// Float conversions
{"int to float", 42, "float", float64(42.0)},
{"string to float", "42.7", "float", float64(42.7)},
{"float to float", 42.7, "float", float64(42.7)},
// String conversions
{"int to string", 42, "string", "42"},
{"float to string", 42.7, "string", "42.7"},
{"string to string", "hello", "string", "hello"},
// Unknown/empty type (should return original)
{"unknown type", 42, "unknown", 42},
{"empty type", 42, "", 42},
{"nil value", nil, "int", int64(0)},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := toString(tt.value, tt.castType)
assert.Equal(t, cast.ToString(tt.expected), result)
})
}
}