Skip to content

Commit

Permalink
fix: Consider folder state for vfolder invitations (#2667)
Browse files Browse the repository at this point in the history
### TL;DR

This PR is about considers the state of the vfolder for vfolder invitations.

> This PR must be merged after the corresponding PR on the core side is merged. lablup/backend.ai#2780

### What changed?

- The basic logic of the webui is the same. However, I added logic to refresh the invitation on error.
- Added playwrite test code to test vfolder invitations. **All tests are performed against the Backend.AI core and webui initial installations**.

### How to test?

1. Navigate to the Core PR branch and apply the changes.
2. Run Playwrite test code, or test it yourself.

(if you're testing it yourself. It needs 2 browser)

1. Create a vfolder and invite other users to join.
2. Login as the invited user and verify that the invitation appears on the summary page.
3. Open the browser that sent the invite and move the vfolder to the trash.
4. Open the invited user's browser, accept the request, and verify that the invitation refreshes and displays the error.
---

<!--
Please precisely, concisely, and concretely describe what this PR changes, the rationale behind codes,
and how it affects the users and other developers.
-->

**Checklist:** (if applicable)

- [ ] Mention to the original issue
- [ ] Documentation
- [ ] Minium required manager version
- [ ] Specific setting for review (eg., KB link, endpoint or how to setup)
- [ ] Minimum requirements to check during review
- [ ] Test case(s) to demonstrate the difference of before/after
  • Loading branch information
ironAiken2 committed Sep 27, 2024
1 parent b5f174c commit 616b3ab
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 36 deletions.
4 changes: 3 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"wsproxy",
"vfolders",
"vfolder",
"filebrowser"
"filebrowser",
"vaadin",
"textbox"
],
"flagWords": [
"데이터레이크",
Expand Down
173 changes: 150 additions & 23 deletions e2e/vfolder.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import {
createVFolderAndVerify,
deleteVFolderAndVerify,
fillOutVaadinGridCellFilter,
loginAsUser,
loginAsUser2,
logout,
userInfo,
} from './test-util';
import { test, expect } from '@playwright/test';
import { createVFolderAndVerify, deleteVFolderAndVerify, fillOutVaadinGridCellFilter, loginAsUser, loginAsUser2, logout, userInfo } from './test-util';


test.describe('VFolder ', () => {
test('User can create and delete vFolder', async ({ page }) => {
Expand All @@ -11,46 +18,166 @@ test.describe('VFolder ', () => {
});
});

test.describe('VFolder sharing', ()=>{

test.describe('VFolder sharing', () => {
const sharingFolderName = 'e2e-test-folder-sharing';
test.beforeEach(async ({ page }) => {
await loginAsUser(page);
await createVFolderAndVerify(page, sharingFolderName);
});

test.afterEach(async ({ page }) => {
await logout(page);
await loginAsUser(page);
await deleteVFolderAndVerify(page, sharingFolderName);
});

test('User can share vFolder to User2. User2 can accept invitation', async ({ page }) => {
await page.locator("#general-folder-storage vaadin-grid-cell-content").filter({ hasText: sharingFolderName }).locator("//following-sibling::*[7]").getByRole('button', { name: 'share' }).click();
test('User can share vFolder to User2. User2 can accept invitation', async ({
page,
}) => {
await page
.locator('#general-folder-storage vaadin-grid-cell-content')
.filter({ hasText: sharingFolderName })
.locator('//following-sibling::*[7]')
.getByRole('button', { name: 'share' })
.click();
await page.getByRole('textbox', { name: 'Enter E-Mail address' }).click();
await page.getByRole('textbox', { name: 'Enter E-Mail address' }).fill('[email protected]');
// await page.getByRole('button', { name: 'add', exact: true }).click();
// await page.getByLabel('Enter E-Mail address').nth(1).click();
// await page.getByLabel('Enter E-Mail address').nth(1).fill('[email protected]');
await page.locator('#share-folder-dialog').locator('#share-button').getByLabel('share').click();
await page
.getByRole('textbox', { name: 'Enter E-Mail address' })
.fill('[email protected]');
await page
.locator('#share-folder-dialog')
.locator('#share-button')
.getByLabel('share')
.click();

await logout(page);
await loginAsUser2(page);

// click accept button in the invitation
await page.getByText(`From ${userInfo.user.email}`).locator('..').filter({ hasText: sharingFolderName }).getByRole('button', { name: 'accept' }).first().click();
await page
.getByText(`From ${userInfo.user.email}`)
.locator('..')
.filter({ hasText: sharingFolderName })
.getByRole('button', { name: 'accept' })
.first()
.click();
await page.getByRole('menuitem', { name: 'Data & Storage' }).click();
await page.waitForTimeout(1000);

await fillOutVaadinGridCellFilter(page.locator("#general-folder-storage"), 'Name', sharingFolderName);

await page.locator("#general-folder-storage vaadin-grid-cell-content").filter({ hasText: sharingFolderName }).locator("//following-sibling::*[7]").getByLabel('remove_circle').click();

await fillOutVaadinGridCellFilter(
page.locator('#general-folder-storage'),
'Name',
sharingFolderName,
);

await page
.locator('#general-folder-storage vaadin-grid-cell-content')
.filter({ hasText: sharingFolderName })
.locator('//following-sibling::*[7]')
.getByLabel('remove_circle')
.click();
await page.getByLabel('Type folder name to leave').click();
await page.getByLabel('Type folder name to leave').fill(sharingFolderName);
await page.getByRole('button', { name: 'Leave' }).click();

await page.waitForTimeout(1000);
// check disappeared
await expect(page.locator("#general-folder-storage vaadin-grid-cell-content").filter({ hasText: sharingFolderName }).first()).toBeHidden();
await expect(
page
.locator('#general-folder-storage vaadin-grid-cell-content')
.filter({ hasText: sharingFolderName })
.first(),
).toBeHidden();

await logout(page);
await loginAsUser(page);
await deleteVFolderAndVerify(page, sharingFolderName);
});

test('User2 can not see the invitation if User deleted the folder you shared.', async ({
page,
}) => {
await page
.locator('#general-folder-storage vaadin-grid-cell-content')
.filter({ hasText: sharingFolderName })
.locator('//following-sibling::*[7]')
.getByRole('button', { name: 'share' })
.click();
await page.getByRole('textbox', { name: 'Enter E-Mail address' }).click();
await page
.getByRole('textbox', { name: 'Enter E-Mail address' })
.fill('[email protected]');
await page
.locator('#share-folder-dialog')
.locator('#share-button')
.getByLabel('share')
.click();

await logout(page);
await loginAsUser2(page);

// check the invitation is sent to User2
await expect(
page
.getByText(`From ${userInfo.user.email}`)
.locator('..')
.filter({ hasText: sharingFolderName }),
).toBeVisible();

await logout(page);
await loginAsUser(page);
await deleteVFolderAndVerify(page, sharingFolderName);

// check the invitation is disappeared
await logout(page);
await loginAsUser2(page);
await expect(
page
.getByText(`From ${userInfo.user.email}`)
.locator('..')
.filter({ hasText: sharingFolderName }),
).toBeHidden();
});

test('User2 can see the invitation but can not accept if User deleted the folder when User2 is trying to accept.', async ({
page,
browser,
}) => {
await page
.locator('#general-folder-storage vaadin-grid-cell-content')
.filter({ hasText: sharingFolderName })
.locator('//following-sibling::*[7]')
.getByRole('button', { name: 'share' })
.click();
await page.getByRole('textbox', { name: 'Enter E-Mail address' }).click();
await page
.getByRole('textbox', { name: 'Enter E-Mail address' })
.fill('[email protected]');
await page
.locator('#share-folder-dialog')
.locator('#share-button')
.getByLabel('share')
.click();

// check the invitation is sent to User2
const page2 = await browser.newPage();
await loginAsUser2(page2);
await expect(
page2
.getByText(`From ${userInfo.user.email}`)
.locator('..')
.filter({ hasText: sharingFolderName }),
).toBeVisible();

// User delete the folder when User2 is trying to accept
await deleteVFolderAndVerify(page, sharingFolderName);

// User2 accept the invitation
await page2
.getByText(`From ${userInfo.user.email}`)
.locator('..')
.filter({ hasText: sharingFolderName })
.getByRole('button', { name: 'accept' })
.first()
.click();
await expect(
page2
.locator('.ant-notification-notice')
.filter({ hasText: 'No such vfolder invitation' }),
).toBeVisible();
});
});
16 changes: 4 additions & 12 deletions src/components/backend-ai-summary-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,16 +408,12 @@ export default class BackendAISummary extends BackendAIPage {
this.notification.text =
_text('summary.AcceptSharedVFolder') + `${invitation.vfolder_name}`;
this.notification.show();
this._refreshInvitations();
} catch (err) {
panel.setAttribute('disabled', 'false');
panel.querySelectorAll('mwc-button').forEach((btn) => {
btn.setAttribute('disabled', 'false');
});
this.notification.text = PainKiller.relieve(err.title);
this.notification.detail = err.message;
this.notification.show(true, err);
}
this._refreshInvitations();
}

/**
Expand All @@ -441,16 +437,12 @@ export default class BackendAISummary extends BackendAIPage {
this.notification.text =
_text('summary.DeclineSharedVFolder') + `${invitation.vfolder_name}`;
this.notification.show();
this._refreshInvitations();
} catch (err) {
panel.setAttribute('disabled', 'false');
panel.querySelectorAll('mwc-button').forEach((btn) => {
btn.setAttribute('disabled', 'false');
});
this.notification.text = PainKiller.relieve(err.title);
this.notification.detail = err.message;
this.notification.show(true, err);
}
this._refreshInvitations();
}

_stripHTMLTags(str) {
Expand Down Expand Up @@ -597,10 +589,10 @@ export default class BackendAISummary extends BackendAIPage {
<h3 style="padding-top:10px;">
From ${invitation.inviter}
</h3>
<span class="invitation_folder_name">
<div class="invitation_folder_name">
${_t('summary.FolderName')}:
${invitation.vfolder_name}
</span>
</div>
<div class="horizontal center layout">
${_t('summary.Permission')}:
${[...invitation.perm].map(
Expand Down

0 comments on commit 616b3ab

Please sign in to comment.