Files
wehub-resource-sync 09e9f3545f
Test / Code Quality (push) Has been cancelled
Test / Test (macos-latest, Python 3.10) (push) Has been cancelled
Test / Test (macos-latest, Python 3.11) (push) Has been cancelled
Test / Test (macos-latest, Python 3.12) (push) Has been cancelled
Test / Test (macos-latest, Python 3.13) (push) Has been cancelled
Test / Test (macos-latest, Python 3.14) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.10) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.11) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.12) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.13) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.14) (push) Has been cancelled
Test / Test (windows-latest, Python 3.10) (push) Has been cancelled
Test / Test (windows-latest, Python 3.11) (push) Has been cancelled
Test / Test (windows-latest, Python 3.12) (push) Has been cancelled
Test / Test (windows-latest, Python 3.13) (push) Has been cancelled
Test / Test (windows-latest, Python 3.14) (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
dependency-audit / pip-audit (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:30:13 +08:00

137 lines
4.8 KiB
Python

"""Sharing routes under /v1/notebooks/{id}/share."""
from __future__ import annotations
from fastapi.testclient import TestClient
from notebooklm._types.sharing import SharedUser
from notebooklm.rpc.types import SharePermission
from .fakes import FakeClient
def test_share_status_returns_current_state(
authed_client: TestClient, fake_client: FakeClient
) -> None:
fake_client.public_shares["nb-1"] = True
fake_client.shared_users["nb-1"] = {
"reader@example.com": SharedUser(
email="reader@example.com",
permission=SharePermission.VIEWER,
)
}
resp = authed_client.get("/v1/notebooks/nb-1/share")
assert resp.status_code == 200
body = resp.json()
assert body["notebook_id"] == "nb-1"
assert body["is_public"] is True
# Shared view: access/permission are string labels; view_level is omitted on
# the read path (the read RPC does not report it).
assert body["access"] == "anyone_with_link"
assert body["share_url"].endswith("/nb-1")
assert body["shared_users"][0]["email"] == "reader@example.com"
assert body["shared_users"][0]["permission"] == "viewer"
assert "view_level" not in body
def test_set_public_toggles_link(authed_client: TestClient) -> None:
resp = authed_client.post("/v1/notebooks/nb-1/share/public", json={"enable": True})
assert resp.status_code == 200
assert resp.json()["is_public"] is True
# Shared view labels the access enum (not a bare int).
assert resp.json()["access"] == "anyone_with_link"
resp = authed_client.post("/v1/notebooks/nb-1/share/public", json={"enable": False})
assert resp.status_code == 200
assert resp.json()["is_public"] is False
assert resp.json()["access"] == "restricted"
assert resp.json()["share_url"] is None
def test_add_update_and_remove_user(authed_client: TestClient, fake_client: FakeClient) -> None:
add = authed_client.post(
"/v1/notebooks/nb-1/share/users",
json={"email": "reader@example.com", "permission": "viewer", "notify": False},
)
assert add.status_code == 201
assert add.json() == {
"notebook_id": "nb-1",
"email": "reader@example.com",
"permission": "viewer",
"notify": False,
}
assert fake_client.shared_users["nb-1"]["reader@example.com"].permission == (
SharePermission.VIEWER
)
assert fake_client.last_share_notify is False
fake_client.last_share_notify = True
update = authed_client.patch(
"/v1/notebooks/nb-1/share/users/reader@example.com",
json={"permission": "editor"},
)
assert update.status_code == 200
assert update.json()["permission"] == "editor"
assert fake_client.shared_users["nb-1"]["reader@example.com"].permission == (
SharePermission.EDITOR
)
assert fake_client.last_share_notify is False
remove = authed_client.delete("/v1/notebooks/nb-1/share/users/reader@example.com")
assert remove.status_code == 204
assert "reader@example.com" not in fake_client.shared_users["nb-1"]
def test_add_user_notify_defaults_off(authed_client: TestClient, fake_client: FakeClient) -> None:
"""Omitting ``notify`` must NOT email the third party (default flipped to False)."""
resp = authed_client.post(
"/v1/notebooks/nb-1/share/users",
json={"email": "reader@example.com", "permission": "viewer"},
)
assert resp.status_code == 201
assert resp.json()["notify"] is False
assert fake_client.last_share_notify is False
def test_add_user_notify_opt_in(authed_client: TestClient, fake_client: FakeClient) -> None:
"""An explicit ``notify=true`` still emails."""
resp = authed_client.post(
"/v1/notebooks/nb-1/share/users",
json={"email": "reader@example.com", "permission": "viewer", "notify": True},
)
assert resp.status_code == 201
assert resp.json()["notify"] is True
assert fake_client.last_share_notify is True
def test_set_view_level(authed_client: TestClient) -> None:
resp = authed_client.post("/v1/notebooks/nb-1/share/view-level", json={"level": "chat"})
assert resp.status_code == 200
# set_view_level's return is authoritative, so view_level is surfaced (labeled).
assert resp.json()["view_level"] == "chat"
def test_share_rejects_bad_permission(authed_client: TestClient) -> None:
resp = authed_client.post(
"/v1/notebooks/nb-1/share/users",
json={"email": "reader@example.com", "permission": "owner"},
)
assert resp.status_code == 422
def test_share_routes_require_auth(raw_client: TestClient) -> None:
h = {"Host": "127.0.0.1"}
assert raw_client.get("/v1/notebooks/nb-1/share", headers=h).status_code == 401
assert (
raw_client.post(
"/v1/notebooks/nb-1/share/public", json={"enable": True}, headers=h
).status_code
== 401
)