Skip to content

Commit 38ce6b0

Browse files
varzacclaude
andcommitted
Add initial set of LAN integration tests for Hue
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent a8b3846 commit 38ce6b0

14 files changed

Lines changed: 3002 additions & 14 deletions

‎drivers/SmartThings/philips-hue/src/test/hue_test_helpers.lua‎

Lines changed: 1262 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
local test = require "integration_test"
2+
local lan_test_utils = require "integration_test.lan_test_utils"
3+
local mock_mdns = require "integration_test.mock_mdns"
4+
local mock_devices_api = require "integration_test.mock_devices_api"
5+
6+
local Discovery = require "disco"
7+
8+
local BRIDGE_IP = "192.168.1.20"
9+
local BRIDGE_MAC = "aa-bb-cc-dd-ee-ff"
10+
local BRIDGE_DNI = "AABBCCDDEEFF" -- BRIDGE_MAC with separators stripped, uppercased
11+
local BRIDGE_NAME = "Living Room"
12+
13+
test.add_test_env_setup_func(function(driver)
14+
-- disco is a module-level singleton that persists across tests within this file; a stale
15+
-- discovery_active=true (e.g. left over from an interrupted prior run) would make
16+
-- HueDiscovery.discover silently no-op.
17+
Discovery.discovery_active = false
18+
Discovery.api_keys = {}
19+
Discovery.disco_api_instances = {}
20+
end)
21+
22+
local function test_init()
23+
-- No bridge device is pre-registered here -- discovering and creating it is exactly what
24+
-- these tests exercise.
25+
end
26+
27+
test.set_test_init_function(test_init)
28+
29+
--- Queue an mDNS response for the bridge and start discovery via the same "discovery" channel
30+
--- message the real hub sends when a user initiates a scan (see
31+
--- st.handlers.discovery_message_handlers), rather than invoking Discovery.discover directly:
32+
--- that function makes real (mocked) blocking REST calls internally via cosock, which only
33+
--- works correctly inside a real cosock-managed thread -- exactly what the framework's own
34+
--- discovery dispatch spins up, and what the test coroutine itself is not.
35+
local function start_discovery()
36+
mock_mdns.__queue_response(Discovery.ServiceType, Discovery.Domain, {
37+
found = {
38+
mock_mdns.build_event({
39+
name = "Hue Bridge",
40+
service_type = Discovery.ServiceType,
41+
domain = Discovery.Domain,
42+
address = BRIDGE_IP,
43+
port = 443,
44+
}),
45+
},
46+
})
47+
test.socket.discovery:__queue_receive({ "start", {} })
48+
end
49+
50+
--- Discovery.discover loops "scan, sleep 1s" until told to stop; without this it would keep
51+
--- retrying (and re-sending requests) forever.
52+
local function stop_discovery()
53+
test.socket.discovery:__queue_receive({ "stop" })
54+
end
55+
56+
test.register_coroutine_test(
57+
"mDNS discovery finds a bridge and requests an API key, but does not create a device if the Link Button hasn't been pressed",
58+
function()
59+
local bridge_server = lan_test_utils.build_mock_server(BRIDGE_IP, 443)
60+
bridge_server:queue_http_response(200, {}, {
61+
mac = BRIDGE_MAC,
62+
swversion = "1968054000",
63+
modelid = "BSB002",
64+
name = BRIDGE_NAME,
65+
})
66+
bridge_server:queue_http_response(200, {}, {
67+
{ error = { type = 101, address = "/", description = "link button not pressed" } },
68+
})
69+
70+
start_discovery()
71+
test.wait_for_events()
72+
stop_discovery()
73+
test.wait_for_events()
74+
75+
bridge_server:assert_http_request_received("GET", "/api/config")
76+
bridge_server:assert_http_request_received(
77+
"POST",
78+
"/api",
79+
{ body = { devicetype = "smartthings_edge_driver#" .. BRIDGE_IP, generateclientkey = true } }
80+
)
81+
end
82+
)
83+
84+
test.register_coroutine_test(
85+
"mDNS discovery creates a bridge device once an API key is obtained",
86+
function()
87+
local bridge_server = lan_test_utils.build_mock_server(BRIDGE_IP, 443)
88+
bridge_server:queue_http_response(200, {}, {
89+
mac = BRIDGE_MAC,
90+
swversion = "1968054000",
91+
modelid = "BSB002",
92+
name = BRIDGE_NAME,
93+
})
94+
bridge_server:queue_http_response(200, {}, {
95+
{ success = { username = "new-bridge-api-key", client_key = "some-client-key" } },
96+
})
97+
98+
mock_devices_api.__expect_create_device({
99+
deviceNetworkId = BRIDGE_DNI,
100+
label = BRIDGE_NAME,
101+
profileReference = "hue-bridge",
102+
manufacturer = "Signify Netherlands B.V.",
103+
model = "BSB002",
104+
vendorProvidedLabel = BRIDGE_NAME,
105+
type = "LAN",
106+
})
107+
108+
start_discovery()
109+
test.wait_for_events()
110+
stop_discovery()
111+
test.wait_for_events()
112+
113+
bridge_server:assert_http_request_received("GET", "/api/config")
114+
bridge_server:assert_http_request_received(
115+
"POST",
116+
"/api",
117+
{ body = { devicetype = "smartthings_edge_driver#" .. BRIDGE_IP, generateclientkey = true } }
118+
)
119+
end
120+
)
121+
122+
test.run_registered_tests()

0 commit comments

Comments
 (0)