diff --git a/csv2notion/notion_db.py b/csv2notion/notion_db.py index 4514de5..6b46bbf 100644 --- a/csv2notion/notion_db.py +++ b/csv2notion/notion_db.py @@ -120,7 +120,10 @@ def get_collection_id(client: NotionClientExtended, notion_url: str) -> str: raise NotionError("Invalid URL.") from e if block.type not in ["collection_view_page", "collection_view"]: - raise NotionError("Provided URL links does not point to a Notion database.") + raise NotionError("Provided URL does not point to a Notion database.") + + if block.collection.role not in {"editor", "content_only_editor"}: + raise NotionError("You must have editing permissions for Notion database.") return str(block.collection.id) diff --git a/tests/cassettes/test_read_only_url.yaml b/tests/cassettes/test_read_only_url.yaml new file mode 100644 index 0000000..1a5439e --- /dev/null +++ b/tests/cassettes/test_read_only_url.yaml @@ -0,0 +1,104 @@ +interactions: +- request: + body: '{}' + headers: + Content-Length: + - '2' + Content-Type: + - application/json + cookie: + - PRIVATE + method: POST + uri: https://www.notion.so/api/v3/loadUserContent + response: + body: + string: '{"recordMap":{"notion_user":{"a03b888f-5426-4e4f-b5ef-bed855b162f0":{"role":"editor","value":{"id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","version":7,"email":"test_py_notion@protonmail.com","onboarding_completed":true,"name":"test_py"}}},"user_root":{"a03b888f-5426-4e4f-b5ef-bed855b162f0":{"role":"editor","value":{"id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","version":3,"space_views":["703440cc-f5cb-4f27-ba54-a9125a58e033"],"space_view_pointers":[{"id":"703440cc-f5cb-4f27-ba54-a9125a58e033","table":"space_view","spaceId":"d51d3ca5-7889-4c70-b906-3a5a37b60274"}]}}},"user_settings":{"a03b888f-5426-4e4f-b5ef-bed855b162f0":{"role":"editor","value":{"id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","version":10,"settings":{"type":"personal","persona":"personal","team_role":"unfilled","time_zone":"Asia/Tashkent","signup_time":1638259864507,"cookie_consent":{"id":"2c2f9260-c9a6-4097-bc19-30e5395dfb02","permission":{"necessary":true,"targeting":false,"preference":false,"performance":false}},"preferred_locale":"en-US","used_desktop_web_app":true,"seen_views_intro_modal":true,"preferred_locale_origin":"autodetect","seen_persona_collection":true}}}},"space_view":{"703440cc-f5cb-4f27-ba54-a9125a58e033":{"role":"editor","value":{"id":"703440cc-f5cb-4f27-ba54-a9125a58e033","version":39,"space_id":"d51d3ca5-7889-4c70-b906-3a5a37b60274","parent_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","parent_table":"user_root","alive":true,"notify_mobile":false,"notify_desktop":true,"notify_email":false,"visited_templates":["7e89f436-7aac-4f66-b0a6-6e65ec868d2a","88c9c2b0-d732-4342-8963-0580a4725571","ba43b46e-4ad3-47f7-95f0-58a3ba01476f","2dddc8c5-a711-4aa2-b5b3-ff952a49bcfa","b7572331-51ab-4ed5-a931-5a7d34b08bf0"],"sidebar_hidden_templates":["7e89f436-7aac-4f66-b0a6-6e65ec868d2a","88c9c2b0-d732-4342-8963-0580a4725571","ba43b46e-4ad3-47f7-95f0-58a3ba01476f","2dddc8c5-a711-4aa2-b5b3-ff952a49bcfa","b7572331-51ab-4ed5-a931-5a7d34b08bf0"],"created_getting_started":true,"created_onboarding_templates":true,"private_pages":["aea9acad-4243-4c01-95ba-5dbcfc404713"],"joined":true,"settings":{"on_app_start":"first_page"}}}},"space":{"d51d3ca5-7889-4c70-b906-3a5a37b60274":{"role":"editor","value":{"id":"d51d3ca5-7889-4c70-b906-3a5a37b60274","version":6049,"name":"test_py","permissions":[{"role":"editor","type":"user_permission","user_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0"}],"beta_enabled":false,"created_time":1638259881592,"last_edited_time":1657343400000,"created_by_table":"notion_user","created_by_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","last_edited_by_table":"notion_user","last_edited_by_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","plan_type":"personal","invite_link_enabled":true,"subscription_tier":"personal_free"}}}}}' + headers: + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + content-length: + - '2730' + status: + code: 200 + message: OK +- request: + body: '{}' + headers: + Content-Length: + - '2' + Content-Type: + - application/json + cookie: + - PRIVATE + x-notion-active-user-header: + - a03b888f-5426-4e4f-b5ef-bed855b162f0 + method: POST + uri: https://www.notion.so/api/v3/loadUserContent + response: + body: + string: '{"recordMap":{"notion_user":{"a03b888f-5426-4e4f-b5ef-bed855b162f0":{"role":"editor","value":{"id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","version":7,"email":"test_py_notion@protonmail.com","onboarding_completed":true,"name":"test_py"}}},"user_settings":{"a03b888f-5426-4e4f-b5ef-bed855b162f0":{"role":"editor","value":{"id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","version":10,"settings":{"type":"personal","persona":"personal","team_role":"unfilled","time_zone":"Asia/Tashkent","signup_time":1638259864507,"cookie_consent":{"id":"2c2f9260-c9a6-4097-bc19-30e5395dfb02","permission":{"necessary":true,"targeting":false,"preference":false,"performance":false}},"preferred_locale":"en-US","used_desktop_web_app":true,"seen_views_intro_modal":true,"preferred_locale_origin":"autodetect","seen_persona_collection":true}}}},"user_root":{"a03b888f-5426-4e4f-b5ef-bed855b162f0":{"role":"editor","value":{"id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","version":3,"space_views":["703440cc-f5cb-4f27-ba54-a9125a58e033"],"space_view_pointers":[{"id":"703440cc-f5cb-4f27-ba54-a9125a58e033","table":"space_view","spaceId":"d51d3ca5-7889-4c70-b906-3a5a37b60274"}]}}},"space_view":{"703440cc-f5cb-4f27-ba54-a9125a58e033":{"role":"editor","value":{"id":"703440cc-f5cb-4f27-ba54-a9125a58e033","version":39,"space_id":"d51d3ca5-7889-4c70-b906-3a5a37b60274","parent_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","parent_table":"user_root","alive":true,"notify_mobile":false,"notify_desktop":true,"notify_email":false,"visited_templates":["7e89f436-7aac-4f66-b0a6-6e65ec868d2a","88c9c2b0-d732-4342-8963-0580a4725571","ba43b46e-4ad3-47f7-95f0-58a3ba01476f","2dddc8c5-a711-4aa2-b5b3-ff952a49bcfa","b7572331-51ab-4ed5-a931-5a7d34b08bf0"],"sidebar_hidden_templates":["7e89f436-7aac-4f66-b0a6-6e65ec868d2a","88c9c2b0-d732-4342-8963-0580a4725571","ba43b46e-4ad3-47f7-95f0-58a3ba01476f","2dddc8c5-a711-4aa2-b5b3-ff952a49bcfa","b7572331-51ab-4ed5-a931-5a7d34b08bf0"],"created_getting_started":true,"created_onboarding_templates":true,"private_pages":["aea9acad-4243-4c01-95ba-5dbcfc404713"],"joined":true,"settings":{"on_app_start":"first_page"}}}},"space":{"d51d3ca5-7889-4c70-b906-3a5a37b60274":{"role":"editor","value":{"id":"d51d3ca5-7889-4c70-b906-3a5a37b60274","version":6049,"name":"test_py","permissions":[{"role":"editor","type":"user_permission","user_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0"}],"beta_enabled":false,"created_time":1638259881592,"last_edited_time":1657343400000,"created_by_table":"notion_user","created_by_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","last_edited_by_table":"notion_user","last_edited_by_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","plan_type":"personal","invite_link_enabled":true,"subscription_tier":"personal_free"}}}}}' + headers: + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + content-length: + - '2730' + status: + code: 200 + message: OK +- request: + body: '{}' + headers: + Content-Length: + - '2' + Content-Type: + - application/json + cookie: + - PRIVATE + method: POST + uri: https://www.notion.so/api/v3/loadUserContent + response: + body: + string: '{"recordMap":{"notion_user":{"a03b888f-5426-4e4f-b5ef-bed855b162f0":{"role":"editor","value":{"id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","version":7,"email":"test_py_notion@protonmail.com","onboarding_completed":true,"name":"test_py"}}},"user_root":{"a03b888f-5426-4e4f-b5ef-bed855b162f0":{"role":"editor","value":{"id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","version":3,"space_views":["703440cc-f5cb-4f27-ba54-a9125a58e033"],"space_view_pointers":[{"id":"703440cc-f5cb-4f27-ba54-a9125a58e033","table":"space_view","spaceId":"d51d3ca5-7889-4c70-b906-3a5a37b60274"}]}}},"user_settings":{"a03b888f-5426-4e4f-b5ef-bed855b162f0":{"role":"editor","value":{"id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","version":10,"settings":{"type":"personal","persona":"personal","team_role":"unfilled","time_zone":"Asia/Tashkent","signup_time":1638259864507,"cookie_consent":{"id":"2c2f9260-c9a6-4097-bc19-30e5395dfb02","permission":{"necessary":true,"targeting":false,"preference":false,"performance":false}},"preferred_locale":"en-US","used_desktop_web_app":true,"seen_views_intro_modal":true,"preferred_locale_origin":"autodetect","seen_persona_collection":true}}}},"space_view":{"703440cc-f5cb-4f27-ba54-a9125a58e033":{"role":"editor","value":{"id":"703440cc-f5cb-4f27-ba54-a9125a58e033","version":39,"space_id":"d51d3ca5-7889-4c70-b906-3a5a37b60274","parent_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","parent_table":"user_root","alive":true,"notify_mobile":false,"notify_desktop":true,"notify_email":false,"visited_templates":["7e89f436-7aac-4f66-b0a6-6e65ec868d2a","88c9c2b0-d732-4342-8963-0580a4725571","ba43b46e-4ad3-47f7-95f0-58a3ba01476f","2dddc8c5-a711-4aa2-b5b3-ff952a49bcfa","b7572331-51ab-4ed5-a931-5a7d34b08bf0"],"sidebar_hidden_templates":["7e89f436-7aac-4f66-b0a6-6e65ec868d2a","88c9c2b0-d732-4342-8963-0580a4725571","ba43b46e-4ad3-47f7-95f0-58a3ba01476f","2dddc8c5-a711-4aa2-b5b3-ff952a49bcfa","b7572331-51ab-4ed5-a931-5a7d34b08bf0"],"created_getting_started":true,"created_onboarding_templates":true,"private_pages":["aea9acad-4243-4c01-95ba-5dbcfc404713"],"joined":true,"settings":{"on_app_start":"first_page"}}}},"space":{"d51d3ca5-7889-4c70-b906-3a5a37b60274":{"role":"editor","value":{"id":"d51d3ca5-7889-4c70-b906-3a5a37b60274","version":6049,"name":"test_py","permissions":[{"role":"editor","type":"user_permission","user_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0"}],"beta_enabled":false,"created_time":1638259881592,"last_edited_time":1657343400000,"created_by_table":"notion_user","created_by_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","last_edited_by_table":"notion_user","last_edited_by_id":"a03b888f-5426-4e4f-b5ef-bed855b162f0","plan_type":"personal","invite_link_enabled":true,"subscription_tier":"personal_free"}}}}}' + headers: + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + content-length: + - '2730' + status: + code: 200 + message: OK +- request: + body: '{"page": {"id": "70ffd895-eb19-47b1-8bda-9dacf535f67f"}, "limit": 100, + "cursor": {"stack": []}, "chunkNumber": 0, "verticalColumns": false}' + headers: + Content-Length: + - '139' + Content-Type: + - application/json + cookie: + - PRIVATE + x-notion-active-user-header: + - a03b888f-5426-4e4f-b5ef-bed855b162f0 + method: POST + uri: https://www.notion.so/api/v3/loadPageChunk + response: + body: + string: '{"cursor":{"stack":[]},"recordMap":{"block":{"70ffd895-eb19-47b1-8bda-9dacf535f67f":{"role":"reader","value":{"id":"70ffd895-eb19-47b1-8bda-9dacf535f67f","version":24,"type":"collection_view_page","view_ids":["c081db76-1527-4caa-9d90-e6e8609fcda8"],"collection_id":"49dad0eb-995a-47b5-8a12-bd9e51ad2190","format":{"collection_pointer":{"id":"49dad0eb-995a-47b5-8a12-bd9e51ad2190","table":"collection","spaceId":"513e2791-a137-425b-9fb1-175c9c90efc0"}},"permissions":[{"role":"reader","type":"public_permission","added_timestamp":1668429669428,"allow_duplicate":false}],"created_time":1668429664304,"last_edited_time":1668429660000,"parent_id":"23dec397-92f0-4fdc-9efa-7c654a908059","parent_table":"block","alive":true,"created_by_table":"notion_user","created_by_id":"dbc1277c-3e0f-42b5-8518-6936b754ffca","last_edited_by_table":"notion_user","last_edited_by_id":"dbc1277c-3e0f-42b5-8518-6936b754ffca","space_id":"513e2791-a137-425b-9fb1-175c9c90efc0"}}},"collection_view":{"c081db76-1527-4caa-9d90-e6e8609fcda8":{"role":"reader","value":{"id":"c081db76-1527-4caa-9d90-e6e8609fcda8","version":2,"type":"table","format":{"table_wrap":true,"table_properties":[{"width":276,"visible":true,"property":"title"},{"visible":true,"property":"WP_C"}],"collection_pointer":{"id":"49dad0eb-995a-47b5-8a12-bd9e51ad2190","table":"collection","spaceId":"513e2791-a137-425b-9fb1-175c9c90efc0"}},"parent_id":"70ffd895-eb19-47b1-8bda-9dacf535f67f","parent_table":"block","alive":true,"page_sort":["1deda22c-6e85-4f73-93d8-fd7ac7b80dc8","684a0498-8f1a-4187-87f4-db6579ee9cf7","3ee2de9c-459a-42a0-8ba6-dc6dfb543e83"],"space_id":"513e2791-a137-425b-9fb1-175c9c90efc0"}}},"collection":{"49dad0eb-995a-47b5-8a12-bd9e51ad2190":{"role":"reader","value":{"id":"49dad0eb-995a-47b5-8a12-bd9e51ad2190","version":1,"name":[["Read + Only DB"]],"schema":{"WP_C":{"name":"Tags","type":"multi_select"},"title":{"name":"Name","type":"title"}},"format":{"collection_page_properties":[{"visible":true,"property":"WP_C"}]},"parent_id":"70ffd895-eb19-47b1-8bda-9dacf535f67f","parent_table":"block","alive":true,"migrated":true,"space_id":"513e2791-a137-425b-9fb1-175c9c90efc0"}}},"space":{}}}' + headers: + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + content-length: + - '2152' + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_ops.py b/tests/test_ops.py index 3b7b1de..54648d4 100644 --- a/tests/test_ops.py +++ b/tests/test_ops.py @@ -90,7 +90,30 @@ def test_bad_url_type(tmp_path, db_maker): str(test_file), ) - assert "Provided URL links does not point to a Notion database" in str(e.value) + assert "Provided URL does not point to a Notion database" in str(e.value) + + +@pytest.mark.vcr() +@pytest.mark.usefixtures("vcr_uuid4") +def test_read_only_url(tmp_path, db_maker): + test_file = tmp_path / "test.csv" + test_file.write_text("a,b,c\na,b,c\n") + + read_only_url = ( + "https://www.notion.so/vzhd1701/70ffd895eb1947b18bda9dacf535f67f?" + "v=c081db7615274caa9d90e6e8609fcda8" + ) + + with pytest.raises(NotionError) as e: + cli( + "--token", + db_maker.token, + "--url", + read_only_url, + str(test_file), + ) + + assert "You must have editing permissions for Notion database" in str(e.value) @pytest.mark.vcr()