ESPSomfy-RTS/test/test_loopqueue/test_loopqueue.cpp
cjkas 2a954aa158 feat!: remove the old API, ports 8081 and 8080 (step 4a)
Step 4a of docs/SECURITY_PLAN.md. Port 80 keeps the eleven HTTP routes of
ADR 0006 and the socket at /ws; everything else moved to protocol 2.

- Port 8081 (ApiRoutes) and the socket on 8080 (SocketEmitter) are gone.
  Protocol 2 owns its frame buffer and loop-task check.
- Port 80 drops every route the old web UI called: reads, edits,
  settings, scans, reboot, /shades.cfg, /discovery. HttpRoutes.cpp holds
  what stays.
- ModelSnapshot, SnapshotSlots and the read documents are gone. The item
  snapshot types stay, as ItemSnapshot, for events, MQTT and the command
  replies.
- Model edits reply only to their protocol 2 op: requestResult goes.
- The settings' toJSON writers, used only by the settings routes, go.
- The _espsomfy_rts._tcp mDNS record moves to port 80, with path=/ws.
- The memory event reports the loop-rate window it closes.
- A deleted room no longer re-publishes its retained MQTT topics.
- e2e: the heap check reads the sync's status; the sync is checked on
  its own instead of against /controller.
- README gets an API and ports section.

BREAKING CHANGE: ports 8081 and 8080 and the old HTTP routes are gone.
Home Assistant needs integration 3.0.0 or newer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 21:49:38 +01:00

82 lines
3.2 KiB
C++

#include <unity.h>
#include "LoopQueue.h"
static loop_item_t request(shade_request_type_t type) {
loop_item_t item;
item.request.type = type;
return item;
}
static loop_item_t item(loop_item_type_t type) {
loop_item_t item;
item.type = type;
return item;
}
static const shade_request_type_t RADIO_REQUESTS[] = {
shade_request_type_t::shade_command, shade_request_type_t::group_command, shade_request_type_t::tilt_command,
shade_request_type_t::shade_repeat, shade_request_type_t::group_repeat, shade_request_type_t::shade_sensor,
shade_request_type_t::group_sensor, shade_request_type_t::set_favorite, shade_request_type_t::unpair
};
static const shade_request_type_t OFF_RADIO_REQUESTS[] = {
shade_request_type_t::set_positions, shade_request_type_t::set_rolling_code
};
static const loop_item_type_t OTHER_ITEMS[] = {
loop_item_type_t::restore_shades, loop_item_type_t::model_edit, loop_item_type_t::proto_read,
// A frequency scan's end among them, so it never waits for the radio.
loop_item_type_t::proto_device
};
void setUp() {}
void tearDown() {}
static void test_only_position_and_rolling_code_requests_stay_off_the_radio() {
int offRadio = 0;
for(uint8_t t = 0; t <= static_cast<uint8_t>(shade_request_type_t::set_rolling_code); t++) {
if(!shadeRequestUsesRadio(static_cast<shade_request_type_t>(t))) offRadio++;
}
TEST_ASSERT_EQUAL_INT(2, offRadio);
for(shade_request_type_t t : OFF_RADIO_REQUESTS) TEST_ASSERT_FALSE(loopItemUsesRadio(request(t)));
for(loop_item_type_t t : OTHER_ITEMS) TEST_ASSERT_FALSE(loopItemUsesRadio(item(t)));
}
static void test_off_radio_items_are_never_held() {
// Nothing goes on air, so a full or suspended radio doesn't matter.
for(shade_request_type_t t : OFF_RADIO_REQUESTS) {
TEST_ASSERT_FALSE(holdLoopItem(request(t), false, false));
TEST_ASSERT_FALSE(holdLoopItem(request(t), true, false));
}
for(loop_item_type_t t : OTHER_ITEMS) {
TEST_ASSERT_FALSE(holdLoopItem(item(t), false, false));
TEST_ASSERT_FALSE(holdLoopItem(item(t), true, false));
}
}
static void test_radio_request_waits_for_room() {
for(shade_request_type_t t : RADIO_REQUESTS) {
TEST_ASSERT_TRUE(holdLoopItem(request(t), false, false));
TEST_ASSERT_FALSE(holdLoopItem(request(t), false, true));
}
}
static void test_requests_are_not_held_while_suspended() {
// Nothing goes on air during a frequency scan or OTA anyway.
for(shade_request_type_t t : RADIO_REQUESTS) {
if(t == shade_request_type_t::unpair) continue;
TEST_ASSERT_FALSE(holdLoopItem(request(t), true, false));
TEST_ASSERT_FALSE(holdLoopItem(request(t), true, true));
}
}
static void test_unpair_waits_out_a_suspend() {
// The client was already told the shade is unpaired.
TEST_ASSERT_TRUE(holdLoopItem(request(shade_request_type_t::unpair), true, false));
TEST_ASSERT_TRUE(holdLoopItem(request(shade_request_type_t::unpair), true, true));
}
int main(int argc, char **argv) {
(void)argc;
(void)argv;
UNITY_BEGIN();
RUN_TEST(test_only_position_and_rolling_code_requests_stay_off_the_radio);
RUN_TEST(test_off_radio_items_are_never_held);
RUN_TEST(test_radio_request_waits_for_room);
RUN_TEST(test_requests_are_not_held_while_suspended);
RUN_TEST(test_unpair_waits_out_a_suspend);
return UNITY_END();
}