// 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(OAUTH2_CLIENT_ID, "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(OAUTH2_CLIENT_ID, "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) } }