-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- switch to rapid-api-client for youtube api/webapi - rework unit tests - better async fetch - rework api/proxy/web routers - keep only channel_id and @user - user names without @ are now deprecated
- Loading branch information
Showing
29 changed files
with
802 additions
and
626 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,63 @@ | ||
@base_url = http://localhost:8000 | ||
|
||
@channel_id = UCVooVnzQxPSTXTMzSi1s6uw | ||
|
||
######################################### | ||
## API | ||
######################################### | ||
|
||
### | ||
GET {{base_url}}/u/alice | ||
Authorization: Basic alice foo | ||
GET {{base_url}}/api/version | ||
|
||
|
||
######################################### | ||
## Youtube proxy | ||
######################################### | ||
|
||
### | ||
GET {{base_url}}/proxy/rss/UCVooVnzQxPSTXTMzSi1s6uw | ||
|
||
### | ||
GET {{base_url}}/proxy/avatar/UCVooVnzQxPSTXTMzSi1s6uw | ||
|
||
### | ||
GET {{base_url}}/proxy/home/UCVooVnzQxPSTXTMzSi1s6uw | ||
|
||
### | ||
GET {{base_url}}/proxy/rss/@jonnygiger | ||
|
||
### | ||
GET {{base_url}}/proxy/avatar/@jonnygiger | ||
|
||
### | ||
GET {{base_url}}/proxy/home/@jonnygiger | ||
|
||
|
||
|
||
######################################### | ||
## Frontend | ||
######################################### | ||
|
||
### Default page | ||
GET {{base_url}}/ | ||
|
||
### Error, wrong password | ||
GET {{base_url}}/u/alice | ||
Authorization: Basic alice bar | ||
|
||
### | ||
### Alice's homepage | ||
GET {{base_url}}/u/alice | ||
Authorization: Basic alice foo | ||
|
||
### Error, wrong password | ||
GET {{base_url}}/u/bob | ||
Authorization: Basic bob foo | ||
|
||
### | ||
### Bob's homepage | ||
GET {{base_url}}/u/bob | ||
Authorization: Basic bob bar | ||
|
||
### | ||
### Demo's homepage | ||
GET {{base_url}}/u/demo | ||
|
||
### | ||
GET {{base_url}}/api/rss/{{channel_id}} | ||
|
||
### | ||
GET {{base_url}}/api/avatar/{{channel_id}} | ||
### Watch single video | ||
GET {{base_url}}/watch?v=q5IMA244HXw |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,17 @@ | ||
import pytest_asyncio | ||
from fastapi.testclient import TestClient | ||
import pytest | ||
from httpx import ASGITransport, AsyncClient | ||
|
||
from yourss.main import app | ||
from yourss.youtube.client import YoutubeClient | ||
|
||
|
||
@pytest_asyncio.fixture | ||
async def yt_client(): | ||
yield YoutubeClient() | ||
@pytest.fixture | ||
def anyio_backend(): | ||
return "asyncio" | ||
|
||
|
||
@pytest_asyncio.fixture | ||
async def yourss_client(): | ||
yield TestClient(app) | ||
@pytest.fixture | ||
async def client(): | ||
async with AsyncClient( | ||
transport=ASGITransport(app=app), base_url="http://test", follow_redirects=False | ||
) as client: | ||
yield client |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,58 @@ | ||
from .test_youtube import CHANNEL_ID, SLUG, USER | ||
import re | ||
|
||
import pytest | ||
|
||
def test_version(yourss_client): | ||
resp = yourss_client.get("/api/version") | ||
resp.raise_for_status() | ||
|
||
|
||
def test_api_avatar_slug(yourss_client): | ||
resp = yourss_client.get(f"/api/avatar/{SLUG}", follow_redirects=False) | ||
assert 300 <= resp.status_code < 400 | ||
|
||
|
||
def test_api_avatar_channel(yourss_client): | ||
resp = yourss_client.get(f"/api/avatar/{CHANNEL_ID}", follow_redirects=False) | ||
assert 300 <= resp.status_code < 400 | ||
|
||
|
||
def test_api_avatar_user(yourss_client): | ||
resp = yourss_client.get(f"/api/avatar/{USER}", follow_redirects=False) | ||
assert 300 <= resp.status_code < 400 | ||
|
||
from yourss.main import app_name, app_version | ||
|
||
def test_api_rss_slug(yourss_client): | ||
resp = yourss_client.get(f"/api/rss/{SLUG}", follow_redirects=False) | ||
assert 300 <= resp.status_code < 400 | ||
|
||
|
||
def test_api_rss_channel(yourss_client): | ||
resp = yourss_client.get(f"/api/rss/{CHANNEL_ID}", follow_redirects=False) | ||
assert 300 <= resp.status_code < 400 | ||
|
||
|
||
def test_api_rss_user(yourss_client): | ||
resp = yourss_client.get(f"/api/rss/{USER}", follow_redirects=False) | ||
assert 300 <= resp.status_code < 400 | ||
|
||
|
||
def test_homepage(yourss_client): | ||
resp = yourss_client.get("/") | ||
assert resp.status_code == 200 | ||
|
||
@pytest.mark.anyio | ||
async def test_version(client): | ||
resp = await client.get("/api/version") | ||
resp.raise_for_status() | ||
|
||
def test_page(yourss_client): | ||
resp = yourss_client.get("/@jonnygiger") | ||
assert resp.status_code == 200 | ||
payload = resp.json() | ||
assert payload.get("name") == app_name | ||
assert payload.get("version") == app_version | ||
|
||
|
||
@pytest.mark.anyio | ||
async def test_proxy_rss(client): | ||
channel = await client.get("/proxy/rss/UCVooVnzQxPSTXTMzSi1s6uw") | ||
user = await client.get("/proxy/rss/@jonnygiger") | ||
playlist = await client.get("/proxy/rss/PLw-vK1_d04zZCal3yMX_T23h5nDJ2toTk") | ||
|
||
assert user.status_code == channel.status_code == playlist.status_code == 307 | ||
assert ( | ||
user.headers["Location"] | ||
== user.headers["Location"] | ||
== "https://www.youtube.com/feeds/videos.xml?channel_id=UCVooVnzQxPSTXTMzSi1s6uw" | ||
) | ||
assert ( | ||
playlist.headers["Location"] | ||
== "https://www.youtube.com/feeds/videos.xml?playlist_id=PLw-vK1_d04zZCal3yMX_T23h5nDJ2toTk" | ||
) | ||
|
||
|
||
@pytest.mark.anyio | ||
async def test_proxy_avatar(client): | ||
channel = await client.get("/proxy/avatar/UCVooVnzQxPSTXTMzSi1s6uw") | ||
user = await client.get("/proxy/avatar/@jonnygiger") | ||
|
||
assert user.status_code == channel.status_code == 307 | ||
assert user.headers["Location"] == user.headers["Location"] | ||
assert re.fullmatch( | ||
r"^https://yt[0-9]+\.googleusercontent\.com/.*$", user.headers["Location"] | ||
) | ||
|
||
|
||
@pytest.mark.anyio | ||
async def test_proxy_home(client): | ||
channel = await client.get("/proxy/home/UCVooVnzQxPSTXTMzSi1s6uw") | ||
user = await client.get("/proxy/home/@jonnygiger") | ||
|
||
assert user.status_code == channel.status_code == 307 | ||
assert ( | ||
user.headers["Location"] | ||
== user.headers["Location"] | ||
== "https://www.youtube.com/channel/UCVooVnzQxPSTXTMzSi1s6uw" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import pytest | ||
from httpx import BasicAuth | ||
|
||
from yourss.youtube.utils import bs_parse | ||
|
||
|
||
@pytest.mark.anyio | ||
async def test_default(client): | ||
resp = await client.get("/") | ||
assert resp.status_code == 307 | ||
assert resp.headers["Location"] == "/@CardMagicByJason" | ||
|
||
|
||
@pytest.mark.anyio | ||
async def test_watch(client): | ||
resp = await client.get("/watch?v=q5IMA244HXw") | ||
assert resp.status_code == 307 | ||
assert ( | ||
resp.headers["Location"] | ||
== "https://www.youtube-nocookie.com/embed/q5IMA244HXw?autoplay=1&control=2&rel=0" | ||
) | ||
|
||
|
||
@pytest.mark.anyio | ||
async def test_homepage(client): | ||
# Alice's password is bar | ||
resp = await client.get("/u/alice") | ||
assert resp.status_code == 401 | ||
|
||
resp = await client.get("/u/alice", auth=BasicAuth("4l1c3", "password")) | ||
assert resp.status_code == 401 | ||
|
||
resp = await client.get("/u/alice", auth=BasicAuth("alice", "password")) | ||
assert resp.status_code == 401 | ||
|
||
resp = await client.get("/u/alice", auth=BasicAuth("alice", "foo")) | ||
assert resp.status_code == 200 | ||
|
||
# Demo has no password | ||
resp = await client.get("/u/demo") | ||
assert resp.status_code == 200 | ||
|
||
# Unknown page | ||
resp = await client.get("/u/unknown") | ||
assert resp.status_code == 404 | ||
|
||
|
||
@pytest.mark.anyio | ||
async def test_page_content(client): | ||
names = [ | ||
"PLw-vK1_d04zZCal3yMX_T23h5nDJ2toTk", # a playlist | ||
"UCVooVnzQxPSTXTMzSi1s6uw", # a channel | ||
"@CardMagicByJason", # a user | ||
"@UCAAAAAAAAAAAAAAAAAAAAAA", # an unknown user | ||
"UCAAAAAAAAAAAAAAAAAAAAAA", # an invalid channel | ||
"foobar", # an invalid name | ||
] | ||
resp = await client.get("/" + ",".join(names)) | ||
assert resp.status_code == 200 | ||
|
||
soup = bs_parse(resp.text) | ||
assert len(soup.find_all("div", class_="yourss-filterable")) == 45 | ||
|
||
# when no valid feed given, should return 404 | ||
resp = await client.get("/UCAAAAAAAAAAAAAAAAAAAAAA,@UCAAAAAAAAAAAAAAAAAAAAAA") | ||
assert resp.status_code == 404 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.