diff --git a/integ_tests/test_sharing.py b/integ_tests/test_sharing.py index 56439ec3..ecc667c9 100644 --- a/integ_tests/test_sharing.py +++ b/integ_tests/test_sharing.py @@ -48,7 +48,9 @@ def test_create_and_delete_share_by_key(page: Page, radicale_server: str) -> Non page.locator("tr[data-name='sharetokenrowtemplate']:not(.hidden)") ).to_have_count(1) expect( - page.locator("tr[data-name='sharetokenrowtemplate']:not(.hidden) span[data-name='ro']") + page.locator( + "tr[data-name='sharetokenrowtemplate']:not(.hidden) span[data-name='ro']" + ) ).to_be_visible() page.once("dialog", lambda dialog: dialog.accept()) page.click('tr:not(.hidden) button[data-name="delete"]', strict=True) @@ -62,7 +64,9 @@ def test_create_and_delete_share_by_key(page: Page, radicale_server: str) -> Non page.locator("tr[data-name='sharetokenrowtemplate']:not(.hidden)") ).to_have_count(1) expect( - page.locator("tr[data-name='sharetokenrowtemplate']:not(.hidden) span[data-name='rw']") + page.locator( + "tr[data-name='sharetokenrowtemplate']:not(.hidden) span[data-name='rw']" + ) ).to_be_visible() page.once("dialog", lambda dialog: dialog.accept()) page.click('tr:not(.hidden) button[data-name="delete"]', strict=True) @@ -89,7 +93,9 @@ def test_create_and_delete_share_by_map(page: Page, radicale_server: str) -> Non page.locator("tr[data-name='sharemaprowtemplate']:not(.hidden)") ).to_have_count(1) expect( - page.locator("tr[data-name='sharemaprowtemplate']:not(.hidden) span[data-name='ro']") + page.locator( + "tr[data-name='sharemaprowtemplate']:not(.hidden) span[data-name='ro']" + ) ).to_be_visible() page.once("dialog", lambda dialog: dialog.accept()) page.click('tr:not(.hidden) button[data-name="delete"]', strict=True) @@ -105,7 +111,9 @@ def test_create_and_delete_share_by_map(page: Page, radicale_server: str) -> Non page.locator("tr[data-name='sharemaprowtemplate']:not(.hidden)") ).to_have_count(1) expect( - page.locator("tr[data-name='sharemaprowtemplate']:not(.hidden) span[data-name='rw']") + page.locator( + "tr[data-name='sharemaprowtemplate']:not(.hidden) span[data-name='rw']" + ) ).to_be_visible() page.once("dialog", lambda dialog: dialog.accept()) page.click('tr:not(.hidden) button[data-name="delete"]', strict=True) @@ -196,7 +204,9 @@ def test_edit_share_by_token(page: Page, radicale_server: str) -> None: page.click('button[data-name="sharebytoken"]') page.click('#newshare button[data-name="submit"]') expect( - page.locator("tr[data-name='sharetokenrowtemplate']:not(.hidden) span[data-name='ro']") + page.locator( + "tr[data-name='sharetokenrowtemplate']:not(.hidden) span[data-name='ro']" + ) ).to_be_visible() # Edit to RW @@ -207,7 +217,9 @@ def test_edit_share_by_token(page: Page, radicale_server: str) -> None: # Verify RW expect( - page.locator("tr[data-name='sharetokenrowtemplate']:not(.hidden) span[data-name='rw']") + page.locator( + "tr[data-name='sharetokenrowtemplate']:not(.hidden) span[data-name='rw']" + ) ).to_be_visible() @@ -223,7 +235,9 @@ def test_edit_share_by_map(page: Page, radicale_server: str) -> None: page.locator('input[data-name="sharehref"]').fill("mapped") page.click('#newshare button[data-name="submit"]') expect( - page.locator("tr[data-name='sharemaprowtemplate']:not(.hidden) span[data-name='ro']") + page.locator( + "tr[data-name='sharemaprowtemplate']:not(.hidden) span[data-name='ro']" + ) ).to_be_visible() # Edit map share @@ -239,7 +253,9 @@ def test_edit_share_by_map(page: Page, radicale_server: str) -> None: # Verify changes expect( - page.locator("tr[data-name='sharemaprowtemplate']:not(.hidden) span[data-name='rw']") + page.locator( + "tr[data-name='sharemaprowtemplate']:not(.hidden) span[data-name='rw']" + ) ).to_be_visible() # If disabled, it might not show up or show differently, but our current UI doesn't visually distinguish enabled/disabled in the list yet # Let's verify by re-opening edit scene @@ -307,27 +323,81 @@ def test_incoming_shares(page: Page, radicale_server: str) -> None: # 4. Max sees the incoming share page.click('a[data-name="incomingshares"]') - expect(page.locator('#incomingsharingscene')).to_be_visible() + expect(page.locator("#incomingsharingscene")).to_be_visible() expect( page.locator("tr[data-name='incomingsharerowtemplate']:not(.hidden)") ).to_have_count(1) expect( - page.locator("tr[data-name='incomingsharerowtemplate']:not(.hidden) td[data-name='pathortoken']") - ).to_have_text("mapped") + page.locator( + "tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='pathortoken']" + ) + ).to_have_value("mapped") - # 5. Max makes changes to the hidden flag + # 5. Max enables and shows the share + # Initially, it's disabled and not shown (security by default) expect( - page.locator("tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='hidden']") - ).to_be_checked() - page.uncheck("tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='hidden']") - - expect( - page.locator("tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='hidden']") + page.locator( + "tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='enabled']" + ) ).not_to_be_checked() + expect( + page.locator( + "tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='shown']" + ) + ).not_to_be_checked() + expect( + page.locator( + "tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='shown']" + ) + ).to_be_disabled() + + # Enable it + page.check( + "tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='enabled']" + ) + expect( + page.locator( + "tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='shown']" + ) + ).not_to_be_disabled() + + # Show it + page.check( + "tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='shown']" + ) + expect( + page.locator( + "tr[data-name='incomingsharerowtemplate']:not(.hidden) input[data-name='shown']" + ) + ).to_be_checked() # 6. Assert no error was shown expect(page.locator('#incomingsharingscene span[data-name="error"]')).to_be_hidden() page.click('#incomingsharingscene button[data-name="cancel"]') - expect(page.locator('#incomingsharingscene')).to_be_hidden() + expect(page.locator("#incomingsharingscene")).to_be_hidden() + + +def test_no_incoming_shares_message(page: Page, radicale_server: str) -> None: + # 1. Max logs in + page.goto(radicale_server) + page.fill('#loginscene input[data-name="user"]', "max") + page.fill('#loginscene input[data-name="password"]', "maxpassword") + page.click('button:has-text("Next")') + + # 2. Max goes to incoming shares scene + page.click('a[data-name="incomingshares"]') + expect(page.locator("#incomingsharingscene")).to_be_visible() + + # 3. Verify that the table is hidden and the message is visible + expect(page.locator("#incomingsharingscene table")).to_be_hidden() + expect( + page.locator('#incomingsharingscene [data-name="nosharesmessage"]') + ).to_be_visible() + expect( + page.locator('#incomingsharingscene [data-name="nosharesmessage"]') + ).to_have_text("No incoming shares") + + page.click('#incomingsharingscene button[data-name="cancel"]') + expect(page.locator("#incomingsharingscene")).to_be_hidden() diff --git a/radicale/web/internal_data/index.html b/radicale/web/internal_data/index.html index 7d916373..02d32749 100644 --- a/radicale/web/internal_data/index.html +++ b/radicale/web/internal_data/index.html @@ -212,25 +212,28 @@
Manage shares that others have shared with you.
| + | - | rwro | +rwro | - | + |
No incoming shares
@@ -249,9 +252,9 @@