gabriel / musehub public
test_musehub_oembed.py python
232 lines 8.7 KB
cd448303 Initial extraction of MuseHub from maestro monorepo. Gabriel Cardona <gabriel@tellurstori.com> 7d ago
1 """Tests for the MuseHub oEmbed discovery endpoint.
2
3 Covers acceptance criteria (original) and (rich metadata):
4 - test_oembed_endpoint — GET /oembed returns valid JSON with HTML embed code
5 - test_oembed_unknown_url_404 — Invalid / unrecognised URL returns 404
6 - test_oembed_iframe_content — Returned HTML is an <iframe> pointing to embed route
7 - test_oembed_respects_maxwidth — maxwidth parameter is reflected in returned iframe width
8 - test_oembed_xml_format_501 — Non-JSON format returns 501
9 - test_oembed_musehub_extension_fields — Response includes all musehub:* extension fields
10 - test_oembed_standard_fields_complete — Response has all required standard oEmbed fields
11 - test_oembed_commit_endpoint — GET /oembed/commit returns 200 for commit URLs
12 - test_oembed_commit_unknown_url_404 — /oembed/commit returns 404 for non-commit URLs
13 - test_oembed_commit_iframe_uses_sha — /oembed/commit iframe src contains the commit SHA
14 - test_oembed_commit_xml_format_501 — /oembed/commit returns 501 for XML format
15
16 The /oembed and /oembed/commit endpoints require no auth — oEmbed consumers
17 (CMSes, blog platforms) call them without user credentials to discover embed metadata.
18 """
19 from __future__ import annotations
20
21 import pytest
22 from httpx import AsyncClient
23
24
25 @pytest.mark.anyio
26 async def test_oembed_endpoint(client: AsyncClient) -> None:
27 """GET /oembed with a valid embed URL returns 200 JSON with oEmbed fields."""
28 repo_id = "aaaabbbb-cccc-dddd-eeee-ffff00001111"
29 ref = "abc1234567890"
30 embed_url = f"/musehub/ui/{repo_id}/embed/{ref}"
31
32 response = await client.get(f"/oembed?url={embed_url}")
33 assert response.status_code == 200
34 assert "application/json" in response.headers["content-type"]
35
36 data = response.json()
37 assert data["version"] == "1.0"
38 assert data["type"] == "rich"
39 assert "title" in data
40 assert data["provider_name"] == "MuseHub"
41 assert "html" in data
42 assert isinstance(data["width"], int)
43 assert isinstance(data["height"], int)
44
45
46 @pytest.mark.anyio
47 async def test_oembed_unknown_url_404(client: AsyncClient) -> None:
48 """GET /oembed with a URL that doesn't match an embed pattern returns 404."""
49 response = await client.get("/oembed?url=https://example.com/not-musehub")
50 assert response.status_code == 404
51
52
53 @pytest.mark.anyio
54 async def test_oembed_iframe_content(client: AsyncClient) -> None:
55 """The HTML field returned by /oembed is an <iframe> pointing to the embed route."""
56 repo_id = "11112222-3333-4444-5555-666677778888"
57 ref = "deadbeef1234"
58 embed_url = f"/musehub/ui/{repo_id}/embed/{ref}"
59
60 response = await client.get(f"/oembed?url={embed_url}")
61 assert response.status_code == 200
62
63 html = response.json()["html"]
64 assert "<iframe" in html
65 assert f"/musehub/ui/{repo_id}/embed/{ref}" in html
66 assert "</iframe>" in html
67
68
69 @pytest.mark.anyio
70 async def test_oembed_respects_maxwidth(client: AsyncClient) -> None:
71 """maxwidth query parameter is reflected as the iframe width attribute."""
72 repo_id = "aaaabbbb-1111-2222-3333-ccccddddeeee"
73 ref = "cafebabe"
74 embed_url = f"/musehub/ui/{repo_id}/embed/{ref}"
75
76 response = await client.get(f"/oembed?url={embed_url}&maxwidth=400")
77 assert response.status_code == 200
78
79 data = response.json()
80 assert data["width"] == 400
81 assert 'width="400"' in data["html"]
82
83
84 @pytest.mark.anyio
85 async def test_oembed_xml_format_501(client: AsyncClient) -> None:
86 """Requesting XML format returns 501 Not Implemented."""
87 repo_id = "aaaabbbb-cccc-dddd-eeee-000011112222"
88 ref = "feedface"
89 embed_url = f"/musehub/ui/{repo_id}/embed/{ref}"
90
91 response = await client.get(f"/oembed?url={embed_url}&format=xml")
92 assert response.status_code == 501
93
94
95 @pytest.mark.anyio
96 async def test_oembed_no_auth_required(client: AsyncClient) -> None:
97 """oEmbed endpoint must not require a JWT — CMS platforms call it unauthenticated."""
98 repo_id = "bbbbcccc-dddd-eeee-ffff-000011112222"
99 ref = "aabbccdd"
100 embed_url = f"/musehub/ui/{repo_id}/embed/{ref}"
101
102 response = await client.get(f"/oembed?url={embed_url}")
103 assert response.status_code != 401
104 assert response.status_code == 200
105
106
107 @pytest.mark.anyio
108 async def test_oembed_title_contains_short_ref(client: AsyncClient) -> None:
109 """oEmbed title includes the first 8 characters of the ref for human readability."""
110 repo_id = "ccccdddd-eeee-ffff-0000-111122223333"
111 ref = "1234567890abcdef"
112 embed_url = f"/musehub/ui/{repo_id}/embed/{ref}"
113
114 response = await client.get(f"/oembed?url={embed_url}")
115 assert response.status_code == 200
116
117 data = response.json()
118 assert ref[:8] in data["title"]
119
120
121 @pytest.mark.anyio
122 async def test_oembed_musehub_extension_fields(client: AsyncClient) -> None:
123 """Response includes all musehub:* extension fields defined."""
124 repo_id = "ddddeeee-ffff-0000-1111-222233334444"
125 ref = "beefcafe1234"
126 embed_url = f"/musehub/ui/{repo_id}/embed/{ref}"
127
128 response = await client.get(f"/oembed?url={embed_url}")
129 assert response.status_code == 200
130
131 data = response.json()
132 # All musehub:* extension fields must be present (may be null if not yet resolved)
133 extension_fields = [
134 "musehub:key",
135 "musehub:tempo_bpm",
136 "musehub:time_signature",
137 "musehub:duration_beats",
138 "musehub:instruments",
139 "musehub:license",
140 "musehub:genre",
141 "musehub:commit_id",
142 "musehub:audio_url",
143 ]
144 for field in extension_fields:
145 assert field in data, f"Missing extension field: {field}"
146
147 # commit_id is always populated from the ref
148 assert data["musehub:commit_id"] == ref[:8]
149 # audio_url must be a string URL pointing to the render endpoint
150 assert isinstance(data["musehub:audio_url"], str)
151 assert repo_id in data["musehub:audio_url"]
152
153
154 @pytest.mark.anyio
155 async def test_oembed_standard_fields_complete(client: AsyncClient) -> None:
156 """Response contains the full set of standard oEmbed rich-type fields."""
157 repo_id = "eeeeffff-0000-1111-2222-333344445555"
158 ref = "d00dcafe"
159 embed_url = f"/musehub/ui/{repo_id}/embed/{ref}"
160
161 response = await client.get(f"/oembed?url={embed_url}")
162 assert response.status_code == 200
163
164 data = response.json()
165 required_fields = [
166 "version", "type", "title",
167 "provider_name", "provider_url",
168 "thumbnail_url", "thumbnail_width", "thumbnail_height",
169 "html", "width", "height",
170 ]
171 for field in required_fields:
172 assert field in data, f"Missing required oEmbed field: {field}"
173
174 assert data["provider_name"] == "MuseHub"
175 assert data["provider_url"] == "https://musehub.stori.app"
176 assert isinstance(data["thumbnail_width"], int)
177 assert isinstance(data["thumbnail_height"], int)
178 assert repo_id in data["thumbnail_url"]
179
180
181 @pytest.mark.anyio
182 async def test_oembed_commit_endpoint(client: AsyncClient) -> None:
183 """GET /oembed/commit returns 200 JSON for a valid commit URL."""
184 repo_id = "aaaabbbb-cccc-dddd-eeee-111122223333"
185 sha = "abc1234567890def"
186 commit_url = f"/musehub/ui/{repo_id}/commit/{sha}"
187
188 response = await client.get(f"/oembed/commit?url={commit_url}")
189 assert response.status_code == 200
190 assert "application/json" in response.headers["content-type"]
191
192 data = response.json()
193 assert data["version"] == "1.0"
194 assert data["type"] == "rich"
195 assert sha[:8] in data["title"]
196 assert data["provider_name"] == "MuseHub"
197 assert "html" in data
198 assert data["musehub:commit_id"] == sha[:8]
199
200
201 @pytest.mark.anyio
202 async def test_oembed_commit_unknown_url_404(client: AsyncClient) -> None:
203 """/oembed/commit returns 404 for a URL that doesn't match a commit pattern."""
204 response = await client.get("/oembed/commit?url=https://example.com/not-a-commit")
205 assert response.status_code == 404
206
207
208 @pytest.mark.anyio
209 async def test_oembed_commit_iframe_uses_sha(client: AsyncClient) -> None:
210 """The /oembed/commit endpoint's iframe src contains the commit SHA as the ref."""
211 repo_id = "bbbbcccc-dddd-eeee-ffff-111122223333"
212 sha = "deadbeefcafe0001"
213 commit_url = f"/musehub/ui/{repo_id}/commit/{sha}"
214
215 response = await client.get(f"/oembed/commit?url={commit_url}")
216 assert response.status_code == 200
217
218 html = response.json()["html"]
219 # The embed player uses the full SHA as the ref so the snapshot is pinned
220 assert sha in html
221 assert f"/musehub/ui/{repo_id}/embed/{sha}" in html
222
223
224 @pytest.mark.anyio
225 async def test_oembed_commit_xml_format_501(client: AsyncClient) -> None:
226 """/oembed/commit returns 501 for non-JSON format requests."""
227 repo_id = "ccccdddd-eeee-ffff-0000-111122223333"
228 sha = "cafebabe12345678"
229 commit_url = f"/musehub/ui/{repo_id}/commit/{sha}"
230
231 response = await client.get(f"/oembed/commit?url={commit_url}&format=xml")
232 assert response.status_code == 501