diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-29 11:15:54 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-29 11:15:54 +0200 |
| commit | b7733e812fadd6007976d262bd1d793572a36ba7 (patch) | |
| tree | 52e2ac07c9ba4929fa50b6ba8d19f94f86e8b304 /packages/meshbay-node/tests/test_musicbrainz.py | |
| parent | 09a007937f03fad04a390323f3817f1ae7d7c2a9 (diff) | |
| download | meshbay-b7733e812fadd6007976d262bd1d793572a36ba7.tar.gz | |
feat: node workflow redesign — wizard auto-config, reset, MusicBrainz contact
Wizard (Electron):
- Auto-provisions node config (hub URL + username) from logged-in user
- node:start handles both cold start and restart of misconfigured daemon
- Waits for daemon to reach 'running', auto-links node key on hub
- probeNode accepts intermediate states for wizard progress feedback
Reset (meshbay-node reset):
- Unlinks node key from hub (DELETE /me/node_key, best-effort)
- Stops and disables daemon (systemctl --user disable --now)
- Erases ~/.config/meshbay, ~/.local/share/meshbay, ~/.local/state/meshbay
MusicBrainz contact:
- Resolved from owner's hub email instead of per-node roster config
- Removed musicbrainz_contact UI and WebRTC handshake field
- Removed set_musicbrainz_contact/musicbrainz_contact from roster
Node pairing:
- Added operator pairing banner on NodePage
- Added operator_paired flag to list_groups
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/tests/test_musicbrainz.py')
| -rw-r--r-- | packages/meshbay-node/tests/test_musicbrainz.py | 33 |
1 files changed, 12 insertions, 21 deletions
diff --git a/packages/meshbay-node/tests/test_musicbrainz.py b/packages/meshbay-node/tests/test_musicbrainz.py index 4d075d3..843a691 100644 --- a/packages/meshbay-node/tests/test_musicbrainz.py +++ b/packages/meshbay-node/tests/test_musicbrainz.py @@ -7,14 +7,6 @@ import pytest from meshbay_node.musicbrainz import _MIN_INTERVAL_SECS, MusicBrainzClient, _escape_lucene -class FakeRoster: - def __init__(self, contact: str | None = "operator@example.invalid"): - self._contact = contact - - async def musicbrainz_contact(self): - return self._contact - - def _handler(response_map): def handle(request: httpx.Request) -> httpx.Response: path = request.url.path @@ -30,7 +22,7 @@ async def test_search_release_returns_top_result_and_confidence(): body = {"releases": [{"id": "abc-123", "title": "The Great Album", "artist-credit": [{"name": "Some Artist"}]}]} client = MusicBrainzClient( - roster=FakeRoster(), + owner_email="operator@example.invalid", transport=httpx.MockTransport(_handler({"release": body})), ) result, ratio = await client.search_release("Some Artist", "The Great Album") @@ -44,7 +36,7 @@ async def test_search_release_returns_top_result_and_confidence(): @pytest.mark.asyncio async def test_no_results_returns_none_and_zero_confidence(): client = MusicBrainzClient( - roster=FakeRoster(), + owner_email="operator@example.invalid", transport=httpx.MockTransport(_handler({"release": {"releases": []}})), ) result, ratio = await client.search_release("Nobody", "Nonexistent Obscure Album") @@ -80,7 +72,7 @@ async def test_strict_match_does_not_pay_for_a_second_request(): }) client = MusicBrainzClient( - roster=FakeRoster(), + owner_email="operator@example.invalid", transport=httpx.MockTransport(handle), ) await client.search_release("Some Artist", "The Great Album") @@ -112,7 +104,7 @@ async def test_falls_back_to_a_loose_query_when_the_strict_one_finds_nothing(): }) client = MusicBrainzClient( - roster=FakeRoster(), + owner_email="operator@example.invalid", transport=httpx.MockTransport(handle), ) result, ratio = await client.search_release("Groundation", "Hebron Gate (2003)") @@ -139,7 +131,7 @@ async def test_confidence_reflects_a_wrong_artist_on_a_same_titled_release(): }) client = MusicBrainzClient( - roster=FakeRoster(), + owner_email="operator@example.invalid", transport=httpx.MockTransport(handle), ) result, ratio = await client.search_release("Groundation", "Live") @@ -150,8 +142,7 @@ async def test_confidence_reflects_a_wrong_artist_on_a_same_titled_release(): @pytest.mark.asyncio -async def test_no_contact_configured_makes_no_request(monkeypatch): - monkeypatch.delenv("MESHBAY_MUSICBRAINZ_CONTACT_DEFAULT", raising=False) +async def test_no_contact_configured_makes_no_request(): calls = [] def handle(request: httpx.Request) -> httpx.Response: @@ -159,7 +150,7 @@ async def test_no_contact_configured_makes_no_request(monkeypatch): return httpx.Response(200, json={"releases": []}) client = MusicBrainzClient( - roster=FakeRoster(contact=None), + owner_email="", transport=httpx.MockTransport(handle), ) result, ratio = await client.search_release("Anyone", "Anything") @@ -178,7 +169,7 @@ async def test_the_configured_contact_is_sent_as_user_agent(): return httpx.Response(200, json={"releases": []}) client = MusicBrainzClient( - roster=FakeRoster(contact="operator@example.invalid"), + owner_email="operator@example.invalid", transport=httpx.MockTransport(handle), ) await client.search_release("Anyone", "Anything") @@ -193,7 +184,7 @@ async def test_http_error_returns_none_gracefully(): return httpx.Response(500, json={"error": "server error"}) client = MusicBrainzClient( - roster=FakeRoster(), + owner_email="operator@example.invalid", transport=httpx.MockTransport(handle), ) result, ratio = await client.search_release("Anyone", "Anything") @@ -209,7 +200,7 @@ async def test_cover_art_missing_returns_none_not_an_error(): return httpx.Response(404) client = MusicBrainzClient( - roster=FakeRoster(), + owner_email="operator@example.invalid", transport=httpx.MockTransport(handle), ) content = await client.fetch_cover_art("abc-123") @@ -224,7 +215,7 @@ async def test_cover_art_found_returns_bytes(): return httpx.Response(200, content=b"\xff\xd8fake-jpeg-bytes") client = MusicBrainzClient( - roster=FakeRoster(), + owner_email="operator@example.invalid", transport=httpx.MockTransport(handle), ) content = await client.fetch_cover_art("abc-123") @@ -245,7 +236,7 @@ async def test_calls_are_paced_at_least_min_interval_apart(): return httpx.Response(200, json={"releases": []}) client = MusicBrainzClient( - roster=FakeRoster(), + owner_email="operator@example.invalid", transport=httpx.MockTransport(handle), ) start = time.monotonic() |