feat(zones): rename tabs to zones across api, ui, and storage
Made-with: Cursor
This commit is contained in:
@@ -10,7 +10,7 @@ from test_preset import test_preset
|
||||
from test_profile import test_profile
|
||||
from test_group import test_group
|
||||
from test_sequence import test_sequence
|
||||
from test_tab import test_tab
|
||||
from test_zone import test_zone
|
||||
from test_palette import test_palette
|
||||
from test_device import test_device
|
||||
|
||||
@@ -26,7 +26,7 @@ def run_all_tests():
|
||||
("Profile", test_profile),
|
||||
("Group", test_group),
|
||||
("Sequence", test_sequence),
|
||||
("Tab", test_tab),
|
||||
("Zone", test_zone),
|
||||
("Palette", test_palette),
|
||||
("Device", test_device),
|
||||
]
|
||||
|
||||
@@ -36,7 +36,7 @@ def test_device():
|
||||
|
||||
mac = "aabbccddeeff"
|
||||
print("Testing create device")
|
||||
device_id = devices.create("Test Device", address="aa:bb:cc:dd:ee:ff", default_pattern="on", tabs=["1", "2"])
|
||||
device_id = devices.create("Test Device", address="aa:bb:cc:dd:ee:ff", default_pattern="on", zones=["1", "2"])
|
||||
print(f"Created device with ID: {device_id}")
|
||||
assert device_id == mac
|
||||
assert device_id in devices
|
||||
@@ -51,7 +51,7 @@ def test_device():
|
||||
assert device["transport"] == "espnow"
|
||||
assert device["address"] == mac
|
||||
assert device["default_pattern"] == "on"
|
||||
assert device["tabs"] == ["1", "2"]
|
||||
assert device["zones"] == ["1", "2"]
|
||||
|
||||
print("\nTesting read by colon MAC")
|
||||
assert devices.read("aa:bb:cc:dd:ee:ff")["id"] == mac
|
||||
@@ -65,14 +65,14 @@ def test_device():
|
||||
update_data = {
|
||||
"name": "Updated Device",
|
||||
"default_pattern": "rainbow",
|
||||
"tabs": ["1", "2", "3"],
|
||||
"zones": ["1", "2", "3"],
|
||||
}
|
||||
result = devices.update(device_id, update_data)
|
||||
assert result is True
|
||||
updated = devices.read(device_id)
|
||||
assert updated["name"] == "Updated Device"
|
||||
assert updated["default_pattern"] == "rainbow"
|
||||
assert len(updated["tabs"]) == 3
|
||||
assert len(updated["zones"]) == 3
|
||||
|
||||
print("\nTesting list devices")
|
||||
device_list = devices.list()
|
||||
|
||||
@@ -3,7 +3,7 @@ import os
|
||||
|
||||
def test_profile():
|
||||
"""Test Profile model CRUD operations.
|
||||
Profile create() sets name, type, tabs (list of tab IDs), scenes, palette_id.
|
||||
Profile create() sets name, type, zones (list of zone IDs), scenes, palette_id.
|
||||
"""
|
||||
# Clean up any existing test file (model uses db/profile.json from project root)
|
||||
db_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "db")
|
||||
@@ -24,20 +24,20 @@ def test_profile():
|
||||
print(f"Read: {profile}")
|
||||
assert profile is not None
|
||||
assert profile["name"] == "test_profile"
|
||||
assert "tabs" in profile
|
||||
assert "zones" in profile
|
||||
assert "palette_id" in profile
|
||||
assert "type" in profile
|
||||
|
||||
print("\nTesting update profile")
|
||||
update_data = {
|
||||
"name": "updated_profile",
|
||||
"tabs": ["tab1"],
|
||||
"zones": ["tab1"],
|
||||
}
|
||||
result = profiles.update(profile_id, update_data)
|
||||
assert result is True
|
||||
updated = profiles.read(profile_id)
|
||||
assert updated["name"] == "updated_profile"
|
||||
assert "tab1" in updated["tabs"]
|
||||
assert "tab1" in updated["zones"]
|
||||
|
||||
print("\nTesting list profiles")
|
||||
profile_list = profiles.list()
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
from models.tab import Tab
|
||||
import os
|
||||
|
||||
def test_tab():
|
||||
"""Test Tab model CRUD operations."""
|
||||
# Clean up any existing test file
|
||||
if os.path.exists("Tab.json"):
|
||||
os.remove("Tab.json")
|
||||
|
||||
tabs = Tab()
|
||||
|
||||
print("Testing create tab")
|
||||
tab_id = tabs.create("test_tab", ["1", "2", "3"], ["preset1", "preset2"])
|
||||
print(f"Created tab with ID: {tab_id}")
|
||||
assert tab_id is not None
|
||||
assert tab_id in tabs
|
||||
|
||||
print("\nTesting read tab")
|
||||
tab = tabs.read(tab_id)
|
||||
print(f"Read: {tab}")
|
||||
assert tab is not None
|
||||
assert tab["name"] == "test_tab"
|
||||
assert len(tab["names"]) == 3
|
||||
assert len(tab["presets"]) == 2
|
||||
|
||||
print("\nTesting update tab")
|
||||
update_data = {
|
||||
"name": "updated_tab",
|
||||
"names": ["4", "5"],
|
||||
"presets": ["preset3"]
|
||||
}
|
||||
result = tabs.update(tab_id, update_data)
|
||||
assert result is True
|
||||
updated = tabs.read(tab_id)
|
||||
assert updated["name"] == "updated_tab"
|
||||
assert len(updated["names"]) == 2
|
||||
assert len(updated["presets"]) == 1
|
||||
|
||||
print("\nTesting list tabs")
|
||||
tab_list = tabs.list()
|
||||
print(f"Tab list: {tab_list}")
|
||||
assert tab_id in tab_list
|
||||
|
||||
print("\nTesting delete tab")
|
||||
deleted = tabs.delete(tab_id)
|
||||
assert deleted is True
|
||||
assert tab_id not in tabs
|
||||
|
||||
print("\nTesting read after delete")
|
||||
tab = tabs.read(tab_id)
|
||||
assert tab is None
|
||||
|
||||
print("\nAll tab tests passed!")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_tab()
|
||||
57
tests/models/test_zone.py
Normal file
57
tests/models/test_zone.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from models.zone import Zone
|
||||
import os
|
||||
|
||||
|
||||
def test_zone():
|
||||
"""Test Zone model CRUD operations."""
|
||||
if os.path.exists("Zone.json"):
|
||||
os.remove("Zone.json")
|
||||
|
||||
zones = Zone()
|
||||
|
||||
print("Testing create zone")
|
||||
zone_id = zones.create("test_zone", ["1", "2", "3"], ["preset1", "preset2"])
|
||||
print(f"Created zone with ID: {zone_id}")
|
||||
assert zone_id is not None
|
||||
assert zone_id in zones
|
||||
|
||||
print("\nTesting read zone")
|
||||
zone = zones.read(zone_id)
|
||||
print(f"Read: {zone}")
|
||||
assert zone is not None
|
||||
assert zone["name"] == "test_zone"
|
||||
assert len(zone["names"]) == 3
|
||||
assert len(zone["presets"]) == 2
|
||||
|
||||
print("\nTesting update zone")
|
||||
update_data = {
|
||||
"name": "updated_zone",
|
||||
"names": ["4", "5"],
|
||||
"presets": ["preset3"],
|
||||
}
|
||||
result = zones.update(zone_id, update_data)
|
||||
assert result is True
|
||||
updated = zones.read(zone_id)
|
||||
assert updated["name"] == "updated_zone"
|
||||
assert len(updated["names"]) == 2
|
||||
assert len(updated["presets"]) == 1
|
||||
|
||||
print("\nTesting list zones")
|
||||
zone_list = zones.list()
|
||||
print(f"Zone list: {zone_list}")
|
||||
assert zone_id in zone_list
|
||||
|
||||
print("\nTesting delete zone")
|
||||
deleted = zones.delete(zone_id)
|
||||
assert deleted is True
|
||||
assert zone_id not in zones
|
||||
|
||||
print("\nTesting read after delete")
|
||||
zone = zones.read(zone_id)
|
||||
assert zone is None
|
||||
|
||||
print("\nAll zone tests passed!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_zone()
|
||||
@@ -162,13 +162,13 @@ class BrowserTest:
|
||||
print(f" ⚠ Failed to cleanup preset {preset_id}: {e}")
|
||||
|
||||
# Delete created tabs by ID
|
||||
for tab_id in self.created_tabs:
|
||||
for zone_id in self.created_tabs:
|
||||
try:
|
||||
response = session.delete(f"{self.base_url}/tabs/{tab_id}")
|
||||
response = session.delete(f"{self.base_url}/zones/{zone_id}")
|
||||
if response.status_code == 200:
|
||||
print(f" ✓ Cleaned up tab: {tab_id}")
|
||||
print(f" ✓ Cleaned up zone: {zone_id}")
|
||||
except Exception as e:
|
||||
print(f" ⚠ Failed to cleanup tab {tab_id}: {e}")
|
||||
print(f" ⚠ Failed to cleanup zone {zone_id}: {e}")
|
||||
|
||||
# Delete created profiles by ID
|
||||
for profile_id in self.created_profiles:
|
||||
@@ -180,20 +180,20 @@ class BrowserTest:
|
||||
print(f" ⚠ Failed to cleanup profile {profile_id}: {e}")
|
||||
|
||||
# Also try to cleanup by name pattern (in case IDs weren't tracked)
|
||||
test_names = ['Browser Test Tab', 'Browser Test Profile', 'Browser Test Preset',
|
||||
'Preset 1', 'Preset 2', 'Preset 3', 'Edited Browser Tab']
|
||||
test_names = ['Browser Test Zone', 'Browser Test Profile', 'Browser Test Preset',
|
||||
'Preset 1', 'Preset 2', 'Preset 3', 'Edited Browser Zone']
|
||||
|
||||
# Cleanup tabs by name
|
||||
try:
|
||||
tabs_response = session.get(f"{self.base_url}/tabs")
|
||||
tabs_response = session.get(f"{self.base_url}/zones")
|
||||
if tabs_response.status_code == 200:
|
||||
tabs_data = tabs_response.json()
|
||||
tabs = tabs_data.get('tabs', {})
|
||||
for tab_id, tab_data in tabs.items():
|
||||
tabs = tabs_data.get('zones', {})
|
||||
for zone_id, tab_data in zones.items():
|
||||
if isinstance(tab_data, dict) and tab_data.get('name') in test_names:
|
||||
try:
|
||||
session.delete(f"{self.base_url}/tabs/{tab_id}")
|
||||
print(f" ✓ Cleaned up tab by name: {tab_data.get('name')}")
|
||||
session.delete(f"{self.base_url}/zones/{zone_id}")
|
||||
print(f" ✓ Cleaned up zone by name: {tab_data.get('name')}")
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
@@ -330,11 +330,11 @@ def test_tabs_ui(browser: BrowserTest) -> bool:
|
||||
|
||||
# Test 2: Open tabs modal
|
||||
total += 1
|
||||
if browser.click_element(By.ID, 'tabs-btn'):
|
||||
if browser.click_element(By.ID, 'zones-btn'):
|
||||
print("✓ Clicked Tabs button")
|
||||
# Wait for modal to appear
|
||||
time.sleep(0.5)
|
||||
modal = browser.wait_for_element(By.ID, 'tabs-modal')
|
||||
modal = browser.wait_for_element(By.ID, 'zones-modal')
|
||||
if modal and 'active' in modal.get_attribute('class'):
|
||||
print("✓ Tabs modal opened")
|
||||
passed += 1
|
||||
@@ -343,58 +343,58 @@ def test_tabs_ui(browser: BrowserTest) -> bool:
|
||||
else:
|
||||
print("✗ Failed to click Tabs button")
|
||||
|
||||
# Test 3: Create a tab via UI
|
||||
# Test 3: Create a zone via UI
|
||||
total += 1
|
||||
try:
|
||||
# Fill in tab name
|
||||
if browser.fill_input(By.ID, 'new-tab-name', 'Browser Test Tab'):
|
||||
print(" ✓ Filled tab name")
|
||||
# Fill in zone name
|
||||
if browser.fill_input(By.ID, 'new-zone-name', 'Browser Test Zone'):
|
||||
print(" ✓ Filled zone name")
|
||||
# Devices default from registry or placeholder name "1"
|
||||
# Click create button
|
||||
if browser.click_element(By.ID, 'create-tab-btn'):
|
||||
if browser.click_element(By.ID, 'create-zone-btn'):
|
||||
print(" ✓ Clicked create button")
|
||||
time.sleep(1) # Wait for creation
|
||||
# Check if tab appears in list and extract ID
|
||||
tabs_list = browser.wait_for_element(By.ID, 'tabs-list-modal')
|
||||
# Check if zone appears in list and extract ID
|
||||
tabs_list = browser.wait_for_element(By.ID, 'zones-list-modal')
|
||||
if tabs_list:
|
||||
list_text = tabs_list.text
|
||||
if 'Browser Test Tab' in list_text:
|
||||
print("✓ Created tab via UI")
|
||||
# Try to extract tab ID from the list (look for data-tab-id attribute)
|
||||
if 'Browser Test Zone' in list_text:
|
||||
print("✓ Created zone via UI")
|
||||
# Try to extract zone ID from the list (look for data-zone-id attribute)
|
||||
try:
|
||||
tab_rows = browser.driver.find_elements(By.CSS_SELECTOR, '#tabs-list-modal .profiles-row')
|
||||
tab_rows = browser.driver.find_elements(By.CSS_SELECTOR, '#zones-list-modal .profiles-row')
|
||||
for row in tab_rows:
|
||||
if 'Browser Test Tab' in row.text:
|
||||
tab_id = row.get_attribute('data-tab-id')
|
||||
if tab_id:
|
||||
browser.created_tabs.append(tab_id)
|
||||
if 'Browser Test Zone' in row.text:
|
||||
zone_id = row.get_attribute('data-zone-id')
|
||||
if zone_id:
|
||||
browser.created_tabs.append(zone_id)
|
||||
break
|
||||
except:
|
||||
pass # If we can't extract ID, cleanup will try by name
|
||||
passed += 1
|
||||
else:
|
||||
print("✗ Tab not found in list after creation")
|
||||
print("✗ Zone not found in list after creation")
|
||||
else:
|
||||
print("✗ Tabs list not found")
|
||||
else:
|
||||
print("✗ Failed to click create button")
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to create tab via UI: {e}")
|
||||
print(f"✗ Failed to create zone via UI: {e}")
|
||||
|
||||
# Test 4: Edit a tab via UI (right-click in Tabs list)
|
||||
# Test 4: Edit a zone via UI (right-click in Tabs list)
|
||||
total += 1
|
||||
try:
|
||||
# First, close and reopen modal to refresh
|
||||
browser.click_element(By.ID, 'tabs-close-btn')
|
||||
browser.click_element(By.ID, 'zones-close-btn')
|
||||
time.sleep(0.5)
|
||||
browser.click_element(By.ID, 'tabs-btn')
|
||||
browser.click_element(By.ID, 'zones-btn')
|
||||
time.sleep(0.5)
|
||||
|
||||
# Right-click the row corresponding to 'Browser Test Tab'
|
||||
# Right-click the row corresponding to 'Browser Test Zone'
|
||||
try:
|
||||
tab_row = browser.driver.find_element(
|
||||
By.XPATH,
|
||||
"//div[@id='tabs-list-modal']//div[contains(@class,'profiles-row')][.//span[contains(text(), 'Browser Test Tab')]]"
|
||||
"//div[@id='zones-list-modal']//div[contains(@class,'profiles-row')][.//span[contains(text(), 'Browser Test Zone')]]"
|
||||
)
|
||||
except Exception:
|
||||
tab_row = None
|
||||
@@ -405,14 +405,14 @@ def test_tabs_ui(browser: BrowserTest) -> bool:
|
||||
time.sleep(0.5)
|
||||
|
||||
# Check if edit modal opened
|
||||
edit_modal = browser.wait_for_element(By.ID, 'edit-tab-modal')
|
||||
edit_modal = browser.wait_for_element(By.ID, 'edit-zone-modal')
|
||||
if edit_modal:
|
||||
print("✓ Edit modal opened via right-click")
|
||||
# Fill in new name
|
||||
if browser.fill_input(By.ID, 'edit-tab-name', 'Edited Browser Tab'):
|
||||
print(" ✓ Filled new tab name")
|
||||
if browser.fill_input(By.ID, 'edit-zone-name', 'Edited Browser Zone'):
|
||||
print(" ✓ Filled new zone name")
|
||||
# Submit form
|
||||
edit_form = browser.wait_for_element(By.ID, 'edit-tab-form')
|
||||
edit_form = browser.wait_for_element(By.ID, 'edit-zone-form')
|
||||
if edit_form:
|
||||
browser.driver.execute_script("arguments[0].submit();", edit_form)
|
||||
time.sleep(1) # Wait for update
|
||||
@@ -423,24 +423,24 @@ def test_tabs_ui(browser: BrowserTest) -> bool:
|
||||
else:
|
||||
print("✗ Edit modal didn't open after right-click")
|
||||
else:
|
||||
print("✗ Could not find tab row for 'Browser Test Tab'")
|
||||
print("✗ Could not find zone row for 'Browser Test Zone'")
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to edit tab via UI: {e}")
|
||||
print(f"✗ Failed to edit zone via UI: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
# Test 5: Check current tab cookie
|
||||
# Test 5: Check current zone cookie
|
||||
total += 1
|
||||
cookie = browser.get_cookie('current_tab')
|
||||
cookie = browser.get_cookie('current_zone')
|
||||
if cookie:
|
||||
print(f"✓ Found current_tab cookie: {cookie.get('value')}")
|
||||
print(f"✓ Found current_zone cookie: {cookie.get('value')}")
|
||||
passed += 1
|
||||
else:
|
||||
print("⚠ No current_tab cookie found (might be normal if no tab selected)")
|
||||
print("⚠ No current_zone cookie found (might be normal if no zone selected)")
|
||||
passed += 1 # Not a failure, just informational
|
||||
|
||||
# Close modal
|
||||
browser.click_element(By.ID, 'tabs-close-btn')
|
||||
browser.click_element(By.ID, 'zones-close-btn')
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Browser test error: {e}")
|
||||
@@ -519,7 +519,7 @@ def test_profiles_ui(browser: BrowserTest) -> bool:
|
||||
|
||||
def test_mobile_tab_presets_two_columns():
|
||||
"""
|
||||
Verify that the tab preset selecting area shows roughly two preset tiles per row
|
||||
Verify that the zone preset selecting area shows roughly two preset tiles per row
|
||||
on a phone-sized viewport.
|
||||
"""
|
||||
bt = BrowserTest(base_url=BASE_URL, headless=True)
|
||||
@@ -531,18 +531,18 @@ def test_mobile_tab_presets_two_columns():
|
||||
bt.driver.set_window_size(400, 800)
|
||||
assert bt.navigate('/'), "Failed to load main page"
|
||||
|
||||
# Click the first tab button to load presets for that tab
|
||||
first_tab = bt.wait_for_element(By.CSS_SELECTOR, '.tab-button', timeout=10)
|
||||
assert first_tab is not None, "No tab buttons found"
|
||||
# Click the first zone button to load presets for that zone
|
||||
first_tab = bt.wait_for_element(By.CSS_SELECTOR, '.zone-button', timeout=10)
|
||||
assert first_tab is not None, "No zone buttons found"
|
||||
first_tab.click()
|
||||
time.sleep(1)
|
||||
|
||||
container = bt.wait_for_element(By.ID, 'presets-list-tab', timeout=10)
|
||||
assert container is not None, "presets-list-tab not found"
|
||||
container = bt.wait_for_element(By.ID, 'presets-list-zone', timeout=10)
|
||||
assert container is not None, "presets-list-zone not found"
|
||||
|
||||
tiles = bt.driver.find_elements(By.CSS_SELECTOR, '#presets-list-tab .preset-tile-row')
|
||||
tiles = bt.driver.find_elements(By.CSS_SELECTOR, '#presets-list-zone .preset-tile-row')
|
||||
# Need at least 2 presets to make this meaningful
|
||||
assert len(tiles) >= 2, "Fewer than 2 presets found for tab"
|
||||
assert len(tiles) >= 2, "Fewer than 2 presets found for zone"
|
||||
|
||||
container_width = container.size['width']
|
||||
first_width = tiles[0].size['width']
|
||||
@@ -760,8 +760,8 @@ def test_color_palette_ui(browser: BrowserTest) -> bool:
|
||||
return passed >= total - 1 # Allow one failure (alert handling might be flaky)
|
||||
|
||||
def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
|
||||
"""Test dragging presets around in a tab."""
|
||||
print("\n=== Testing Preset Drag and Drop in Tab ===")
|
||||
"""Test dragging presets around in a zone."""
|
||||
print("\n=== Testing Preset Drag and Drop in Zone ===")
|
||||
passed = 0
|
||||
total = 0
|
||||
|
||||
@@ -769,7 +769,7 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
|
||||
return False
|
||||
|
||||
try:
|
||||
# Test 1: Load page and ensure we have a tab
|
||||
# Test 1: Load page and ensure we have a zone
|
||||
total += 1
|
||||
if browser.navigate('/'):
|
||||
print("✓ Loaded main page")
|
||||
@@ -778,33 +778,33 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
|
||||
browser.teardown()
|
||||
return False
|
||||
|
||||
# Test 2: Open tabs modal and create/select a tab
|
||||
# Test 2: Open tabs modal and create/select a zone
|
||||
total += 1
|
||||
browser.click_element(By.ID, 'tabs-btn')
|
||||
browser.click_element(By.ID, 'zones-btn')
|
||||
time.sleep(0.5)
|
||||
|
||||
# Check if we have tabs, if not create one
|
||||
tabs_list = browser.wait_for_element(By.ID, 'tabs-list-modal')
|
||||
tabs_list = browser.wait_for_element(By.ID, 'zones-list-modal')
|
||||
if tabs_list and 'No tabs found' in tabs_list.text:
|
||||
# Create a tab
|
||||
browser.fill_input(By.ID, 'new-tab-name', 'Drag Test Tab')
|
||||
browser.click_element(By.ID, 'create-tab-btn')
|
||||
# Create a zone
|
||||
browser.fill_input(By.ID, 'new-zone-name', 'Drag Test Zone')
|
||||
browser.click_element(By.ID, 'create-zone-btn')
|
||||
time.sleep(1)
|
||||
|
||||
# Select first tab (or the one we just created)
|
||||
# Select first zone (or the one we just created)
|
||||
select_buttons = browser.driver.find_elements(By.XPATH, "//button[contains(text(), 'Select')]")
|
||||
if select_buttons:
|
||||
select_buttons[0].click()
|
||||
time.sleep(1)
|
||||
print("✓ Selected a tab")
|
||||
print("✓ Selected a zone")
|
||||
passed += 1
|
||||
else:
|
||||
print("✗ No tabs available to select")
|
||||
browser.click_element(By.ID, 'tabs-close-btn')
|
||||
browser.click_element(By.ID, 'zones-close-btn')
|
||||
browser.teardown()
|
||||
return False
|
||||
|
||||
browser.click_element(By.ID, 'tabs-close-btn', use_js=True)
|
||||
browser.click_element(By.ID, 'zones-close-btn', use_js=True)
|
||||
time.sleep(0.5)
|
||||
|
||||
# Test 3: Open presets modal and create presets
|
||||
@@ -845,54 +845,54 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
|
||||
print("✓ Created 3 presets for drag test")
|
||||
passed += 1
|
||||
|
||||
# Test 4: Add presets to the tab (via Edit Tab modal – Add buttons in list)
|
||||
# Test 4: Add presets to the zone (via Edit Zone modal – Add buttons in list)
|
||||
total += 1
|
||||
try:
|
||||
tab_id = browser.driver.execute_script(
|
||||
zone_id = browser.driver.execute_script(
|
||||
"return (window.tabsManager && window.tabsManager.getCurrentTabId && window.tabsManager.getCurrentTabId()) || null;"
|
||||
)
|
||||
if not tab_id:
|
||||
print("✗ Could not get current tab id")
|
||||
if not zone_id:
|
||||
print("✗ Could not get current zone id")
|
||||
else:
|
||||
browser.driver.execute_script(
|
||||
"if (window.tabsManager && window.tabsManager.openEditTabModal) { window.tabsManager.openEditTabModal(arguments[0], null); }",
|
||||
tab_id
|
||||
zone_id
|
||||
)
|
||||
time.sleep(1)
|
||||
list_el = browser.wait_for_element(By.ID, 'edit-tab-presets-list', timeout=5)
|
||||
list_el = browser.wait_for_element(By.ID, 'edit-zone-presets-list', timeout=5)
|
||||
if list_el:
|
||||
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-tab-presets-list']//button[text()='Add']")
|
||||
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-zone-presets-list']//button[text()='Add']")
|
||||
if len(select_buttons) >= 2:
|
||||
browser.driver.execute_script("arguments[0].click();", select_buttons[0])
|
||||
time.sleep(1.5)
|
||||
browser.handle_alert(accept=True, timeout=1)
|
||||
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-tab-presets-list']//button[text()='Add']")
|
||||
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-zone-presets-list']//button[text()='Add']")
|
||||
if len(select_buttons) >= 1:
|
||||
browser.driver.execute_script("arguments[0].click();", select_buttons[0])
|
||||
time.sleep(1.5)
|
||||
browser.handle_alert(accept=True, timeout=1)
|
||||
print(" ✓ Added 2 presets to tab")
|
||||
print(" ✓ Added 2 presets to zone")
|
||||
passed += 1
|
||||
elif len(select_buttons) == 1:
|
||||
browser.driver.execute_script("arguments[0].click();", select_buttons[0])
|
||||
time.sleep(1.5)
|
||||
browser.handle_alert(accept=True, timeout=1)
|
||||
print(" ✓ Added 1 preset to tab")
|
||||
print(" ✓ Added 1 preset to zone")
|
||||
passed += 1
|
||||
else:
|
||||
print(" ⚠ No presets available to add (all already in tab)")
|
||||
print(" ⚠ No presets available to add (all already in zone)")
|
||||
else:
|
||||
print("✗ Edit tab presets list not found")
|
||||
print("✗ Edit zone presets list not found")
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to add presets to tab: {e}")
|
||||
print(f"✗ Failed to add presets to zone: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
# Test 5: Find presets in tab and test drag and drop (Edit mode only)
|
||||
# Test 5: Find presets in zone and test drag and drop (Edit mode only)
|
||||
total += 1
|
||||
try:
|
||||
# Wait for presets to load in the tab
|
||||
presets_list_tab = browser.wait_for_element(By.ID, 'presets-list-tab', timeout=5)
|
||||
# Wait for presets to load in the zone
|
||||
presets_list_tab = browser.wait_for_element(By.ID, 'presets-list-zone', timeout=5)
|
||||
if presets_list_tab:
|
||||
time.sleep(1) # Wait for presets to render
|
||||
|
||||
@@ -904,7 +904,7 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
|
||||
|
||||
# Find draggable preset elements - wait a bit more for rendering
|
||||
time.sleep(1)
|
||||
draggable_presets = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-tab .draggable-preset')
|
||||
draggable_presets = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-zone .draggable-preset')
|
||||
if len(draggable_presets) >= 2:
|
||||
print(f" ✓ Found {len(draggable_presets)} draggable presets")
|
||||
|
||||
@@ -922,7 +922,7 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
|
||||
time.sleep(1) # Wait for reorder to complete
|
||||
|
||||
# Check if order changed
|
||||
draggable_presets_after = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-tab .draggable-preset')
|
||||
draggable_presets_after = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-zone .draggable-preset')
|
||||
if len(draggable_presets_after) >= 2:
|
||||
new_order = [p.text for p in draggable_presets_after]
|
||||
print(f" New order: {new_order[:3]}")
|
||||
@@ -936,28 +936,28 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
|
||||
else:
|
||||
print("✗ Presets disappeared after drag")
|
||||
elif len(draggable_presets) == 1:
|
||||
print(f"⚠ Only 1 preset found in tab (need 2 for drag test). Preset: {draggable_presets[0].text}")
|
||||
tab_id = browser.driver.execute_script(
|
||||
print(f"⚠ Only 1 preset found in zone (need 2 for drag test). Preset: {draggable_presets[0].text}")
|
||||
zone_id = browser.driver.execute_script(
|
||||
"return (window.tabsManager && window.tabsManager.getCurrentTabId && window.tabsManager.getCurrentTabId()) || null;"
|
||||
)
|
||||
if tab_id:
|
||||
if zone_id:
|
||||
browser.driver.execute_script(
|
||||
"if (window.tabsManager && window.tabsManager.openEditTabModal) { window.tabsManager.openEditTabModal(arguments[0], null); }",
|
||||
tab_id
|
||||
zone_id
|
||||
)
|
||||
time.sleep(1)
|
||||
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-tab-presets-list']//button[text()='Add']")
|
||||
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-zone-presets-list']//button[text()='Add']")
|
||||
if select_buttons:
|
||||
print(" Attempting to add another preset...")
|
||||
browser.driver.execute_script("arguments[0].click();", select_buttons[0])
|
||||
time.sleep(1.5)
|
||||
browser.handle_alert(accept=True, timeout=1)
|
||||
try:
|
||||
browser.driver.execute_script("document.getElementById('edit-tab-modal').classList.remove('active');")
|
||||
browser.driver.execute_script("document.getElementById('edit-zone-modal').classList.remove('active');")
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(1)
|
||||
draggable_presets = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-tab .draggable-preset')
|
||||
draggable_presets = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-zone .draggable-preset')
|
||||
if len(draggable_presets) >= 2:
|
||||
print(" ✓ Added another preset, now testing drag...")
|
||||
source = draggable_presets[0]
|
||||
@@ -970,11 +970,11 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
|
||||
else:
|
||||
print(f" ✗ Still only {len(draggable_presets)} preset(s) after adding")
|
||||
else:
|
||||
print(" ✗ No Add buttons found in Edit Tab modal")
|
||||
print(" ✗ No Add buttons found in Edit Zone modal")
|
||||
else:
|
||||
print(f"✗ No presets found in tab (found {len(draggable_presets)})")
|
||||
print(f"✗ No presets found in zone (found {len(draggable_presets)})")
|
||||
else:
|
||||
print("✗ Presets list in tab not found")
|
||||
print("✗ Presets list in zone not found")
|
||||
except Exception as e:
|
||||
print(f"✗ Drag and drop test error: {e}")
|
||||
import traceback
|
||||
|
||||
@@ -91,115 +91,115 @@ def test_tabs(client: TestClient) -> bool:
|
||||
# Test 1: List tabs
|
||||
total += 1
|
||||
try:
|
||||
response = client.get('/tabs')
|
||||
response = client.get('/zones')
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"✓ GET /tabs - Found {len(data.get('tabs', {}))} tabs")
|
||||
print(f"✓ GET /zones - Found {len(data.get('zones', {}))} tabs")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ GET /tabs - Status: {response.status_code}")
|
||||
print(f"✗ GET /zones - Status: {response.status_code}")
|
||||
except Exception as e:
|
||||
print(f"✗ GET /tabs - Error: {e}")
|
||||
print(f"✗ GET /zones - Error: {e}")
|
||||
|
||||
# Test 2: Create tab
|
||||
# Test 2: Create zone
|
||||
total += 1
|
||||
try:
|
||||
tab_data = {
|
||||
"name": "Test Tab",
|
||||
"name": "Test Zone",
|
||||
"names": ["1", "2"]
|
||||
}
|
||||
response = client.post('/tabs', json_data=tab_data)
|
||||
response = client.post('/zones', json_data=tab_data)
|
||||
if response.status_code == 201:
|
||||
created_tab = response.json()
|
||||
# Response format: {tab_id: {tab_data}}
|
||||
# Response format: {zone_id: {tab_data}}
|
||||
if isinstance(created_tab, dict):
|
||||
# Get the first key which should be the tab ID
|
||||
tab_id = next(iter(created_tab.keys())) if created_tab else None
|
||||
# Get the first key which should be the zone ID
|
||||
zone_id = next(iter(created_tab.keys())) if created_tab else None
|
||||
else:
|
||||
tab_id = None
|
||||
print(f"✓ POST /tabs - Created tab: {tab_id}")
|
||||
zone_id = None
|
||||
print(f"✓ POST /zones - Created zone: {zone_id}")
|
||||
passed += 1
|
||||
|
||||
# Test 3: Get specific tab
|
||||
if tab_id:
|
||||
# Test 3: Get specific zone
|
||||
if zone_id:
|
||||
total += 1
|
||||
response = client.get(f'/tabs/{tab_id}')
|
||||
response = client.get(f'/zones/{zone_id}')
|
||||
if response.status_code == 200:
|
||||
print(f"✓ GET /tabs/{tab_id} - Retrieved tab")
|
||||
print(f"✓ GET /zones/{zone_id} - Retrieved zone")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ GET /tabs/{tab_id} - Status: {response.status_code}")
|
||||
print(f"✗ GET /zones/{zone_id} - Status: {response.status_code}")
|
||||
|
||||
# Test 4: Set current tab
|
||||
# Test 4: Set current zone
|
||||
total += 1
|
||||
response = client.post(f'/tabs/{tab_id}/set-current')
|
||||
response = client.post(f'/zones/{zone_id}/set-current')
|
||||
if response.status_code == 200:
|
||||
print(f"✓ POST /tabs/{tab_id}/set-current - Set current tab")
|
||||
print(f"✓ POST /zones/{zone_id}/set-current - Set current zone")
|
||||
# Check cookie was set
|
||||
cookie = client.get_cookie('current_tab')
|
||||
if cookie == tab_id:
|
||||
print(f" ✓ Cookie 'current_tab' set to {tab_id}")
|
||||
cookie = client.get_cookie('current_zone')
|
||||
if cookie == zone_id:
|
||||
print(f" ✓ Cookie 'current_zone' set to {zone_id}")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ POST /tabs/{tab_id}/set-current - Status: {response.status_code}")
|
||||
print(f"✗ POST /zones/{zone_id}/set-current - Status: {response.status_code}")
|
||||
|
||||
# Test 5: Get current tab
|
||||
# Test 5: Get current zone
|
||||
total += 1
|
||||
response = client.get('/tabs/current')
|
||||
response = client.get('/zones/current')
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get('tab_id') == tab_id:
|
||||
print(f"✓ GET /tabs/current - Current tab is {tab_id}")
|
||||
if data.get('zone_id') == zone_id:
|
||||
print(f"✓ GET /zones/current - Current zone is {zone_id}")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ GET /tabs/current - Wrong tab ID")
|
||||
print(f"✗ GET /zones/current - Wrong zone ID")
|
||||
else:
|
||||
print(f"✗ GET /tabs/current - Status: {response.status_code}")
|
||||
print(f"✗ GET /zones/current - Status: {response.status_code}")
|
||||
|
||||
# Test 6: Update tab (edit functionality)
|
||||
# Test 6: Update zone (edit functionality)
|
||||
total += 1
|
||||
update_data = {
|
||||
"name": "Updated Test Tab",
|
||||
"name": "Updated Test Zone",
|
||||
"names": ["1", "2", "3"] # Update device IDs too
|
||||
}
|
||||
response = client.put(f'/tabs/{tab_id}', json_data=update_data)
|
||||
response = client.put(f'/zones/{zone_id}', json_data=update_data)
|
||||
if response.status_code == 200:
|
||||
updated = response.json()
|
||||
if updated.get('name') == "Updated Test Tab" and updated.get('names') == ["1", "2", "3"]:
|
||||
print(f"✓ PUT /tabs/{tab_id} - Updated tab (name and device IDs)")
|
||||
if updated.get('name') == "Updated Test Zone" and updated.get('names') == ["1", "2", "3"]:
|
||||
print(f"✓ PUT /zones/{zone_id} - Updated zone (name and device IDs)")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ PUT /tabs/{tab_id} - Update didn't work correctly")
|
||||
print(f" Expected name='Updated Test Tab', got '{updated.get('name')}'")
|
||||
print(f"✗ PUT /zones/{zone_id} - Update didn't work correctly")
|
||||
print(f" Expected name='Updated Test Zone', got '{updated.get('name')}'")
|
||||
print(f" Expected names=['1','2','3'], got {updated.get('names')}")
|
||||
else:
|
||||
print(f"✗ PUT /tabs/{tab_id} - Status: {response.status_code}, Response: {response.text}")
|
||||
print(f"✗ PUT /zones/{zone_id} - Status: {response.status_code}, Response: {response.text}")
|
||||
|
||||
# Test 6b: Verify update persisted
|
||||
total += 1
|
||||
response = client.get(f'/tabs/{tab_id}')
|
||||
response = client.get(f'/zones/{zone_id}')
|
||||
if response.status_code == 200:
|
||||
verified = response.json()
|
||||
if verified.get('name') == "Updated Test Tab":
|
||||
print(f"✓ GET /tabs/{tab_id} - Verified update persisted")
|
||||
if verified.get('name') == "Updated Test Zone":
|
||||
print(f"✓ GET /zones/{zone_id} - Verified update persisted")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ GET /tabs/{tab_id} - Update didn't persist")
|
||||
print(f"✗ GET /zones/{zone_id} - Update didn't persist")
|
||||
else:
|
||||
print(f"✗ GET /tabs/{tab_id} - Status: {response.status_code}")
|
||||
print(f"✗ GET /zones/{zone_id} - Status: {response.status_code}")
|
||||
|
||||
# Test 7: Delete tab
|
||||
# Test 7: Delete zone
|
||||
total += 1
|
||||
response = client.delete(f'/tabs/{tab_id}')
|
||||
response = client.delete(f'/zones/{zone_id}')
|
||||
if response.status_code == 200:
|
||||
print(f"✓ DELETE /tabs/{tab_id} - Deleted tab")
|
||||
print(f"✓ DELETE /zones/{zone_id} - Deleted zone")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ DELETE /tabs/{tab_id} - Status: {response.status_code}")
|
||||
print(f"✗ DELETE /zones/{zone_id} - Status: {response.status_code}")
|
||||
else:
|
||||
print(f"✗ POST /tabs - Status: {response.status_code}, Response: {response.text}")
|
||||
print(f"✗ POST /zones - Status: {response.status_code}, Response: {response.text}")
|
||||
except Exception as e:
|
||||
print(f"✗ POST /tabs - Error: {e}")
|
||||
print(f"✗ POST /zones - Error: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -409,87 +409,87 @@ def test_patterns(client: TestClient) -> bool:
|
||||
return passed == total
|
||||
|
||||
def test_tab_edit_workflow(client: TestClient) -> bool:
|
||||
"""Test complete tab edit workflow like a browser would."""
|
||||
print("\n=== Testing Tab Edit Workflow ===")
|
||||
"""Test complete zone edit workflow like a browser would."""
|
||||
print("\n=== Testing Zone Edit Workflow ===")
|
||||
passed = 0
|
||||
total = 0
|
||||
|
||||
# Step 1: Create a tab to edit
|
||||
# Step 1: Create a zone to edit
|
||||
total += 1
|
||||
try:
|
||||
tab_data = {
|
||||
"name": "Tab to Edit",
|
||||
"name": "Zone to Edit",
|
||||
"names": ["1"]
|
||||
}
|
||||
response = client.post('/tabs', json_data=tab_data)
|
||||
response = client.post('/zones', json_data=tab_data)
|
||||
if response.status_code == 201:
|
||||
created = response.json()
|
||||
if isinstance(created, dict):
|
||||
tab_id = next(iter(created.keys())) if created else None
|
||||
zone_id = next(iter(created.keys())) if created else None
|
||||
else:
|
||||
tab_id = None
|
||||
zone_id = None
|
||||
|
||||
if tab_id:
|
||||
print(f"✓ Created tab {tab_id} for editing")
|
||||
if zone_id:
|
||||
print(f"✓ Created zone {zone_id} for editing")
|
||||
passed += 1
|
||||
|
||||
# Step 2: Get the tab to verify initial state
|
||||
# Step 2: Get the zone to verify initial state
|
||||
total += 1
|
||||
response = client.get(f'/tabs/{tab_id}')
|
||||
response = client.get(f'/zones/{zone_id}')
|
||||
if response.status_code == 200:
|
||||
original_tab = response.json()
|
||||
print(f"✓ Retrieved tab - Name: '{original_tab.get('name')}', IDs: {original_tab.get('names')}")
|
||||
print(f"✓ Retrieved zone - Name: '{original_tab.get('name')}', IDs: {original_tab.get('names')}")
|
||||
passed += 1
|
||||
|
||||
# Step 3: Edit the tab (simulate browser edit form submission)
|
||||
# Step 3: Edit the zone (simulate browser edit form submission)
|
||||
total += 1
|
||||
edit_data = {
|
||||
"name": "Edited Tab Name",
|
||||
"name": "Edited Zone Name",
|
||||
"names": ["2", "3", "4"]
|
||||
}
|
||||
response = client.put(f'/tabs/{tab_id}', json_data=edit_data)
|
||||
response = client.put(f'/zones/{zone_id}', json_data=edit_data)
|
||||
if response.status_code == 200:
|
||||
edited = response.json()
|
||||
if edited.get('name') == "Edited Tab Name" and edited.get('names') == ["2", "3", "4"]:
|
||||
print(f"✓ PUT /tabs/{tab_id} - Successfully edited tab")
|
||||
if edited.get('name') == "Edited Zone Name" and edited.get('names') == ["2", "3", "4"]:
|
||||
print(f"✓ PUT /zones/{zone_id} - Successfully edited zone")
|
||||
print(f" New name: '{edited.get('name')}'")
|
||||
print(f" New device IDs: {edited.get('names')}")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ PUT /tabs/{tab_id} - Edit didn't work correctly")
|
||||
print(f"✗ PUT /zones/{zone_id} - Edit didn't work correctly")
|
||||
print(f" Got: {edited}")
|
||||
else:
|
||||
print(f"✗ PUT /tabs/{tab_id} - Status: {response.status_code}, Response: {response.text}")
|
||||
print(f"✗ PUT /zones/{zone_id} - Status: {response.status_code}, Response: {response.text}")
|
||||
|
||||
# Step 4: Verify edit persisted by getting the tab again
|
||||
# Step 4: Verify edit persisted by getting the zone again
|
||||
total += 1
|
||||
response = client.get(f'/tabs/{tab_id}')
|
||||
response = client.get(f'/zones/{zone_id}')
|
||||
if response.status_code == 200:
|
||||
verified = response.json()
|
||||
if verified.get('name') == "Edited Tab Name" and verified.get('names') == ["2", "3", "4"]:
|
||||
print(f"✓ GET /tabs/{tab_id} - Verified edit persisted")
|
||||
if verified.get('name') == "Edited Zone Name" and verified.get('names') == ["2", "3", "4"]:
|
||||
print(f"✓ GET /zones/{zone_id} - Verified edit persisted")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ GET /tabs/{tab_id} - Edit didn't persist")
|
||||
print(f" Expected name='Edited Tab Name', got '{verified.get('name')}'")
|
||||
print(f"✗ GET /zones/{zone_id} - Edit didn't persist")
|
||||
print(f" Expected name='Edited Zone Name', got '{verified.get('name')}'")
|
||||
print(f" Expected names=['2','3','4'], got {verified.get('names')}")
|
||||
else:
|
||||
print(f"✗ GET /tabs/{tab_id} - Status: {response.status_code}")
|
||||
print(f"✗ GET /zones/{zone_id} - Status: {response.status_code}")
|
||||
|
||||
# Step 5: Clean up - delete the test tab
|
||||
# Step 5: Clean up - delete the test zone
|
||||
total += 1
|
||||
response = client.delete(f'/tabs/{tab_id}')
|
||||
response = client.delete(f'/zones/{zone_id}')
|
||||
if response.status_code == 200:
|
||||
print(f"✓ DELETE /tabs/{tab_id} - Cleaned up test tab")
|
||||
print(f"✓ DELETE /zones/{zone_id} - Cleaned up test zone")
|
||||
passed += 1
|
||||
else:
|
||||
print(f"✗ DELETE /tabs/{tab_id} - Status: {response.status_code}")
|
||||
print(f"✗ DELETE /zones/{zone_id} - Status: {response.status_code}")
|
||||
else:
|
||||
print(f"✗ Failed to extract tab ID from create response")
|
||||
print(f"✗ Failed to extract zone ID from create response")
|
||||
else:
|
||||
print(f"✗ POST /tabs - Status: {response.status_code}, Response: {response.text}")
|
||||
print(f"✗ POST /zones - Status: {response.status_code}, Response: {response.text}")
|
||||
except Exception as e:
|
||||
print(f"✗ Tab edit workflow - Error: {e}")
|
||||
print(f"✗ Zone edit workflow - Error: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -505,7 +505,7 @@ def test_static_files(client: TestClient) -> bool:
|
||||
static_files = [
|
||||
'/static/style.css',
|
||||
'/static/app.js',
|
||||
'/static/tabs.js',
|
||||
'/static/zones.js',
|
||||
'/static/presets.js',
|
||||
'/static/profiles.js',
|
||||
'/static/devices.js',
|
||||
@@ -544,7 +544,7 @@ def main():
|
||||
|
||||
# Run all tests
|
||||
results.append(("Tabs", test_tabs(client)))
|
||||
results.append(("Tab Edit Workflow", test_tab_edit_workflow(client)))
|
||||
results.append(("Zone Edit Workflow", test_tab_edit_workflow(client)))
|
||||
results.append(("Profiles", test_profiles(client)))
|
||||
results.append(("Presets", test_presets(client)))
|
||||
results.append(("Patterns", test_patterns(client)))
|
||||
|
||||
@@ -119,7 +119,7 @@ def server(monkeypatch, tmp_path_factory):
|
||||
import models.preset as models_preset # noqa: E402
|
||||
import models.profile as models_profile # noqa: E402
|
||||
import models.group as models_group # noqa: E402
|
||||
import models.tab as models_tab # noqa: E402
|
||||
import models.zone as models_tab # noqa: E402
|
||||
import models.pallet as models_pallet # noqa: E402
|
||||
import models.scene as models_scene # noqa: E402
|
||||
import models.pattern as models_pattern # noqa: E402
|
||||
@@ -130,7 +130,7 @@ def server(monkeypatch, tmp_path_factory):
|
||||
models_preset.Preset,
|
||||
models_profile.Profile,
|
||||
models_group.Group,
|
||||
models_tab.Tab,
|
||||
models_tab.Zone,
|
||||
models_pallet.Palette,
|
||||
models_scene.Scene,
|
||||
models_pattern.Pattern,
|
||||
@@ -164,7 +164,7 @@ def server(monkeypatch, tmp_path_factory):
|
||||
"controllers.profile",
|
||||
"controllers.group",
|
||||
"controllers.sequence",
|
||||
"controllers.tab",
|
||||
"controllers.zone",
|
||||
"controllers.palette",
|
||||
"controllers.scene",
|
||||
"controllers.pattern",
|
||||
@@ -178,7 +178,7 @@ def server(monkeypatch, tmp_path_factory):
|
||||
import controllers.profile as profile_ctl # noqa: E402
|
||||
import controllers.group as group_ctl # noqa: E402
|
||||
import controllers.sequence as sequence_ctl # noqa: E402
|
||||
import controllers.tab as tab_ctl # noqa: E402
|
||||
import controllers.zone as zone_ctl # noqa: E402
|
||||
import controllers.palette as palette_ctl # noqa: E402
|
||||
import controllers.scene as scene_ctl # noqa: E402
|
||||
import controllers.pattern as pattern_ctl # noqa: E402
|
||||
@@ -205,7 +205,7 @@ def server(monkeypatch, tmp_path_factory):
|
||||
app.mount(profile_ctl.controller, "/profiles")
|
||||
app.mount(group_ctl.controller, "/groups")
|
||||
app.mount(sequence_ctl.controller, "/sequences")
|
||||
app.mount(tab_ctl.controller, "/tabs")
|
||||
app.mount(tab_ctl.controller, "/zones")
|
||||
app.mount(palette_ctl.controller, "/palettes")
|
||||
app.mount(scene_ctl.controller, "/scenes")
|
||||
app.mount(pattern_ctl.controller, "/patterns")
|
||||
@@ -424,45 +424,45 @@ def test_profiles_presets_tabs_endpoints(server, monkeypatch):
|
||||
assert resp.status_code == 404
|
||||
|
||||
# Tabs CRUD (scoped to current profile session).
|
||||
unique_tab_name = f"pytest-tab-{uuid.uuid4().hex[:8]}"
|
||||
unique_tab_name = f"pytest-zone-{uuid.uuid4().hex[:8]}"
|
||||
resp = c.post(
|
||||
f"{base_url}/tabs",
|
||||
f"{base_url}/zones",
|
||||
json={"name": unique_tab_name, "names": ["1", "2"]},
|
||||
)
|
||||
assert resp.status_code == 201
|
||||
created_tabs = resp.json()
|
||||
tab_id = next(iter(created_tabs.keys()))
|
||||
zone_id = next(iter(created_tabs.keys()))
|
||||
|
||||
resp = c.get(f"{base_url}/tabs/{tab_id}")
|
||||
resp = c.get(f"{base_url}/zones/{zone_id}")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["name"] == unique_tab_name
|
||||
|
||||
resp = c.post(f"{base_url}/tabs/{tab_id}/set-current")
|
||||
resp = c.post(f"{base_url}/zones/{zone_id}/set-current")
|
||||
assert resp.status_code == 200
|
||||
|
||||
resp = c.get(f"{base_url}/tabs/current")
|
||||
resp = c.get(f"{base_url}/zones/current")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["tab_id"] == str(tab_id)
|
||||
assert resp.json()["zone_id"] == str(zone_id)
|
||||
|
||||
resp = c.put(
|
||||
f"{base_url}/tabs/{tab_id}",
|
||||
f"{base_url}/zones/{zone_id}",
|
||||
json={"name": f"{unique_tab_name}-updated", "names": ["3"]},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["names"] == ["3"]
|
||||
|
||||
resp = c.post(f"{base_url}/tabs/{tab_id}/clone", json={"name": "pytest-tab-clone"})
|
||||
resp = c.post(f"{base_url}/zones/{zone_id}/clone", json={"name": "pytest-zone-clone"})
|
||||
assert resp.status_code == 201
|
||||
clone_payload = resp.json()
|
||||
clone_id = next(iter(clone_payload.keys()))
|
||||
|
||||
resp = c.get(f"{base_url}/tabs/{clone_id}")
|
||||
resp = c.get(f"{base_url}/zones/{clone_id}")
|
||||
assert resp.status_code == 200
|
||||
|
||||
resp = c.delete(f"{base_url}/tabs/{clone_id}")
|
||||
resp = c.delete(f"{base_url}/zones/{clone_id}")
|
||||
assert resp.status_code == 200
|
||||
|
||||
resp = c.delete(f"{base_url}/tabs/{tab_id}")
|
||||
resp = c.delete(f"{base_url}/zones/{zone_id}")
|
||||
assert resp.status_code == 200
|
||||
|
||||
# Profile clone + update endpoints.
|
||||
|
||||
Reference in New Issue
Block a user