You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
3.9 KiB
134 lines
3.9 KiB
"""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
|
|
|