135 lines
3.9 KiB
Python
135 lines
3.9 KiB
Python
"""Tests for BrowserState navigation stack and pagination."""
|
|
|
|
from r36s_dlna_browser.dlna.browser_state import BrowserState
|
|
from r36s_dlna_browser.dlna.models import MediaServer, MediaItem, ItemType
|
|
|
|
|
|
def _server(name: str = "TestServer") -> MediaServer:
|
|
return MediaServer(friendly_name=name, location=f"http://{name}:8080/desc.xml")
|
|
|
|
|
|
def _items(n: int, container: bool = False) -> list[MediaItem]:
|
|
t = ItemType.CONTAINER if container else ItemType.AUDIO
|
|
return [
|
|
MediaItem(
|
|
object_id=str(i),
|
|
title=f"Item {i}",
|
|
item_type=t,
|
|
resource_url="" if container else f"http://srv/file{i}.mp3",
|
|
)
|
|
for i in range(n)
|
|
]
|
|
|
|
|
|
class TestServerList:
|
|
def test_empty_initial(self):
|
|
s = BrowserState()
|
|
assert s.servers == []
|
|
assert s.selected_server is None
|
|
|
|
def test_set_servers(self):
|
|
s = BrowserState()
|
|
servers = [_server("A"), _server("B")]
|
|
s.set_servers(servers)
|
|
assert len(s.servers) == 2
|
|
assert s.server_cursor == 0
|
|
assert s.selected_server.friendly_name == "A"
|
|
|
|
def test_cursor_bounds(self):
|
|
s = BrowserState()
|
|
s.set_servers([_server("A"), _server("B"), _server("C")])
|
|
s.server_cursor = 2
|
|
assert s.selected_server.friendly_name == "C"
|
|
s.server_cursor = 5 # out of bounds
|
|
assert s.selected_server is None
|
|
|
|
|
|
class TestBrowseStack:
|
|
def test_not_in_browse_initially(self):
|
|
s = BrowserState()
|
|
assert not s.in_browse_mode
|
|
|
|
def test_enter_server(self):
|
|
s = BrowserState()
|
|
s.set_servers([_server()])
|
|
obj_id = s.enter_server(s.selected_server)
|
|
assert obj_id == "0"
|
|
assert s.in_browse_mode
|
|
assert s.current_level.object_id == "0"
|
|
|
|
def test_set_items_and_cursor(self):
|
|
s = BrowserState()
|
|
s.set_servers([_server()])
|
|
s.enter_server(s.selected_server)
|
|
items = _items(10)
|
|
s.set_items(items, "0")
|
|
assert len(s.current_items) == 10
|
|
assert s.cursor == 0
|
|
s.cursor = 3
|
|
assert s.cursor == 3
|
|
assert s.selected_item().title == "Item 3"
|
|
|
|
def test_cursor_clamps(self):
|
|
s = BrowserState()
|
|
s.set_servers([_server()])
|
|
s.enter_server(s.selected_server)
|
|
s.set_items(_items(5), "0")
|
|
s.cursor = 100
|
|
assert s.cursor == 4 # clamped to last
|
|
s.cursor = -5
|
|
assert s.cursor == 0
|
|
|
|
def test_push_and_pop(self):
|
|
s = BrowserState()
|
|
s.set_servers([_server()])
|
|
s.enter_server(s.selected_server)
|
|
s.set_items(_items(3, container=True), "0")
|
|
|
|
# Drill into child
|
|
s.set_items(_items(5), "1")
|
|
assert len(s.current_items) == 5
|
|
|
|
# Go back
|
|
assert s.go_back()
|
|
assert len(s.current_items) == 3
|
|
assert s.current_level.object_id == "0"
|
|
|
|
# Go back again exits browse
|
|
assert s.go_back()
|
|
assert not s.in_browse_mode
|
|
|
|
def test_go_back_at_root(self):
|
|
s = BrowserState()
|
|
assert not s.go_back()
|
|
|
|
def test_reset(self):
|
|
s = BrowserState()
|
|
s.set_servers([_server()])
|
|
s.enter_server(s.selected_server)
|
|
s.set_items(_items(5), "0")
|
|
s.error = "fail"
|
|
s.playback_title = "song"
|
|
s.playback_paused = True
|
|
s.reset()
|
|
assert not s.in_browse_mode
|
|
assert s.error == ""
|
|
assert s.playback_title == ""
|
|
assert not s.playback_paused
|
|
|
|
|
|
class TestScrollOffset:
|
|
def test_scroll_offset_default(self):
|
|
s = BrowserState()
|
|
s.set_servers([_server()])
|
|
s.enter_server(s.selected_server)
|
|
s.set_items(_items(3), "0")
|
|
assert s.scroll_offset == 0
|
|
|
|
def test_scroll_offset_set(self):
|
|
s = BrowserState()
|
|
s.set_servers([_server()])
|
|
s.enter_server(s.selected_server)
|
|
s.set_items(_items(30), "0")
|
|
s.scroll_offset = 10
|
|
assert s.scroll_offset == 10
|