Files
xiaomihome/miot/miot_cloud_test.go
T
4566704 3a44cb9e6a feat: 初始化小米 IoT (MIoT) 智能家居 Go 库
- 实现 MIoT 客户端核心功能(MQTT 连接、设备管理、属性读写)
- 支持云端 API 调用与局域网设备发现(mDNS)
- 集成国际化(i18n)多语言支持
- 添加 MIoT 设备规约解析器(spec_parser)
- 包含单元测试与使用示例
2026-06-28 22:05:49 +08:00

191 lines
4.7 KiB
Go

// Package miot provides white-box tests for miot_cloud.go cloud API client.
package miot
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
)
func TestToFloat64(t *testing.T) {
tests := []struct {
input interface{}
want float64
}{
{float64(3.14), 3.14},
{int(5), 5.0},
{int64(10), 10.0},
{"123", 123.0},
{nil, 0.0},
{true, 0.0},
}
for _, tt := range tests {
got := toFloat64(tt.input)
if got != tt.want {
t.Errorf("toFloat64(%v) = %f, want %f", tt.input, got, tt.want)
}
}
}
func TestToSlice(t *testing.T) {
if s := toSlice(nil); s != nil {
t.Errorf("toSlice(nil) = %v, want nil", s)
}
if s := toSlice([]interface{}{"a", "b"}); len(s) != 2 {
t.Errorf("toSlice len = %d, want 2", len(s))
}
if s := toSlice("not_a_slice"); s != nil {
t.Errorf("toSlice(string) = %v, want nil", s)
}
}
func TestToStringSlice(t *testing.T) {
s := toStringSlice([]string{"a", "b", "c"})
if len(s) != 3 || s[0] != "a" {
t.Errorf("toStringSlice([]string) = %v", s)
}
s = toStringSlice([]interface{}{"x", "y"})
if len(s) != 2 || s[1] != "y" {
t.Errorf("toStringSlice([]interface{}) = %v", s)
}
s = toStringSlice([]interface{}{"str", 42})
if s[1] != "42" {
t.Errorf("toStringSlice with int = %v, want '42'", s)
}
s = toStringSlice(nil)
if s != nil {
t.Errorf("toStringSlice(nil) should be nil, got %v", s)
}
}
func TestIsUnsupportedModel(t *testing.T) {
if !isUnsupportedModel("chuangmi.ir.v2") {
t.Error("chuangmi.ir.v2 should be unsupported")
}
if isUnsupportedModel("lumi.plug.v1") {
t.Error("lumi.plug.v1 should be supported")
}
if isUnsupportedModel("") {
t.Error("empty string should be supported")
}
}
func TestContainsString(t *testing.T) {
slice := []string{"a", "b", "c"}
if !containsString(slice, "b") {
t.Error("should contain 'b'")
}
if containsString(slice, "z") {
t.Error("should not contain 'z'")
}
if containsString(nil, "a") {
t.Error("nil slice should not contain anything")
}
}
func TestNewMIoTHttpClient_Basic(t *testing.T) {
client, err := NewMIoTHttpClient("cn", "client_id_123", "access_token_abc")
if err != nil {
t.Fatalf("NewMIoTHttpClient failed: %v", err)
}
if client == nil {
t.Fatal("client should not be nil")
}
client.Close()
}
func TestNewMIoTHttpClient_NonCN(t *testing.T) {
client, err := NewMIoTHttpClient("us", "id", "token")
if err != nil {
t.Fatalf("NewMIoTHttpClient for us failed: %v", err)
}
client.Close()
}
func TestNewMIoTOauthClient_Basic(t *testing.T) {
oa := NewMIoTOauthClient("2882303761520251711", "http://localhost/callback", "cn", "test-uuid")
if oa == nil {
t.Fatal("NewMIoTOauthClient returned nil")
}
s := oa.State()
if s == "" {
t.Error("State should not be empty")
}
oa.Close()
}
func TestGenAuthURL(t *testing.T) {
oa := NewMIoTOauthClient("2882303761520251711", "http://localhost/callback", "cn", "test-uuid")
defer oa.Close()
url := oa.GenAuthURL("", "", nil, false)
if url == "" {
t.Error("GenAuthURL returned empty string")
}
url2 := oa.GenAuthURL("http://custom/callback", "mystate", []string{"scope1", "scope2"}, true)
if url2 == "" {
t.Error("GenAuthURL with params returned empty string")
}
}
func TestUpdateHTTPHeader_CN(t *testing.T) {
client, err := NewMIoTHttpClient("cn", "id1", "tok1")
if err != nil {
t.Fatal(err)
}
defer client.Close()
client.UpdateHTTPHeader("cn", "new_id", "new_token")
}
func TestUpdateHTTPHeader_NonCN(t *testing.T) {
client, err := NewMIoTHttpClient("us", "id1", "tok1")
if err != nil {
t.Fatal(err)
}
defer client.Close()
client.UpdateHTTPHeader("de", "id2", "tok2")
}
func TestMihomeAPIGet_Success(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
t.Errorf("expected GET, got %s", r.Method)
}
resp := map[string]interface{}{"code": float64(0), "message": "ok", "result": map[string]interface{}{"data": "test"}}
json.NewEncoder(w).Encode(resp)
}))
defer server.Close()
_ = server
}
func TestPropParam_Struct(t *testing.T) {
p := PropParam{DID: "did1", Siid: 2, Piid: 1, Value: "on"}
if p.DID != "did1" || p.Siid != 2 || p.Piid != 1 {
t.Error("PropParam fields wrong")
}
}
func TestPropResult_Struct(t *testing.T) {
r := PropResult{DID: "did1", Siid: 2, Piid: 1, Code: 0, Value: "ok"}
if r.Code != 0 {
t.Errorf("PropResult Code = %d, want 0", r.Code)
}
}
func TestMIoTHttpClient_Close(t *testing.T) {
client, err := NewMIoTHttpClient("cn", "id", "token")
if err != nil {
t.Fatal(err)
}
client.Close()
client.Close()
}
func TestTokenExpiresTSRatio(t *testing.T) {
if TokenExpiresTSRatio <= 0 || TokenExpiresTSRatio >= 1.0 {
t.Errorf("TokenExpiresTSRatio = %f, should be between 0 and 1", TokenExpiresTSRatio)
}
}