From 65ea828c307b20a943c6e790d2736e880bfea032 Mon Sep 17 00:00:00 2001 From: Kim Lan Phan Hoang Date: Tue, 7 May 2024 15:35:58 +0200 Subject: [PATCH] feat: use packed item (#1140) * feat: use packed, remove shared item route * refactor: remove tags refactor: update tests test: update tests refactor: fix tests refactor: fix tests refactor: fix tests refactor: refactor test fix(test): update flacky tags and viewLink tests fix(test): update itemSettings and thumbnail test fix(test): remove not checked test in Analytics for item settings fix(test): remove only in itemSettings test fix(test): remove WS test of deleted WS events feat: upgrade deps fix: fix issues during rebase fix(test): update path of THUMBNAIL_MEDIUM_PATH * fix: pass item id to LinkItem of new UI version feat: update deps feat: remove only in tests feat: remove only * fix(test): add hasThumbnail setting in viewThumbnails test to fix flacky test * fix(test): add public tag in items to fix public and published tests --------- Co-authored-by: Thibault Reidy --- cypress/e2e/authentication.cy.ts | 45 +- .../e2e/invitations/createInvitation.cy.ts | 35 +- cypress/e2e/invitations/viewInvitation.cy.ts | 2 +- cypress/e2e/item/apps/apps.cy.ts | 16 +- .../bookmarks.cy.ts} | 34 +- cypress/e2e/item/chatbox/chatbox.cy.ts | 14 +- cypress/e2e/item/copy/gridCopyItem.cy.ts | 41 +- cypress/e2e/item/copy/listCopyItem.cy.ts | 37 +- cypress/e2e/item/copy/listCopyMultiple.cy.ts | 42 +- cypress/e2e/item/create/createApp.cy.ts | 13 +- cypress/e2e/item/create/createDocument.cy.ts | 32 +- cypress/e2e/item/create/createFolder.cy.ts | 36 +- cypress/e2e/item/create/createLink.cy.ts | 14 +- cypress/e2e/item/create/createShortcut.cy.ts | 78 +- cypress/e2e/item/create/importZip.cy.ts | 15 +- cypress/e2e/item/delete/gridRecycleItem.cy.ts | 17 +- cypress/e2e/item/delete/listDeleteItem.cy.ts | 14 +- cypress/e2e/item/delete/listDeleteItems.cy.ts | 13 +- cypress/e2e/item/delete/listRecycleItem.cy.ts | 20 +- .../e2e/item/delete/listRecycleItems.cy.ts | 23 +- cypress/e2e/item/delete/listRestoreItem.cy.ts | 26 +- cypress/e2e/item/download/downloadItem.cy.ts | 50 +- .../e2e/item/duplicate/duplicateItem.cy.ts | 16 +- cypress/e2e/item/edit/editApp.cy.ts | 69 +- cypress/e2e/item/edit/editDocument.cy.ts | 54 +- cypress/e2e/item/edit/editEtherpad.cy.ts | 10 +- cypress/e2e/item/edit/editFile.cy.ts | 42 +- cypress/e2e/item/edit/editFolder.cy.ts | 80 +- cypress/e2e/item/edit/editH5p.cy.ts | 10 +- cypress/e2e/item/edit/editLink.cy.ts | 24 +- cypress/e2e/item/edit/editShortcut.cy.ts | 12 +- cypress/e2e/item/flag/flagItem.cy.ts | 11 +- cypress/e2e/item/hide/hideItem.cy.ts | 65 +- cypress/e2e/item/home/home.cy.ts | 46 +- cypress/e2e/item/move/gridMoveItem.cy.ts | 35 +- cypress/e2e/item/move/listMoveItem.cy.ts | 49 +- cypress/e2e/item/move/listMoveMultiple.cy.ts | 44 +- cypress/e2e/item/order/reorderItems.cy.ts | 29 +- cypress/e2e/item/pin/pinItem.cy.ts | 24 +- cypress/e2e/item/publish/ccLicense.cy.ts | 100 ++- .../e2e/item/publish/coEditorSettings.cy.ts | 12 +- cypress/e2e/item/publish/publishedItem.cy.ts | 22 +- cypress/e2e/item/publish/tags.cy.ts | 62 +- cypress/e2e/item/settings/itemSettings.cy.ts | 240 +++-- cypress/e2e/item/settings/thumbnail.cy.ts | 25 +- cypress/e2e/item/share/changeVisibility.cy.ts | 37 +- cypress/e2e/item/share/itemLogin.cy.ts | 102 ++- cypress/e2e/item/share/publicItems.cy.ts | 12 +- cypress/e2e/item/share/shareItemFromCsv.cy.ts | 23 +- cypress/e2e/item/share/shortLink.cy.ts | 37 +- cypress/e2e/item/upload/dropzoneUpload.cy.ts | 9 +- cypress/e2e/item/upload/gridItemUpload.cy.ts | 80 -- cypress/e2e/item/upload/listItemUpload.cy.ts | 82 -- cypress/e2e/item/view/viewDocument.cy.ts | 13 +- cypress/e2e/item/view/viewFolder.cy.ts | 67 +- cypress/e2e/item/view/viewThumbnails.cy.ts | 51 +- .../memberships/createItemMembership.cy.ts | 41 +- .../e2e/memberships/editItemMembership.cy.ts | 5 +- cypress/e2e/memberships/viewMemberships.cy.ts | 2 +- cypress/e2e/redirection.cy.ts | 6 +- cypress/e2e/ws/item.cy.ts | 144 --- cypress/fixtures/apps.ts | 77 +- cypress/fixtures/chatbox.ts | 6 +- cypress/fixtures/documents.ts | 71 -- cypress/fixtures/etherpad.ts | 24 - cypress/fixtures/h5p.ts | 23 - cypress/fixtures/invitations.ts | 54 +- cypress/fixtures/items.ts | 819 +----------------- cypress/fixtures/links.ts | 75 +- cypress/fixtures/memberships.ts | 37 +- cypress/fixtures/sharedItems.ts | 65 -- cypress/fixtures/thumbnails.ts | 116 --- cypress/fixtures/thumbnails/links.ts | 2 + cypress/support/actionsUtils.ts | 3 + cypress/support/constants.ts | 2 +- cypress/support/editUtils.ts | 2 + cypress/support/server.ts | 29 +- cypress/support/types.ts | 3 + cypress/support/viewUtils.ts | 9 +- package.json | 4 +- src/components/App.tsx | 7 - src/components/common/Chatbox.tsx | 8 +- src/components/common/HideButton.tsx | 11 +- src/components/common/MoveButton.tsx | 7 +- src/components/item/ItemContent.tsx | 1 + src/components/item/ItemMain.tsx | 4 +- .../item/header/ItemHeaderActions.tsx | 10 +- .../item/publish/ItemPublishButton.tsx | 1 - .../item/publish/ItemPublishTab.tsx | 36 +- .../item/settings/AdminChatSettings.tsx | 12 +- .../item/settings/LanguageSelect.tsx | 10 +- .../sharing/ItemLoginMembershipsTable.tsx | 51 ++ .../item/sharing/ItemMembershipsTable.tsx | 3 + .../item/sharing/ItemSharingTab.tsx | 85 +- .../item/sharing/VisibilitySelect.tsx | 194 +++-- src/components/main/ItemCard.tsx | 18 +- src/components/main/ItemMenu.tsx | 9 +- src/components/main/Items.tsx | 17 +- src/components/main/ItemsGrid.tsx | 17 +- src/components/main/ItemsTable.tsx | 16 +- src/components/main/MainMenu.tsx | 15 +- .../itemSelectionModal/ItemSelectionModal.tsx | 1 - .../itemSelectionModal/RootNavigationTree.tsx | 5 +- src/components/pages/RecycledItemsScreen.tsx | 1 - src/components/pages/SharedItemsScreen.tsx | 65 -- .../pages/item/ItemScreenLayout.tsx | 23 +- src/components/pages/item/type.ts | 5 +- src/components/table/ActionsCellRenderer.tsx | 21 +- src/components/table/BadgesCellRenderer.tsx | 12 +- src/config/paths.ts | 1 - src/hooks/authorization.ts | 42 - src/utils/itemTag.ts | 7 - src/utils/membership.ts | 30 +- yarn.lock | 60 +- 114 files changed, 1796 insertions(+), 2839 deletions(-) rename cypress/e2e/item/{favorite/favoriteItem.cy.ts => bookmarks/bookmarks.cy.ts} (74%) delete mode 100644 cypress/e2e/item/upload/gridItemUpload.cy.ts delete mode 100644 cypress/e2e/item/upload/listItemUpload.cy.ts delete mode 100644 cypress/e2e/ws/item.cy.ts delete mode 100644 cypress/fixtures/documents.ts delete mode 100644 cypress/fixtures/etherpad.ts delete mode 100644 cypress/fixtures/h5p.ts delete mode 100644 cypress/fixtures/sharedItems.ts delete mode 100644 cypress/fixtures/thumbnails.ts create mode 100644 src/components/item/sharing/ItemLoginMembershipsTable.tsx delete mode 100644 src/components/pages/SharedItemsScreen.tsx delete mode 100644 src/hooks/authorization.ts delete mode 100644 src/utils/itemTag.ts diff --git a/cypress/e2e/authentication.cy.ts b/cypress/e2e/authentication.cy.ts index 4e1b908f9..e2d2ac1fe 100644 --- a/cypress/e2e/authentication.cy.ts +++ b/cypress/e2e/authentication.cy.ts @@ -1,18 +1,12 @@ -import { CookieKeys } from '@graasp/sdk'; +import { CookieKeys, PackedFolderItemFactory } from '@graasp/sdk'; import { HOME_PATH, ITEMS_PATH, REDIRECT_PATH, - SHARED_ITEMS_PATH, buildItemPath, } from '../../src/config/paths'; -import { - CREATE_ITEM_BUTTON_ID, - HEADER_APP_BAR_ID, - ITEM_MAIN_CLASS, -} from '../../src/config/selectors'; -import { SAMPLE_ITEMS } from '../fixtures/items'; +import { HEADER_APP_BAR_ID, ITEM_MAIN_CLASS } from '../../src/config/selectors'; import { REDIRECTION_TIME, REQUEST_FAILURE_LOADING_TIME, @@ -22,7 +16,7 @@ import { SIGN_IN_PATH } from '../support/paths'; describe('Authentication', () => { describe('Signed Off > Redirect to sign in route', () => { beforeEach(() => { - cy.setUpApi({ ...SAMPLE_ITEMS, currentMember: null }); + cy.setUpApi({ currentMember: null }); }); it('Home', () => { cy.visit(HOME_PATH); @@ -31,18 +25,13 @@ describe('Authentication', () => { timeout: REQUEST_FAILURE_LOADING_TIME, }).should('have.property', 'value', HOME_PATH); }); - it('Shared Items', () => { - cy.visit(SHARED_ITEMS_PATH); - cy.url().should('include', SIGN_IN_PATH); - cy.getCookie(CookieKeys.RedirectUrl, { - timeout: REQUEST_FAILURE_LOADING_TIME, - }).should('have.property', 'value', SHARED_ITEMS_PATH); - }); }); describe('Signed In', () => { + const ENV = { items: [PackedFolderItemFactory()] }; + beforeEach(() => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi(ENV); }); describe('Load page correctly', () => { @@ -50,13 +39,8 @@ describe('Authentication', () => { cy.visit(HOME_PATH); cy.get(`#${HEADER_APP_BAR_ID}`).should('exist'); }); - it('Shared Items', () => { - cy.visit(SHARED_ITEMS_PATH); - cy.get(`#${HEADER_APP_BAR_ID}`).should('exist'); - cy.get(`#${CREATE_ITEM_BUTTON_ID}`).should('not.exist'); - }); it('Item', () => { - cy.visit(buildItemPath(SAMPLE_ITEMS.items?.[0].id)); + cy.visit(buildItemPath(ENV.items[0].id)); cy.get(`#${HEADER_APP_BAR_ID}`).should('exist'); cy.get(`.${ITEM_MAIN_CLASS}`).should('exist'); }); @@ -79,23 +63,12 @@ describe('Authentication', () => { }).should('include', ITEMS_PATH); }); - it('SharedItems', () => { - cy.setCookie(CookieKeys.RedirectUrl, SHARED_ITEMS_PATH); - cy.visit(REDIRECT_PATH); - cy.url({ - timeout: REDIRECTION_TIME, - }).should('include', SHARED_ITEMS_PATH); - }); - it('Item', () => { - cy.setCookie( - CookieKeys.RedirectUrl, - buildItemPath(SAMPLE_ITEMS.items?.[0].id), - ); + cy.setCookie(CookieKeys.RedirectUrl, buildItemPath(ENV.items[0].id)); cy.visit(REDIRECT_PATH); cy.url({ timeout: REDIRECTION_TIME }).should( 'include', - buildItemPath(SAMPLE_ITEMS.items?.[0].id), + buildItemPath(ENV.items[0].id), ); }); }); diff --git a/cypress/e2e/invitations/createInvitation.cy.ts b/cypress/e2e/invitations/createInvitation.cy.ts index 983c8d2e1..b2b86bcfe 100644 --- a/cypress/e2e/invitations/createInvitation.cy.ts +++ b/cypress/e2e/invitations/createInvitation.cy.ts @@ -1,4 +1,4 @@ -import { PermissionLevel } from '@graasp/sdk'; +import { PackedFolderItemFactory, PermissionLevel } from '@graasp/sdk'; import { buildItemPath } from '../../../src/config/paths'; import { @@ -7,7 +7,6 @@ import { SHARE_ITEM_SHARE_BUTTON_ID, buildShareButtonId, } from '../../../src/config/selectors'; -import { SAMPLE_ITEMS } from '../../fixtures/items'; import { MEMBERS } from '../../fixtures/members'; const inviteItem = ({ @@ -33,9 +32,10 @@ const inviteItem = ({ describe('Create Invitation', () => { it('invite one new member', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + const items = [PackedFolderItemFactory()]; + cy.setUpApi({ items, members: Object.values(MEMBERS) }); - const id = SAMPLE_ITEMS.items?.[0].id; + const { id } = items[0]; cy.visit(buildItemPath(id)); // invite @@ -55,24 +55,37 @@ describe('Create Invitation', () => { }); it('cannot invite member with membership', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + const item = PackedFolderItemFactory({ creator: MEMBERS.ANNA }); + const items = [ + { + ...item, + memberships: [ + { + item, + member: MEMBERS.ANNA, + permission: PermissionLevel.Admin, + }, + ], + }, + ]; + cy.setUpApi({ items, members: Object.values(MEMBERS) }); // go to child item - const { id } = SAMPLE_ITEMS.items[1]; + const { id } = items[0]; cy.visit(buildItemPath(id)); - // invite + // person to invite const { email } = MEMBERS.ANNA; - const permission = PermissionLevel.Read; - inviteItem({ id, email, permission }); + inviteItem({ id, email, permission: PermissionLevel.Read }); cy.get(`#${SHARE_ITEM_SHARE_BUTTON_ID}`).should('be.disabled'); }); it('cannot invite with invalid data', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + const items = [PackedFolderItemFactory()]; + cy.setUpApi({ items, members: Object.values(MEMBERS) }); - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = items[0]; cy.visit(buildItemPath(id)); // invite diff --git a/cypress/e2e/invitations/viewInvitation.cy.ts b/cypress/e2e/invitations/viewInvitation.cy.ts index 7a13ba75d..5ff7d45f9 100644 --- a/cypress/e2e/invitations/viewInvitation.cy.ts +++ b/cypress/e2e/invitations/viewInvitation.cy.ts @@ -13,7 +13,7 @@ import { describe('View Invitations', () => { beforeEach(() => { - cy.setUpApi({ ...ITEMS_WITH_INVITATIONS }); + cy.setUpApi(ITEMS_WITH_INVITATIONS); }); it('view invitation in share item modal', () => { diff --git a/cypress/e2e/item/apps/apps.cy.ts b/cypress/e2e/item/apps/apps.cy.ts index 1a29aaebb..32f9a1ba2 100644 --- a/cypress/e2e/item/apps/apps.cy.ts +++ b/cypress/e2e/item/apps/apps.cy.ts @@ -1,10 +1,20 @@ +import { ItemType, PackedAppItemFactory } from '@graasp/sdk'; + import { buildItemPath } from '../../../../src/config/paths'; -import { APP_USING_CONTEXT_ITEM } from '../../../fixtures/apps'; +import { buildAppItemLinkForTest } from '../../../fixtures/apps'; + +const APP = PackedAppItemFactory({ + extra: { + [ItemType.APP]: { + url: `${Cypress.env('VITE_GRAASP_API_HOST')}/${buildAppItemLinkForTest('app.html')}`, + }, + }, +}); describe('Apps', () => { it('App should request context', () => { - const { id, name } = APP_USING_CONTEXT_ITEM; - cy.setUpApi({ items: [APP_USING_CONTEXT_ITEM] }); + const { id, name } = APP; + cy.setUpApi({ items: [APP] }); cy.visit(buildItemPath(id)); cy.wait(2000); diff --git a/cypress/e2e/item/favorite/favoriteItem.cy.ts b/cypress/e2e/item/bookmarks/bookmarks.cy.ts similarity index 74% rename from cypress/e2e/item/favorite/favoriteItem.cy.ts rename to cypress/e2e/item/bookmarks/bookmarks.cy.ts index edab1b9a1..acf19ce3b 100644 --- a/cypress/e2e/item/favorite/favoriteItem.cy.ts +++ b/cypress/e2e/item/bookmarks/bookmarks.cy.ts @@ -1,3 +1,8 @@ +import { + PackedFolderItemFactory, + PackedItemBookmarkFactory, +} from '@graasp/sdk'; + import i18n from '../../../../src/config/i18n'; import { BOOKMARKED_ITEMS_PATH, HOME_PATH } from '../../../../src/config/paths'; import { @@ -8,10 +13,18 @@ import { buildItemMenuButtonId, buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; -import { SAMPLE_BOOKMARK, SAMPLE_ITEMS } from '../../../fixtures/items'; import { CURRENT_USER } from '../../../fixtures/members'; +const BOOKMARKED_ITEMS = [ + PackedItemBookmarkFactory(), + PackedItemBookmarkFactory(), +]; +const ITEMS = BOOKMARKED_ITEMS.map(({ item }) => item); +const NON_BOOKMARKED_ITEM = PackedFolderItemFactory(); + const toggleBookmarkButton = (itemId: string) => { + // todo: remove when refactoring the table + cy.wait(500); cy.get(`#${buildItemMenuButtonId(itemId)}`).click(); cy.get(`#${buildItemMenu(itemId)} .${BOOKMARKED_ITEM_BUTTON_CLASS}`).click(); }; @@ -20,7 +33,8 @@ describe('Bookmarked Item', () => { describe('Member has no bookmarked items', () => { beforeEach(() => { cy.setUpApi({ - ...SAMPLE_ITEMS, + items: ITEMS, + bookmarkedItems: BOOKMARKED_ITEMS, }); cy.visit(BOOKMARKED_ITEMS_PATH); }); @@ -33,8 +47,8 @@ describe('Bookmarked Item', () => { describe('Member has several valid bookmarked items', () => { beforeEach(() => { cy.setUpApi({ - ...SAMPLE_ITEMS, - bookmarkedItems: SAMPLE_BOOKMARK, + items: [...ITEMS, NON_BOOKMARKED_ITEM], + bookmarkedItems: BOOKMARKED_ITEMS, }); i18n.changeLanguage(CURRENT_USER.extra.lang as string); cy.visit(HOME_PATH); @@ -45,8 +59,8 @@ describe('Bookmarked Item', () => { cy.get(`#${CREATE_ITEM_BUTTON_ID}`).should('not.exist'); }); - it('add item to bookmarkeds', () => { - const item = SAMPLE_ITEMS.items[0]; + it('add item to bookmarks', () => { + const item = NON_BOOKMARKED_ITEM; toggleBookmarkButton(item.id); @@ -55,8 +69,8 @@ describe('Bookmarked Item', () => { }); }); - it('remove item from bookmarkeds', () => { - const itemId = SAMPLE_ITEMS.items[1].id; + it('remove item from bookmarks', () => { + const itemId = ITEMS[1].id; toggleBookmarkButton(itemId); @@ -68,7 +82,7 @@ describe('Bookmarked Item', () => { it('check bookmarked items view', () => { cy.visit(BOOKMARKED_ITEMS_PATH); - const itemId = SAMPLE_ITEMS.items[1].id; + const itemId = ITEMS[1].id; cy.get(buildItemsTableRowIdAttribute(itemId)).should('exist'); }); @@ -77,7 +91,7 @@ describe('Bookmarked Item', () => { describe('Error Handling', () => { it('check bookmarked items view with server error', () => { cy.setUpApi({ - ...SAMPLE_ITEMS, + items: ITEMS, getFavoriteError: true, }); cy.visit(BOOKMARKED_ITEMS_PATH); diff --git a/cypress/e2e/item/chatbox/chatbox.cy.ts b/cypress/e2e/item/chatbox/chatbox.cy.ts index 0005ff7c9..666a1157e 100644 --- a/cypress/e2e/item/chatbox/chatbox.cy.ts +++ b/cypress/e2e/item/chatbox/chatbox.cy.ts @@ -1,4 +1,5 @@ import { MockWebSocket } from '@graasp/query-client'; +import { PackedFolderItemFactory } from '@graasp/sdk'; import { v4 } from 'uuid'; @@ -8,10 +9,7 @@ import { CHATBOX_INPUT_BOX_ID, ITEM_CHATBOX_BUTTON_ID, } from '../../../../src/config/selectors'; -import { - ITEM_WITHOUT_CHATBOX_MESSAGES, - ITEM_WITH_CHATBOX_MESSAGES, -} from '../../../fixtures/chatbox'; +import { ITEM_WITH_CHATBOX_MESSAGES } from '../../../fixtures/chatbox'; import { CURRENT_USER, MEMBERS } from '../../../fixtures/members'; import { CHATBOX_LOADING_TIME } from '../../../support/constants'; @@ -79,8 +77,12 @@ describe('Chatbox Scenarios', () => { }); it('Receive messages in chatbox from websockets', () => { - const item = ITEM_WITHOUT_CHATBOX_MESSAGES; - cy.visitAndMockWs(buildItemPath(item.id), { items: [item] }, client); + const item = PackedFolderItemFactory(); + cy.visitAndMockWs( + buildItemPath(item.id), + { items: [item], members: [MEMBERS] }, + client, + ); openChatbox(); diff --git a/cypress/e2e/item/copy/gridCopyItem.cy.ts b/cypress/e2e/item/copy/gridCopyItem.cy.ts index 4f5efc4ae..42801e38c 100644 --- a/cypress/e2e/item/copy/gridCopyItem.cy.ts +++ b/cypress/e2e/item/copy/gridCopyItem.cy.ts @@ -1,3 +1,8 @@ +import { + PackedFolderItemFactory, + PackedLocalFileItemFactory, +} from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEM_MENU_COPY_BUTTON_CLASS, @@ -7,7 +12,6 @@ import { buildItemMenuButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; const copyItem = ({ id, @@ -24,16 +28,22 @@ const copyItem = ({ cy.handleTreeMenu(toItemPath, rootId); }; +const IMAGE_ITEM = PackedLocalFileItemFactory(); +const FOLDER = PackedFolderItemFactory(); +const IMAGE_ITEM_CHILD = PackedLocalFileItemFactory({ parentItem: FOLDER }); +const FOLDER2 = PackedFolderItemFactory(); + +const items = [IMAGE_ITEM, FOLDER, FOLDER2, IMAGE_ITEM_CHILD]; + describe('Copy Item in Grid', () => { it('copy item on Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); // copy - const { id: copyItemId } = SAMPLE_ITEMS.items[0]; - const { path: toItemPath } = SAMPLE_ITEMS.items[1]; - copyItem({ id: copyItemId, toItemPath }); + const { id: copyItemId } = FOLDER; + copyItem({ id: copyItemId, toItemPath: MY_GRAASP_ITEM_PATH }); cy.wait('@copyItems').then(({ request: { url } }) => { cy.get(`#${buildItemCard(copyItemId)}`).should('exist'); @@ -42,16 +52,16 @@ describe('Copy Item in Grid', () => { }); it('copy item in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.Grid); // copy - const { id: copyItemId } = SAMPLE_ITEMS.items[2]; - const { id: toItemId, path: toItemPath } = SAMPLE_ITEMS.items[3]; + const { id: copyItemId } = IMAGE_ITEM_CHILD; + const { id: toItemId, path: toItemPath } = FOLDER2; copyItem({ id: copyItemId, toItemPath }); cy.wait('@copyItems').then(({ request: { url, body } }) => { @@ -62,21 +72,20 @@ describe('Copy Item in Grid', () => { }); it('copy item to Home', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); // go to children item - cy.visit(buildItemPath(id)); + cy.visit(buildItemPath(FOLDER.id)); cy.switchMode(ItemLayoutMode.Grid); // copy - const { id: copyItemId } = SAMPLE_ITEMS.items[2]; + const { id } = IMAGE_ITEM_CHILD; const toItemPath = MY_GRAASP_ITEM_PATH; - copyItem({ id: copyItemId, toItemPath }); + copyItem({ id, toItemPath }); cy.wait('@copyItems').then(({ request: { url } }) => { - cy.get(`#${buildItemCard(copyItemId)}`).should('exist'); - expect(url).to.contain(copyItemId); + cy.get(`#${buildItemCard(id)}`).should('exist'); + expect(url).to.contain(id); }); }); }); diff --git a/cypress/e2e/item/copy/listCopyItem.cy.ts b/cypress/e2e/item/copy/listCopyItem.cy.ts index 6ba34a4bf..3dec3c6c4 100644 --- a/cypress/e2e/item/copy/listCopyItem.cy.ts +++ b/cypress/e2e/item/copy/listCopyItem.cy.ts @@ -1,3 +1,8 @@ +import { + PackedFolderItemFactory, + PackedLocalFileItemFactory, +} from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEM_MENU_COPY_BUTTON_CLASS, @@ -7,7 +12,6 @@ import { buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; import ItemLayoutMode from '../../../../src/enums/itemLayoutMode'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; const copyItem = ({ id, @@ -18,21 +22,30 @@ const copyItem = ({ toItemPath: string; rootId?: string; }) => { + // I need this wait because the table reloads and I lose the menu + // todo: remove on table refactor + cy.wait(500); cy.get(`#${buildItemMenuButtonId(id)}`).click(); cy.get(`#${buildItemMenu(id)} .${ITEM_MENU_COPY_BUTTON_CLASS}`).click(); cy.handleTreeMenu(toItemPath, rootId); }; +const IMAGE_ITEM = PackedLocalFileItemFactory(); +const FOLDER = PackedFolderItemFactory(); +const IMAGE_ITEM_CHILD = PackedLocalFileItemFactory({ parentItem: FOLDER }); +const FOLDER2 = PackedFolderItemFactory(); + +const items = [IMAGE_ITEM, FOLDER, FOLDER2, IMAGE_ITEM_CHILD]; + describe('Copy Item in List', () => { it('copy item on Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); // copy - const { id: copyItemId } = SAMPLE_ITEMS.items[0]; - const { path: toItemPath } = SAMPLE_ITEMS.items[1]; - copyItem({ id: copyItemId, toItemPath }); + const { id: copyItemId } = IMAGE_ITEM; + copyItem({ id: copyItemId, toItemPath: MY_GRAASP_ITEM_PATH }); cy.wait('@copyItems').then(({ request: { url } }) => { expect(url).to.contain(copyItemId); @@ -41,16 +54,16 @@ describe('Copy Item in List', () => { }); it('copy item in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.List); // copy - const { id: copyItemId } = SAMPLE_ITEMS.items[2]; - const { id: toItem, path: toItemPath } = SAMPLE_ITEMS.items[3]; + const { id: copyItemId } = IMAGE_ITEM_CHILD; + const { id: toItem, path: toItemPath } = FOLDER2; copyItem({ id: copyItemId, toItemPath }); cy.wait('@copyItems').then(({ request: { url, body } }) => { @@ -61,15 +74,15 @@ describe('Copy Item in List', () => { }); it('copy item to Home', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.List); // copy - const { id: copyItemId } = SAMPLE_ITEMS.items[2]; + const { id: copyItemId } = IMAGE_ITEM_CHILD; copyItem({ id: copyItemId, toItemPath: MY_GRAASP_ITEM_PATH }); cy.wait('@copyItems').then(({ request: { url } }) => { diff --git a/cypress/e2e/item/copy/listCopyMultiple.cy.ts b/cypress/e2e/item/copy/listCopyMultiple.cy.ts index ca7b2496c..23081e09a 100644 --- a/cypress/e2e/item/copy/listCopyMultiple.cy.ts +++ b/cypress/e2e/item/copy/listCopyMultiple.cy.ts @@ -1,3 +1,8 @@ +import { + PackedFolderItemFactory, + PackedLocalFileItemFactory, +} from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEMS_TABLE_COPY_SELECTED_ITEMS_ID, @@ -5,7 +10,22 @@ import { buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; import ItemLayoutMode from '../../../../src/enums/itemLayoutMode'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; + +const IMAGE_ITEM = PackedLocalFileItemFactory(); +const FOLDER = PackedFolderItemFactory(); +const IMAGE_ITEM_CHILD = PackedLocalFileItemFactory({ parentItem: FOLDER }); +const IMAGE_ITEM_CHILD2 = PackedLocalFileItemFactory({ parentItem: FOLDER }); +const FOLDER2 = PackedFolderItemFactory(); +const FOLDER3 = PackedFolderItemFactory(); + +const items = [ + IMAGE_ITEM, + FOLDER, + FOLDER2, + FOLDER3, + IMAGE_ITEM_CHILD, + IMAGE_ITEM_CHILD2, +]; const copyItems = ({ itemIds, @@ -27,13 +47,13 @@ const copyItems = ({ describe('Copy items in List', () => { it('Copy items on Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); - const itemIds = [SAMPLE_ITEMS.items[0].id, SAMPLE_ITEMS.items[5].id]; - const { path: toItemPath } = SAMPLE_ITEMS.items[1]; + const itemIds = [FOLDER2.id, FOLDER3.id]; + const { path: toItemPath } = FOLDER; copyItems({ itemIds, toItemPath }); cy.wait('@copyItems').then(({ request: { url } }) => { @@ -45,16 +65,16 @@ describe('Copy items in List', () => { }); it('Copy items in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id: start } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id: start } = FOLDER; // go to children item cy.visit(buildItemPath(start)); cy.switchMode(ItemLayoutMode.List); // copy - const itemIds = [SAMPLE_ITEMS.items[2].id, SAMPLE_ITEMS.items[4].id]; - const { id: toItem, path: toItemPath } = SAMPLE_ITEMS.items[3]; + const itemIds = [IMAGE_ITEM_CHILD.id, IMAGE_ITEM_CHILD2.id]; + const { id: toItem, path: toItemPath } = FOLDER2; copyItems({ itemIds, toItemPath }); cy.wait('@copyItems').then(({ request: { url, body } }) => { @@ -67,15 +87,15 @@ describe('Copy items in List', () => { }); it('Copy items to Home', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id: start } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id: start } = FOLDER; // go to children item cy.visit(buildItemPath(start)); cy.switchMode(ItemLayoutMode.List); // copy - const itemIds = [SAMPLE_ITEMS.items[2].id, SAMPLE_ITEMS.items[4].id]; + const itemIds = [IMAGE_ITEM_CHILD.id, IMAGE_ITEM_CHILD2.id]; copyItems({ itemIds, toItemPath: MY_GRAASP_ITEM_PATH }); cy.wait('@copyItems').then(({ request: { url } }) => { diff --git a/cypress/e2e/item/create/createApp.cy.ts b/cypress/e2e/item/create/createApp.cy.ts index abb657d33..4ab567816 100644 --- a/cypress/e2e/item/create/createApp.cy.ts +++ b/cypress/e2e/item/create/createApp.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import ItemLayoutMode from '../../../../src/enums/itemLayoutMode'; import { @@ -5,9 +7,10 @@ import { GRAASP_CUSTOM_APP_ITEM, } from '../../../fixtures/apps'; import { APPS_LIST } from '../../../fixtures/apps/apps'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; import { createApp } from '../../../support/createUtils'; +const FOLDER = PackedFolderItemFactory(); + describe('Create App', () => { describe('create app on Home', () => { it('Create app on Home with dropdown', () => { @@ -43,8 +46,8 @@ describe('Create App', () => { describe('create app in item', () => { it('Create app with dropdown', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items: [FOLDER] }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); @@ -61,8 +64,8 @@ describe('Create App', () => { }); it('Create a custom app', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items: [FOLDER] }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); diff --git a/cypress/e2e/item/create/createDocument.cy.ts b/cypress/e2e/item/create/createDocument.cy.ts index 8392dd970..829634607 100644 --- a/cypress/e2e/item/create/createDocument.cy.ts +++ b/cypress/e2e/item/create/createDocument.cy.ts @@ -1,3 +1,9 @@ +import { + DocumentItemFactory, + ItemType, + PackedFolderItemFactory, +} from '@graasp/sdk'; + import { CREATE_ITEM_BUTTON_ID, CREATE_ITEM_DOCUMENT_ID, @@ -8,11 +14,6 @@ import { import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import ItemLayoutMode from '../../../../src/enums/itemLayoutMode'; -import { - GRAASP_DOCUMENT_BLANK_NAME_ITEM, - GRAASP_DOCUMENT_ITEM, -} from '../../../fixtures/documents'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; import { createDocument } from '../../../support/createUtils'; describe('Create Document', () => { @@ -23,7 +24,7 @@ describe('Create Document', () => { cy.switchMode(ItemLayoutMode.List); // create - createDocument(GRAASP_DOCUMENT_ITEM); + createDocument(DocumentItemFactory()); cy.wait('@postItem').then(() => { // should update view @@ -32,8 +33,9 @@ describe('Create Document', () => { }); it('create document in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + const FOLDER = PackedFolderItemFactory(); + cy.setUpApi({ items: [FOLDER] }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); @@ -41,7 +43,7 @@ describe('Create Document', () => { cy.switchMode(ItemLayoutMode.List); // create - createDocument(GRAASP_DOCUMENT_ITEM); + createDocument(DocumentItemFactory()); cy.wait('@postItem').then(() => { // expect update @@ -54,7 +56,17 @@ describe('Create Document', () => { cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); - createDocument(GRAASP_DOCUMENT_BLANK_NAME_ITEM, { confirm: false }); + createDocument( + DocumentItemFactory({ + name: '', + extra: { + [ItemType.DOCUMENT]: { + content: '

Some Title

', + }, + }, + }), + { confirm: false }, + ); cy.get(`#${ITEM_FORM_CONFIRM_BUTTON_ID}`).should( 'have.prop', diff --git a/cypress/e2e/item/create/createFolder.cy.ts b/cypress/e2e/item/create/createFolder.cy.ts index d9a680012..3ce85c7f9 100644 --- a/cypress/e2e/item/create/createFolder.cy.ts +++ b/cypress/e2e/item/create/createFolder.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { CREATE_ITEM_BUTTON_ID, @@ -7,11 +9,6 @@ import { buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; import ItemLayoutMode from '../../../../src/enums/itemLayoutMode'; -import { - CREATED_BLANK_NAME_ITEM, - CREATED_ITEM, - SAMPLE_ITEMS, -} from '../../../fixtures/items'; import { createFolder } from '../../../support/createUtils'; describe('Create Folder', () => { @@ -23,14 +20,15 @@ describe('Create Folder', () => { cy.switchMode(ItemLayoutMode.List); // create - createFolder(CREATED_ITEM); + createFolder({ name: 'created item' }); cy.wait(['@postItem', '@getAccessibleItems']); }); it('create folder in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + const FOLDER = PackedFolderItemFactory(); + cy.setUpApi({ items: [FOLDER] }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); @@ -38,14 +36,14 @@ describe('Create Folder', () => { cy.switchMode(ItemLayoutMode.List); // create - createFolder(CREATED_ITEM); + createFolder({ name: 'created item' }); }); it('cannot create folder with blank name in item', () => { // create cy.setUpApi(); cy.visit(HOME_PATH); - createFolder(CREATED_BLANK_NAME_ITEM, { confirm: false }); + createFolder({ name: ' ' }, { confirm: false }); cy.get(`#${ITEM_FORM_CONFIRM_BUTTON_ID}`).should( 'have.prop', @@ -58,7 +56,7 @@ describe('Create Folder', () => { // create cy.setUpApi(); cy.visit(HOME_PATH); - createFolder(CREATED_BLANK_NAME_ITEM, { confirm: false }); + createFolder({ name: ' ' }, { confirm: false }); cy.get(`#${ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID}`).should( 'not.exist', @@ -73,7 +71,7 @@ describe('Create Folder', () => { cy.switchMode(ItemLayoutMode.Grid); // create - createFolder(CREATED_ITEM); + createFolder({ name: 'created item' }); cy.wait('@postItem'); // small necessary pause required in order for the form to be able to reset @@ -84,15 +82,16 @@ describe('Create Folder', () => { }); it('create folder in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + const FOLDER = PackedFolderItemFactory(); + cy.setUpApi({ items: [FOLDER] }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.Grid); // create - createFolder(CREATED_ITEM); + createFolder({ name: 'created item' }); cy.wait('@postItem').then(() => { // expect update @@ -103,8 +102,9 @@ describe('Create Folder', () => { describe('Error handling', () => { it('error while creating folder does not create in interface', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, postItemError: true }); - const { id } = SAMPLE_ITEMS.items[0]; + const FOLDER = PackedFolderItemFactory(); + cy.setUpApi({ items: [FOLDER], postItemError: true }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); @@ -112,7 +112,7 @@ describe('Create Folder', () => { cy.switchMode(ItemLayoutMode.List); // create - createFolder(CREATED_ITEM); + createFolder({ name: 'created item' }); cy.wait('@postItem').then(({ response: { body } }) => { // check item is created and displayed diff --git a/cypress/e2e/item/create/createLink.cy.ts b/cypress/e2e/item/create/createLink.cy.ts index 0c2ccb03d..bec2a8999 100644 --- a/cypress/e2e/item/create/createLink.cy.ts +++ b/cypress/e2e/item/create/createLink.cy.ts @@ -1,7 +1,8 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEM_FORM_CONFIRM_BUTTON_ID } from '../../../../src/config/selectors'; import ItemLayoutMode from '../../../../src/enums/itemLayoutMode'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; import { GRAASP_LINK_ITEM, GRAASP_LINK_ITEM_NO_PROTOCOL, @@ -48,8 +49,10 @@ describe('Create Link', () => { }); it('create folder in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + const FOLDER = PackedFolderItemFactory(); + + cy.setUpApi({ items: [FOLDER] }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); @@ -70,8 +73,9 @@ describe('Create Link', () => { describe('Error handling', () => { it('cannot add an invalid link', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + const FOLDER = PackedFolderItemFactory(); + cy.setUpApi({ items: [FOLDER] }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); diff --git a/cypress/e2e/item/create/createShortcut.cy.ts b/cypress/e2e/item/create/createShortcut.cy.ts index d974a32df..dc122975b 100644 --- a/cypress/e2e/item/create/createShortcut.cy.ts +++ b/cypress/e2e/item/create/createShortcut.cy.ts @@ -1,6 +1,11 @@ -import { ItemType, buildShortcutExtra } from '@graasp/sdk'; +import { + ItemType, + PackedFolderItemFactory, + PackedLocalFileItemFactory, + buildShortcutExtra, +} from '@graasp/sdk'; -import { HOME_PATH } from '../../../../src/config/paths'; +import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEM_MENU_SHORTCUT_BUTTON_CLASS, MY_GRAASP_ITEM_PATH, @@ -8,8 +13,11 @@ import { buildItemMenuButtonId, } from '../../../../src/config/selectors'; import ItemLayoutMode from '../../../../src/enums/itemLayoutMode'; -import { IMAGE_ITEM_DEFAULT } from '../../../fixtures/files'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; + +const IMAGE_ITEM = PackedLocalFileItemFactory(); +const FOLDER = PackedFolderItemFactory(); +const IMAGE_ITEM_CHILD = PackedLocalFileItemFactory({ parentItem: FOLDER }); +const FOLDER2 = PackedFolderItemFactory(); const createShortcut = ({ id, @@ -45,6 +53,8 @@ const createShortcutInList = ({ toItemPath?: string; rootId?: string; }) => { + // todo: remove on table refactor + cy.wait(500); const menuSelector = `#${buildItemMenuButtonId(id)}`; cy.get(menuSelector).click(); createShortcut({ id, toItemPath, rootId }); @@ -77,91 +87,67 @@ const checkCreateShortcutRequest = ({ describe('Create Shortcut', () => { describe('List', () => { it('create shortcut from Home to Home', () => { - cy.setUpApi({ items: [...SAMPLE_ITEMS.items, IMAGE_ITEM_DEFAULT] }); + cy.setUpApi({ items: [IMAGE_ITEM] }); cy.visit(HOME_PATH); - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = IMAGE_ITEM; createShortcutInList({ id, toItemPath: MY_GRAASP_ITEM_PATH }); checkCreateShortcutRequest({ id }); }); it('create shortcut from Home to Item', () => { - cy.setUpApi({ items: [...SAMPLE_ITEMS.items, IMAGE_ITEM_DEFAULT] }); + cy.setUpApi({ items: [FOLDER, IMAGE_ITEM] }); cy.visit(HOME_PATH); - const { id } = SAMPLE_ITEMS.items[0]; - const { id: toItemId, path: toItemPath } = SAMPLE_ITEMS.items[3]; + const { id } = IMAGE_ITEM; + const { id: toItemId, path: toItemPath } = FOLDER; createShortcutInList({ id, toItemPath }); checkCreateShortcutRequest({ id, toItemId }); }); it('create shortcut from Item to Item', () => { - cy.setUpApi({ items: [...SAMPLE_ITEMS.items, IMAGE_ITEM_DEFAULT] }); - cy.visit(HOME_PATH); - - const { id } = SAMPLE_ITEMS.items[1]; - const { id: toItemId, path: toItemPath } = SAMPLE_ITEMS.items[3]; - createShortcutInList({ id, toItemPath }); - - checkCreateShortcutRequest({ id, toItemId }); - }); - - it('create shortcut from file to Item', () => { - cy.setUpApi({ items: [...SAMPLE_ITEMS.items, IMAGE_ITEM_DEFAULT] }); - cy.visit(HOME_PATH); + cy.setUpApi({ items: [FOLDER, FOLDER2, IMAGE_ITEM_CHILD] }); + cy.visit(buildItemPath(FOLDER.id)); - const { id } = IMAGE_ITEM_DEFAULT; - const { id: toItemId, path: toItemPath } = SAMPLE_ITEMS.items[3]; + const { id } = IMAGE_ITEM_CHILD; + const { id: toItemId, path: toItemPath } = FOLDER2; createShortcutInList({ id, toItemPath }); - checkCreateShortcutRequest({ id, toItemId }); }); }); describe('Grid', () => { it('create shortcut from Home to Home', () => { - cy.setUpApi({ items: [...SAMPLE_ITEMS.items, IMAGE_ITEM_DEFAULT] }); + cy.setUpApi({ items: [IMAGE_ITEM] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = IMAGE_ITEM; createShortcutInGrid({ id, toItemPath: MY_GRAASP_ITEM_PATH }); checkCreateShortcutRequest({ id }); }); it('create shortcut from Home to Item', () => { - cy.setUpApi({ items: [...SAMPLE_ITEMS.items, IMAGE_ITEM_DEFAULT] }); + cy.setUpApi({ items: [FOLDER, IMAGE_ITEM] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); - const { id } = SAMPLE_ITEMS.items[0]; - const { id: toItemId, path: toItemPath } = SAMPLE_ITEMS.items[3]; + const { id } = IMAGE_ITEM; + const { id: toItemId, path: toItemPath } = FOLDER; createShortcutInGrid({ id, toItemPath }); checkCreateShortcutRequest({ id, toItemId }); }); it('create shortcut from Item to Item', () => { - cy.setUpApi({ items: [...SAMPLE_ITEMS.items, IMAGE_ITEM_DEFAULT] }); - cy.visit(HOME_PATH); - cy.switchMode(ItemLayoutMode.Grid); - - const { id } = SAMPLE_ITEMS.items[1]; - const { id: toItemId, path: toItemPath } = SAMPLE_ITEMS.items[3]; - createShortcutInGrid({ id, toItemPath }); - - checkCreateShortcutRequest({ id, toItemId }); - }); - - it('create shortcut from file to Item', () => { - cy.setUpApi({ items: [...SAMPLE_ITEMS.items, IMAGE_ITEM_DEFAULT] }); - cy.visit(HOME_PATH); + cy.setUpApi({ items: [FOLDER, FOLDER2, IMAGE_ITEM_CHILD] }); + cy.visit(buildItemPath(FOLDER.id)); cy.switchMode(ItemLayoutMode.Grid); - const { id } = IMAGE_ITEM_DEFAULT; - const { id: toItemId, path: toItemPath } = SAMPLE_ITEMS.items[3]; + const { id } = IMAGE_ITEM_CHILD; + const { id: toItemId, path: toItemPath } = FOLDER2; createShortcutInGrid({ id, toItemPath }); checkCreateShortcutRequest({ id, toItemId }); diff --git a/cypress/e2e/item/create/importZip.cy.ts b/cypress/e2e/item/create/importZip.cy.ts index 8f5175f76..e33adc900 100644 --- a/cypress/e2e/item/create/importZip.cy.ts +++ b/cypress/e2e/item/create/importZip.cy.ts @@ -1,8 +1,9 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ZIP_DASHBOARD_UPLOADER_ID } from '../../../../src/config/selectors'; import ItemLayoutMode from '../../../../src/enums/itemLayoutMode'; import { ZIP_DEFAULT } from '../../../fixtures/files'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; import { createItem } from '../../../support/createUtils'; describe('Import Zip', () => { @@ -21,8 +22,10 @@ describe('Import Zip', () => { }); it('create file in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + const FOLDER = PackedFolderItemFactory(); + + cy.setUpApi({ items: [FOLDER] }); + const { id } = FOLDER; cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.List); @@ -36,8 +39,10 @@ describe('Import Zip', () => { }); it('catch error', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, importZipError: true }); - const { id } = SAMPLE_ITEMS.items[0]; + const FOLDER = PackedFolderItemFactory(); + + cy.setUpApi({ items: [FOLDER], importZipError: true }); + const { id } = FOLDER; cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.List); diff --git a/cypress/e2e/item/delete/gridRecycleItem.cy.ts b/cypress/e2e/item/delete/gridRecycleItem.cy.ts index fb96a3834..1777444ec 100644 --- a/cypress/e2e/item/delete/gridRecycleItem.cy.ts +++ b/cypress/e2e/item/delete/gridRecycleItem.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEM_MENU_RECYCLE_BUTTON_CLASS, @@ -5,7 +7,6 @@ import { buildItemMenuButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; const recycleItem = (id: string) => { const menuSelector = `#${buildItemMenuButtonId(id)}`; @@ -15,11 +16,13 @@ const recycleItem = (id: string) => { describe('Recycle Item in Grid', () => { it('recycle item on Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + const FOLDER = PackedFolderItemFactory(); + + cy.setUpApi({ items: [FOLDER] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = FOLDER; // recycle recycleItem(id); @@ -27,9 +30,11 @@ describe('Recycle Item in Grid', () => { }); it('recycle item inside parent', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; - const { id: idToDelete } = SAMPLE_ITEMS.items[2]; + const FOLDER = PackedFolderItemFactory(); + const CHILD = PackedFolderItemFactory({ parentItem: FOLDER }); + cy.setUpApi({ items: [FOLDER, CHILD] }); + const { id } = FOLDER; + const { id: idToDelete } = CHILD; // go to children item cy.visit(buildItemPath(id)); diff --git a/cypress/e2e/item/delete/listDeleteItem.cy.ts b/cypress/e2e/item/delete/listDeleteItem.cy.ts index cbe82e34e..a98326bcd 100644 --- a/cypress/e2e/item/delete/listDeleteItem.cy.ts +++ b/cypress/e2e/item/delete/listDeleteItem.cy.ts @@ -1,3 +1,5 @@ +import { PackedRecycledItemDataFactory } from '@graasp/sdk'; + import { RECYCLE_BIN_PATH } from '../../../../src/config/paths'; import { CONFIRM_DELETE_BUTTON_ID, @@ -5,7 +7,6 @@ import { buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { RECYCLED_ITEM_DATA, SAMPLE_ITEMS } from '../../../fixtures/items'; const deleteItem = (id: string) => { cy.get( @@ -16,11 +17,18 @@ const deleteItem = (id: string) => { describe('Delete Item in List', () => { it('delete item', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, recycledItemData: RECYCLED_ITEM_DATA }); + const recycledItemData = [ + PackedRecycledItemDataFactory(), + PackedRecycledItemDataFactory(), + ]; + cy.setUpApi({ + items: recycledItemData.map(({ item }) => item), + recycledItemData, + }); cy.visit(RECYCLE_BIN_PATH); cy.switchMode(ItemLayoutMode.List); - const { id } = RECYCLED_ITEM_DATA[0].item; + const { id } = recycledItemData[0].item; // delete deleteItem(id); diff --git a/cypress/e2e/item/delete/listDeleteItems.cy.ts b/cypress/e2e/item/delete/listDeleteItems.cy.ts index 1647ac180..a6150c805 100644 --- a/cypress/e2e/item/delete/listDeleteItems.cy.ts +++ b/cypress/e2e/item/delete/listDeleteItems.cy.ts @@ -1,3 +1,5 @@ +import { PackedRecycledItemDataFactory } from '@graasp/sdk'; + import { RECYCLE_BIN_PATH } from '../../../../src/config/paths'; import { CONFIRM_DELETE_BUTTON_ID, @@ -5,7 +7,6 @@ import { buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { RECYCLED_ITEM_DATA, SAMPLE_ITEMS } from '../../../fixtures/items'; const deleteItems = (itemIds: string[]) => { // check selected ids @@ -18,12 +19,14 @@ const deleteItems = (itemIds: string[]) => { }; describe('Delete Items in List', () => { - const itemIds = [ - RECYCLED_ITEM_DATA[0].item.id, - RECYCLED_ITEM_DATA[1].item.id, + const recycledItemData = [ + PackedRecycledItemDataFactory(), + PackedRecycledItemDataFactory(), ]; + const items = recycledItemData.map(({ item }) => item); + const itemIds = items.map(({ id }) => id); it('delete items', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, recycledItemData: RECYCLED_ITEM_DATA }); + cy.setUpApi({ items, recycledItemData }); cy.visit(RECYCLE_BIN_PATH); cy.switchMode(ItemLayoutMode.List); diff --git a/cypress/e2e/item/delete/listRecycleItem.cy.ts b/cypress/e2e/item/delete/listRecycleItem.cy.ts index 5f9b7dc90..233202ba9 100644 --- a/cypress/e2e/item/delete/listRecycleItem.cy.ts +++ b/cypress/e2e/item/delete/listRecycleItem.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEM_MENU_RECYCLE_BUTTON_CLASS, @@ -5,21 +7,27 @@ import { buildItemMenuButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; const recycleItem = (id: string) => { + // I need this wait because the table reloads and I lose the menu + // todo: remove on table refactor + cy.wait(500); cy.get(`#${buildItemMenuButtonId(id)}`).click(); cy.get(`#${buildItemMenu(id)} .${ITEM_MENU_RECYCLE_BUTTON_CLASS}`).click(); }; +const FOLDER = PackedFolderItemFactory(); +const CHILD = PackedFolderItemFactory({ parentItem: FOLDER }); +const items = [FOLDER, CHILD, PackedFolderItemFactory()]; + describe('Recycle Item in List', () => { it('recycle item on Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = items[0]; // delete recycleItem(id); @@ -30,9 +38,9 @@ describe('Recycle Item in List', () => { }); it('recycle item inside parent', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; - const { id: idToDelete } = SAMPLE_ITEMS.items[2]; + cy.setUpApi({ items }); + const { id } = FOLDER; + const { id: idToDelete } = CHILD; // go to children item cy.visit(buildItemPath(id)); diff --git a/cypress/e2e/item/delete/listRecycleItems.cy.ts b/cypress/e2e/item/delete/listRecycleItems.cy.ts index 66483a47d..4f0951915 100644 --- a/cypress/e2e/item/delete/listRecycleItems.cy.ts +++ b/cypress/e2e/item/delete/listRecycleItems.cy.ts @@ -1,10 +1,11 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEMS_TABLE_RECYCLE_SELECTED_ITEMS_ID, buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; const recycleItems = (itemIds: string[]) => { // check selected ids @@ -15,31 +16,35 @@ const recycleItems = (itemIds: string[]) => { cy.get(`#${ITEMS_TABLE_RECYCLE_SELECTED_ITEMS_ID}`).click(); }; +const FOLDER = PackedFolderItemFactory(); +const PARENT = PackedFolderItemFactory(); +const CHILD1 = PackedFolderItemFactory({ parentItem: PARENT }); +const CHILD2 = PackedFolderItemFactory({ parentItem: PARENT }); +const items = [FOLDER, PARENT, CHILD1, CHILD2]; + describe('Recycle Items in List', () => { it('recycle 2 items in Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); // delete - recycleItems([SAMPLE_ITEMS.items[0].id, SAMPLE_ITEMS.items[1].id]); + recycleItems([FOLDER.id, PARENT.id]); cy.wait(['@recycleItems', '@getAccessibleItems']); }); it('recycle 2 items in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - cy.visit(buildItemPath(SAMPLE_ITEMS.items[0].id)); + cy.setUpApi({ items }); + cy.visit(buildItemPath(PARENT.id)); cy.switchMode(ItemLayoutMode.List); // delete - recycleItems([SAMPLE_ITEMS.items[2].id, SAMPLE_ITEMS.items[3].id]); + recycleItems([CHILD1.id, CHILD2.id]); cy.wait('@recycleItems').then(() => { // check item is deleted, others are still displayed - cy.wait('@getItem') - .its('response.url') - .should('contain', SAMPLE_ITEMS.items[0].id); + cy.wait('@getItem').its('response.url').should('contain', PARENT.id); }); }); }); diff --git a/cypress/e2e/item/delete/listRestoreItem.cy.ts b/cypress/e2e/item/delete/listRestoreItem.cy.ts index 2be701610..2e9208f3b 100644 --- a/cypress/e2e/item/delete/listRestoreItem.cy.ts +++ b/cypress/e2e/item/delete/listRestoreItem.cy.ts @@ -1,3 +1,5 @@ +import { PackedRecycledItemDataFactory } from '@graasp/sdk'; + import { RECYCLE_BIN_PATH } from '../../../../src/config/paths'; import { ITEMS_TABLE_RESTORE_SELECTED_ITEMS_ID, @@ -5,7 +7,6 @@ import { buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { RECYCLED_ITEM_DATA, SAMPLE_ITEMS } from '../../../fixtures/items'; const restoreItem = (id: string) => { cy.get( @@ -24,11 +25,18 @@ const restoreItems = (itemIds: string[]) => { describe('Restore Items in List', () => { it('restore one item', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, recycledItemData: RECYCLED_ITEM_DATA }); + const recycledItemData = [ + PackedRecycledItemDataFactory(), + PackedRecycledItemDataFactory(), + ]; + cy.setUpApi({ + items: recycledItemData.map(({ item }) => item), + recycledItemData, + }); cy.visit(RECYCLE_BIN_PATH); cy.switchMode(ItemLayoutMode.List); - const { id } = RECYCLED_ITEM_DATA[0].item; + const { id } = recycledItemData[0].item; // restore restoreItem(id); @@ -39,13 +47,21 @@ describe('Restore Items in List', () => { }); it('restore multiple items', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, recycledItemData: RECYCLED_ITEM_DATA }); + const recycledItemData = [ + PackedRecycledItemDataFactory(), + PackedRecycledItemDataFactory(), + ]; + const items = recycledItemData.map(({ item }) => item); + cy.setUpApi({ + items, + recycledItemData, + }); cy.visit(RECYCLE_BIN_PATH); cy.switchMode(ItemLayoutMode.List); // restore - const itemIds = RECYCLED_ITEM_DATA.map(({ item }) => item.id); + const itemIds = items.map(({ id }) => id); restoreItems(itemIds); cy.wait('@restoreItems').then(({ request: { url } }) => { for (const id of itemIds) { diff --git a/cypress/e2e/item/download/downloadItem.cy.ts b/cypress/e2e/item/download/downloadItem.cy.ts index 2dfb00767..4094d063d 100644 --- a/cypress/e2e/item/download/downloadItem.cy.ts +++ b/cypress/e2e/item/download/downloadItem.cy.ts @@ -1,30 +1,48 @@ +import { PackedFolderItemFactory, PermissionLevel } from '@graasp/sdk'; + import { buildDownloadButtonId } from '@/config/selectors'; import { ItemLayoutMode } from '@/enums'; -import { SHARED_ITEMS_PATH, buildItemPath } from '../../../../src/config/paths'; +import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { SAMPLE_PUBLIC_ITEMS } from '../../../fixtures/items'; import { SIGNED_OUT_MEMBER } from '../../../fixtures/members'; -import { SHARED_ITEMS } from '../../../fixtures/sharedItems'; + +const SHARED_ITEM = PackedFolderItemFactory( + {}, + { permission: PermissionLevel.Read }, +); describe('Download Item', () => { it('Table View', () => { - cy.setUpApi(SHARED_ITEMS); - cy.visit(SHARED_ITEMS_PATH); - cy.wait('@getSharedItems').then(({ response: { body } }) => { - for (const item of body) { - cy.get(`#${buildDownloadButtonId(item.id)}`).should('exist'); - } - }); + cy.setUpApi({ items: [SHARED_ITEM] }); + cy.visit(HOME_PATH); + cy.wait('@getAccessibleItems').then( + ({ + response: { + body: { data }, + }, + }) => { + for (const item of data) { + cy.get(`#${buildDownloadButtonId(item.id)}`).should('exist'); + } + }, + ); }); it('Grid view', () => { - cy.setUpApi(SHARED_ITEMS); - cy.visit(SHARED_ITEMS_PATH); + cy.setUpApi({ items: [SHARED_ITEM] }); + cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); - cy.wait('@getSharedItems').then(({ response: { body } }) => { - for (const item of body) { - cy.get(`#${buildDownloadButtonId(item.id)}`).should('exist'); - } - }); + cy.wait('@getAccessibleItems').then( + ({ + response: { + body: { data }, + }, + }) => { + for (const item of data) { + cy.get(`#${buildDownloadButtonId(item.id)}`).should('exist'); + } + }, + ); }); it('download button for public item should be exist', () => { const currentMember = SIGNED_OUT_MEMBER; diff --git a/cypress/e2e/item/duplicate/duplicateItem.cy.ts b/cypress/e2e/item/duplicate/duplicateItem.cy.ts index c21698af4..0aec6602a 100644 --- a/cypress/e2e/item/duplicate/duplicateItem.cy.ts +++ b/cypress/e2e/item/duplicate/duplicateItem.cy.ts @@ -1,19 +1,21 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { getParentsIdsFromPath } from '@/utils/item'; import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import ItemLayoutMode from '../../../../src/enums/itemLayoutMode'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; import duplicateItem from '../../../support/actionsUtils'; describe('duplicate Item in Home', () => { Object.values([ItemLayoutMode.Grid, ItemLayoutMode.List]).forEach((view) => { it(`duplicate item on Home in ${view} view`, () => { - cy.setUpApi(SAMPLE_ITEMS); + const FOLDER = PackedFolderItemFactory(); + cy.setUpApi({ items: [FOLDER] }); cy.visit(HOME_PATH); cy.switchMode(view); // duplicate - const { id: duplicateItemId } = SAMPLE_ITEMS.items[0]; + const { id: duplicateItemId } = FOLDER; duplicateItem({ id: duplicateItemId }); cy.wait('@copyItems').then(({ request: { url, body } }) => { @@ -27,8 +29,10 @@ describe('duplicate Item in Home', () => { describe('duplicate Item in item', () => { Object.values([ItemLayoutMode.Grid, ItemLayoutMode.List]).forEach((view) => { it(`duplicate item in item in ${view} view`, () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id, path } = SAMPLE_ITEMS.items[0]; + const FOLDER = PackedFolderItemFactory(); + const CHILD = PackedFolderItemFactory({ parentItem: FOLDER }); + cy.setUpApi({ items: [FOLDER, CHILD] }); + const { id, path } = FOLDER; const parentsIds = getParentsIdsFromPath(path); // go to children item @@ -36,7 +40,7 @@ describe('duplicate Item in item', () => { cy.switchMode(view); // duplicate - const { id: duplicateItemId } = SAMPLE_ITEMS.items[2]; + const { id: duplicateItemId } = CHILD; duplicateItem({ id: duplicateItemId }); cy.wait('@copyItems').then(({ request: { url, body } }) => { diff --git a/cypress/e2e/item/edit/editApp.cy.ts b/cypress/e2e/item/edit/editApp.cy.ts index 5e2c2ff45..7b393bb54 100644 --- a/cypress/e2e/item/edit/editApp.cy.ts +++ b/cypress/e2e/item/edit/editApp.cy.ts @@ -1,4 +1,9 @@ -import { buildAppExtra } from '@graasp/sdk'; +import { + ItemType, + PackedAppItemFactory, + PackedFolderItemFactory, + buildAppExtra, +} from '@graasp/sdk'; import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { @@ -9,23 +14,39 @@ import { buildEditButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { - GRAASP_APP_CHILDREN_ITEM, - GRAASP_APP_ITEM, - GRAASP_APP_ITEMS_FIXTURE, - GRAASP_APP_PARENT_FOLDER, -} from '../../../fixtures/apps'; -import { EDITED_FIELDS } from '../../../fixtures/items'; -import { GRAASP_LINK_ITEM } from '../../../fixtures/links'; +import { buildAppItemLinkForTest } from '../../../fixtures/apps'; +import { CURRENT_USER, MEMBERS } from '../../../fixtures/members'; import { EDIT_ITEM_PAUSE } from '../../../support/constants'; import { editCaptionFromViewPage, editItem } from '../../../support/editUtils'; const url = 'http://localhost:3334'; + const newFields = { - ...EDITED_FIELDS, + name: 'new name', extra: buildAppExtra({ url }), }; +const GRAASP_APP_ITEM = PackedAppItemFactory({ + name: 'test app', + description: 'my app description', + creator: CURRENT_USER, +}); + +const GRAASP_APP_PARENT_FOLDER = PackedFolderItemFactory({ + name: 'graasp app parent', +}); + +const APP_USING_CONTEXT_ITEM = PackedAppItemFactory({ + name: 'my app', + extra: { + [ItemType.APP]: { + url: `${Cypress.env('VITE_GRAASP_API_HOST')}/${buildAppItemLinkForTest('app.html')}`, + }, + }, + creator: MEMBERS.ANNA, + parentItem: GRAASP_APP_PARENT_FOLDER, +}); + describe('Edit App', () => { describe('View Page', () => { beforeEach(() => { @@ -63,7 +84,7 @@ describe('Edit App', () => { describe('List', () => { it('edit app on Home', () => { const itemToEdit = GRAASP_APP_ITEM; - cy.setUpApi({ items: [itemToEdit, GRAASP_LINK_ITEM] }); + cy.setUpApi({ items: [itemToEdit] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); @@ -93,11 +114,13 @@ describe('Edit App', () => { }); it('edit app in item', () => { - const itemToEdit = GRAASP_APP_CHILDREN_ITEM; - cy.setUpApi({ items: GRAASP_APP_ITEMS_FIXTURE }); - const parent = GRAASP_APP_PARENT_FOLDER; + const parentItem = PackedFolderItemFactory(); + const itemToEdit = PackedAppItemFactory({ parentItem }); + cy.setUpApi({ + items: [parentItem, itemToEdit], + }); // go to children item - cy.visit(buildItemPath(parent.id)); + cy.visit(buildItemPath(parentItem.id)); cy.switchMode(ItemLayoutMode.List); @@ -120,7 +143,9 @@ describe('Edit App', () => { cy.wait(EDIT_ITEM_PAUSE); expect(id).to.equal(itemToEdit.id); expect(name).to.equal(newFields.name); - cy.get('@getItem').its('response.url').should('contain', parent.id); + cy.get('@getItem') + .its('response.url') + .should('contain', parentItem.id); }, ); }); @@ -128,12 +153,11 @@ describe('Edit App', () => { describe('Grid', () => { it('edit app on Home', () => { - cy.setUpApi({ items: GRAASP_APP_ITEMS_FIXTURE }); + const itemToEdit = GRAASP_APP_ITEM; + cy.setUpApi({ items: [itemToEdit] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); - const itemToEdit = GRAASP_APP_ITEM; - // edit editItem( { @@ -159,14 +183,13 @@ describe('Edit App', () => { }); it('edit app in item', () => { - cy.setUpApi({ items: GRAASP_APP_ITEMS_FIXTURE }); - // go to children item + const itemToEdit = APP_USING_CONTEXT_ITEM; const parent = GRAASP_APP_PARENT_FOLDER; + cy.setUpApi({ items: [parent, itemToEdit] }); + // go to children item cy.visit(buildItemPath(parent.id)); cy.switchMode(ItemLayoutMode.Grid); - const itemToEdit = GRAASP_APP_CHILDREN_ITEM; - // edit editItem( { diff --git a/cypress/e2e/item/edit/editDocument.cy.ts b/cypress/e2e/item/edit/editDocument.cy.ts index 74b5db4f4..1c7298182 100644 --- a/cypress/e2e/item/edit/editDocument.cy.ts +++ b/cypress/e2e/item/edit/editDocument.cy.ts @@ -1,4 +1,9 @@ -import { buildDocumentExtra, getDocumentExtra } from '@graasp/sdk'; +import { + PackedDocumentItemFactory, + PackedFolderItemFactory, + buildDocumentExtra, + getDocumentExtra, +} from '@graasp/sdk'; import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { @@ -8,14 +13,6 @@ import { buildEditButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { - GRAASP_DOCUMENT_CHILDREN_ITEM, - GRAASP_DOCUMENT_ITEM, - GRAASP_DOCUMENT_ITEMS_FIXTURE, - GRAASP_DOCUMENT_PARENT_FOLDER, -} from '../../../fixtures/documents'; -import { EDITED_FIELDS } from '../../../fixtures/items'; -import { GRAASP_LINK_ITEM } from '../../../fixtures/links'; import { CAPTION_EDIT_PAUSE, EDIT_ITEM_PAUSE, @@ -24,14 +21,29 @@ import { editItem } from '../../../support/editUtils'; const content = 'new text'; const newFields = { - ...EDITED_FIELDS, + name: 'new name', extra: buildDocumentExtra({ content }), }; +const GRAASP_DOCUMENT_ITEM = PackedDocumentItemFactory({ + name: 'graasp text', + extra: buildDocumentExtra({ + content: '

Some Title

', + }), +}); +const GRAASP_FOLDER_PARENT = PackedFolderItemFactory(); +const GRAASP_DOCUMENT_ITEM_CHILD = PackedDocumentItemFactory({ + name: 'graasp text', + extra: buildDocumentExtra({ + content: '

Some Title

', + }), + parentItem: GRAASP_FOLDER_PARENT, +}); + describe('Edit Document', () => { describe('List', () => { it('edit on Home', () => { - cy.setUpApi({ items: [GRAASP_DOCUMENT_ITEM, GRAASP_LINK_ITEM] }); + cy.setUpApi({ items: [GRAASP_DOCUMENT_ITEM] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); @@ -64,15 +76,14 @@ describe('Edit Document', () => { }); it('edit in folder', () => { - cy.setUpApi({ items: GRAASP_DOCUMENT_ITEMS_FIXTURE }); - const parent = GRAASP_DOCUMENT_PARENT_FOLDER; + const parent = GRAASP_FOLDER_PARENT; + const itemToEdit = GRAASP_DOCUMENT_ITEM_CHILD; + cy.setUpApi({ items: [parent, itemToEdit] }); // go to children item cy.visit(buildItemPath(parent.id)); cy.switchMode(ItemLayoutMode.List); - const itemToEdit = GRAASP_DOCUMENT_CHILDREN_ITEM; - // edit editItem( { @@ -101,12 +112,11 @@ describe('Edit Document', () => { describe('Grid', () => { it('edit on Home', () => { - cy.setUpApi({ items: GRAASP_DOCUMENT_ITEMS_FIXTURE }); + const itemToEdit = GRAASP_DOCUMENT_ITEM; + cy.setUpApi({ items: [itemToEdit] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); - const itemToEdit = GRAASP_DOCUMENT_ITEM; - // edit editItem( { @@ -133,14 +143,12 @@ describe('Edit Document', () => { }); it('edit in folder', () => { - cy.setUpApi({ items: GRAASP_DOCUMENT_ITEMS_FIXTURE }); - // go to children item - const parent = GRAASP_DOCUMENT_PARENT_FOLDER; + const parent = GRAASP_FOLDER_PARENT; + const itemToEdit = GRAASP_DOCUMENT_ITEM_CHILD; + cy.setUpApi({ items: [parent, itemToEdit] }); cy.visit(buildItemPath(parent.id)); cy.switchMode(ItemLayoutMode.Grid); - const itemToEdit = GRAASP_DOCUMENT_CHILDREN_ITEM; - // edit editItem( { diff --git a/cypress/e2e/item/edit/editEtherpad.cy.ts b/cypress/e2e/item/edit/editEtherpad.cy.ts index 743cb119f..63c55415e 100644 --- a/cypress/e2e/item/edit/editEtherpad.cy.ts +++ b/cypress/e2e/item/edit/editEtherpad.cy.ts @@ -1,10 +1,16 @@ +import { PackedEtherpadItemFactory } from '@graasp/sdk'; + import { HOME_PATH } from '../../../../src/config/paths'; import { ItemLayoutMode } from '../../../../src/enums'; -import { GRAASP_ETHERPAD_ITEM } from '../../../fixtures/etherpad'; -import { EDITED_FIELDS } from '../../../fixtures/items'; import { EDIT_ITEM_PAUSE } from '../../../support/constants'; import { editItem } from '../../../support/editUtils'; +const EDITED_FIELDS = { + name: 'new name', +}; + +const GRAASP_ETHERPAD_ITEM = PackedEtherpadItemFactory(); + describe('Edit Etherpad', () => { beforeEach(() => { cy.setUpApi({ items: [GRAASP_ETHERPAD_ITEM] }); diff --git a/cypress/e2e/item/edit/editFile.cy.ts b/cypress/e2e/item/edit/editFile.cy.ts index 0271c3add..6695a9a6d 100644 --- a/cypress/e2e/item/edit/editFile.cy.ts +++ b/cypress/e2e/item/edit/editFile.cy.ts @@ -1,4 +1,8 @@ -import { DescriptionPlacement } from '@graasp/sdk'; +import { + DescriptionPlacement, + PackedLocalFileItemFactory, + PackedS3FileItemFactory, +} from '@graasp/sdk'; import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { @@ -10,19 +14,41 @@ import { buildEditButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { IMAGE_ITEM_DEFAULT, VIDEO_ITEM_S3 } from '../../../fixtures/files'; -import { EDITED_FIELDS } from '../../../fixtures/items'; +import { MOCK_IMAGE_URL, MOCK_VIDEO_URL } from '../../../fixtures/fileLinks'; +import { ICON_FILEPATH, VIDEO_FILEPATH } from '../../../fixtures/files'; import { EDIT_ITEM_PAUSE } from '../../../support/constants'; import { editCaptionFromViewPage, editItem } from '../../../support/editUtils'; +import { + LocalFileItemForTest, + S3FileItemForTest, +} from '../../../support/types'; + +const EDITED_FIELDS = { + name: 'new name', +}; + +const IMAGE_ITEM: LocalFileItemForTest = { + ...PackedLocalFileItemFactory(), + // for testing: creating needs a fixture, reading needs an url + createFilepath: ICON_FILEPATH, + readFilepath: MOCK_IMAGE_URL, +}; + +const VIDEO_ITEM_S3: S3FileItemForTest = { + ...PackedS3FileItemFactory(), + // for testing: creating needs a fixture, reading needs an url + createFilepath: VIDEO_FILEPATH, + readFilepath: MOCK_VIDEO_URL, +}; describe('Edit File', () => { beforeEach(() => { - cy.setUpApi({ items: [IMAGE_ITEM_DEFAULT, VIDEO_ITEM_S3] }); + cy.setUpApi({ items: [IMAGE_ITEM, VIDEO_ITEM_S3] }); }); describe('View Page', () => { it("edit file's caption", () => { - const { id } = IMAGE_ITEM_DEFAULT; + const { id } = IMAGE_ITEM; cy.visit(buildItemPath(id)); const caption = 'new caption'; editCaptionFromViewPage({ id, caption }); @@ -34,7 +60,7 @@ describe('Edit File', () => { }); it('edit description placement to above', () => { - const { id } = IMAGE_ITEM_DEFAULT; + const { id } = IMAGE_ITEM; cy.visit(buildItemPath(id)); cy.get(`#${buildEditButtonId(id)}`).click(); @@ -66,7 +92,7 @@ describe('Edit File', () => { }); it("cancel file's caption", () => { - const { id } = IMAGE_ITEM_DEFAULT; + const { id } = IMAGE_ITEM; cy.visit(buildItemPath(id)); cy.get(`#${buildEditButtonId(id)}`).click(); cy.get(`#${EDIT_ITEM_MODAL_CANCEL_BUTTON_ID}`).click(); @@ -92,7 +118,7 @@ describe('Edit File', () => { cy.switchMode(ItemLayoutMode.List); - const itemToEdit = IMAGE_ITEM_DEFAULT; + const itemToEdit = IMAGE_ITEM; // edit editItem( diff --git a/cypress/e2e/item/edit/editFolder.cy.ts b/cypress/e2e/item/edit/editFolder.cy.ts index 82878ac58..351475a85 100644 --- a/cypress/e2e/item/edit/editFolder.cy.ts +++ b/cypress/e2e/item/edit/editFolder.cy.ts @@ -1,39 +1,29 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEM_FORM_CONFIRM_BUTTON_ID, buildEditButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { EDITED_FIELDS, SAMPLE_ITEMS } from '../../../fixtures/items'; import { EDIT_ITEM_PAUSE } from '../../../support/constants'; import { editItem } from '../../../support/editUtils'; +const EDITED_FIELDS = { + name: 'new name', +}; + describe('Edit Folder', () => { describe('List', () => { - describe('View Page', () => { - // bug does not work in ci - // it('edit caption', () => { - // const item = SAMPLE_ITEMS.items[0]; - // const { id } = item; - // cy.setUpApi({ items: [item] }); - // cy.visit(buildItemPath(id)); - // cy.switchMode(ItemLayoutMode.List); - // const caption = 'new caption'; - // editCaptionFromViewPage({ id, caption }); - // cy.wait(`@editItem`).then(({ request: { url: endpointUrl, body } }) => { - // expect(endpointUrl).to.contain(id); - // // caption content might be wrapped with html tags - // expect(body?.description).to.contain(caption); - // }); - // }); - }); - it('confirm with empty name', () => { - cy.setUpApi(SAMPLE_ITEMS); + const item = PackedFolderItemFactory(); + cy.setUpApi({ items: [item] }); cy.visit(HOME_PATH); // click edit button - const itemId = SAMPLE_ITEMS.items[0].id; + const itemId = item.id; + // todo: remove once the table is refactored + cy.wait(500); cy.get(`#${buildEditButtonId(itemId)}`).click(); cy.fillFolderModal( @@ -49,12 +39,13 @@ describe('Edit Folder', () => { }); it('edit folder on Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + const item = PackedFolderItemFactory(); + cy.setUpApi({ items: [item] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); - const itemToEdit = SAMPLE_ITEMS.items[0]; + const itemToEdit = item; const newDescription = 'new description'; // edit editItem( @@ -83,14 +74,14 @@ describe('Edit Folder', () => { }); it('edit folder in item', () => { - cy.setUpApi(SAMPLE_ITEMS); + const parentItem = PackedFolderItemFactory(); + const itemToEdit = PackedFolderItemFactory({ parentItem }); + cy.setUpApi({ items: [parentItem, itemToEdit] }); // go to children item - cy.visit(buildItemPath(SAMPLE_ITEMS.items[0].id)); + cy.visit(buildItemPath(itemToEdit.id)); cy.switchMode(ItemLayoutMode.List); - const itemToEdit = SAMPLE_ITEMS.items[2]; - // edit editItem( { @@ -112,38 +103,19 @@ describe('Edit Folder', () => { expect(name).to.equal(EDITED_FIELDS.name); cy.get('@getItem') .its('response.url') - .should('contain', SAMPLE_ITEMS.items[0].id); + .should('contain', itemToEdit.id); }, ); }); }); describe('Grid', () => { - describe('View Page', () => { - // bug: does not work in ci - // it('edit caption', () => { - // const item = SAMPLE_ITEMS.items[0]; - // const { id } = item; - // cy.setUpApi({ items: [item] }); - // cy.visit(buildItemPath(id)); - // cy.switchMode(ItemLayoutMode.Grid); - // const caption = 'new caption'; - // editCaptionFromViewPage({ id, caption }); - // cy.wait(`@editItem`).then(({ request: { url: endpointUrl, body } }) => { - // expect(endpointUrl).to.contain(id); - // // caption content might be wrapped with html tags - // expect(body?.description).to.contain(caption); - // }); - // }); - }); - it('edit folder on Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + const itemToEdit = PackedFolderItemFactory(); + cy.setUpApi({ items: [itemToEdit] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); - const itemToEdit = SAMPLE_ITEMS.items[0]; - // edit editItem( { @@ -169,13 +141,13 @@ describe('Edit Folder', () => { }); it('edit folder in item', () => { - cy.setUpApi(SAMPLE_ITEMS); + const parentItem = PackedFolderItemFactory(); + const itemToEdit = PackedFolderItemFactory({ parentItem }); + cy.setUpApi({ items: [parentItem, itemToEdit] }); // go to children item - cy.visit(buildItemPath(SAMPLE_ITEMS.items[0].id)); + cy.visit(buildItemPath(itemToEdit.id)); cy.switchMode(ItemLayoutMode.Grid); - const itemToEdit = SAMPLE_ITEMS.items[2]; - // edit editItem( { @@ -197,7 +169,7 @@ describe('Edit Folder', () => { expect(name).to.equal(EDITED_FIELDS.name); cy.get('@getItem') .its('response.url') - .should('contain', SAMPLE_ITEMS.items[0].id); + .should('contain', itemToEdit.id); }, ); }); diff --git a/cypress/e2e/item/edit/editH5p.cy.ts b/cypress/e2e/item/edit/editH5p.cy.ts index 03f451c45..9b6330cd4 100644 --- a/cypress/e2e/item/edit/editH5p.cy.ts +++ b/cypress/e2e/item/edit/editH5p.cy.ts @@ -1,10 +1,16 @@ +import { PackedH5PItemFactory } from '@graasp/sdk'; + import { HOME_PATH } from '../../../../src/config/paths'; import { ItemLayoutMode } from '../../../../src/enums'; -import { GRAASP_H5P_ITEM } from '../../../fixtures/h5p'; -import { EDITED_FIELDS } from '../../../fixtures/items'; import { EDIT_ITEM_PAUSE } from '../../../support/constants'; import { editItem } from '../../../support/editUtils'; +const EDITED_FIELDS = { + name: 'new name', +}; + +const GRAASP_H5P_ITEM = PackedH5PItemFactory(); + describe('Edit H5P', () => { beforeEach(() => { cy.setUpApi({ items: [GRAASP_H5P_ITEM] }); diff --git a/cypress/e2e/item/edit/editLink.cy.ts b/cypress/e2e/item/edit/editLink.cy.ts index 5800db72a..bafc0676c 100644 --- a/cypress/e2e/item/edit/editLink.cy.ts +++ b/cypress/e2e/item/edit/editLink.cy.ts @@ -1,3 +1,5 @@ +import { PackedLinkItemFactory, buildLinkExtra } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { EDIT_ITEM_MODAL_CANCEL_BUTTON_ID, @@ -7,17 +9,33 @@ import { buildEditButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { EDITED_FIELDS } from '../../../fixtures/items'; -import { GRAASP_LINK_ITEM, YOUTUBE_LINK_ITEM } from '../../../fixtures/links'; +import { CURRENT_USER } from '../../../fixtures/members'; import { EDIT_ITEM_PAUSE, ITEM_LOADING_PAUSE, } from '../../../support/constants'; import { editCaptionFromViewPage, editItem } from '../../../support/editUtils'; +const EDITED_FIELDS = { + name: 'new name', +}; + +const GRAASP_LINK_ITEM = PackedLinkItemFactory({ + creator: CURRENT_USER, + description: 'my link', + extra: buildLinkExtra({ + url: 'https://graasp.eu', + html: '', + thumbnails: ['https://graasp.eu/img/epfl/logo-tile.png'], + icons: [ + 'https://graasp.eu/cdn/img/epfl/favicons/favicon-32x32.png?v=yyxJ380oWY', + ], + }), +}); + describe('Edit Link', () => { beforeEach(() => { - cy.setUpApi({ items: [GRAASP_LINK_ITEM, YOUTUBE_LINK_ITEM] }); + cy.setUpApi({ items: [GRAASP_LINK_ITEM] }); }); describe('View Page', () => { diff --git a/cypress/e2e/item/edit/editShortcut.cy.ts b/cypress/e2e/item/edit/editShortcut.cy.ts index 6627f321b..b69ba3956 100644 --- a/cypress/e2e/item/edit/editShortcut.cy.ts +++ b/cypress/e2e/item/edit/editShortcut.cy.ts @@ -1,13 +1,19 @@ +import { PackedShortcutItemFactory } from '@graasp/sdk'; + import { HOME_PATH } from '../../../../src/config/paths'; import { ItemLayoutMode } from '../../../../src/enums'; -import { EDITED_FIELDS, SHORTCUT } from '../../../fixtures/items'; -import { GRAASP_LINK_ITEM, YOUTUBE_LINK_ITEM } from '../../../fixtures/links'; import { EDIT_ITEM_PAUSE } from '../../../support/constants'; import { editItem } from '../../../support/editUtils'; +const EDITED_FIELDS = { + name: 'new name', +}; + +const SHORTCUT = PackedShortcutItemFactory(); + describe('Edit Shortcut', () => { beforeEach(() => { - cy.setUpApi({ items: [SHORTCUT, GRAASP_LINK_ITEM, YOUTUBE_LINK_ITEM] }); + cy.setUpApi({ items: [SHORTCUT] }); }); describe('List', () => { diff --git a/cypress/e2e/item/flag/flagItem.cy.ts b/cypress/e2e/item/flag/flagItem.cy.ts index 27ded1f86..bfc6a09c1 100644 --- a/cypress/e2e/item/flag/flagItem.cy.ts +++ b/cypress/e2e/item/flag/flagItem.cy.ts @@ -1,4 +1,4 @@ -import { FlagType } from '@graasp/sdk'; +import { FlagType, PackedFolderItemFactory } from '@graasp/sdk'; import i18n, { BUILDER_NAMESPACE } from '../../../../src/config/i18n'; import { HOME_PATH } from '../../../../src/config/paths'; @@ -9,10 +9,11 @@ import { buildItemMenuButtonId, } from '../../../../src/config/selectors'; import { BUILDER } from '../../../../src/langs/constants'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; import { CURRENT_USER } from '../../../fixtures/members'; const openFlagItemModal = (itemId: string) => { + // todo: remove on table refactor + cy.wait(500); const menuSelector = `#${buildItemMenuButtonId(itemId)}`; cy.get(menuSelector).click(); @@ -37,14 +38,16 @@ const flagItem = (itemId: string, type: FlagType) => { flagItemButton.click(); }; +const FOLDER = PackedFolderItemFactory(); + describe('Flag Item', () => { beforeEach(() => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items: [FOLDER] }); cy.visit(HOME_PATH); }); it('flag item', () => { - const item = SAMPLE_ITEMS.items[0]; + const item = FOLDER; const type = FlagType.FalseInformation; flagItem(item.id, type); diff --git a/cypress/e2e/item/hide/hideItem.cy.ts b/cypress/e2e/item/hide/hideItem.cy.ts index 21b2375c8..3c93be7ac 100644 --- a/cypress/e2e/item/hide/hideItem.cy.ts +++ b/cypress/e2e/item/hide/hideItem.cy.ts @@ -1,4 +1,8 @@ -import { ItemTagType } from '@graasp/sdk'; +import { + ItemTagType, + PackedFolderItemFactory, + PermissionLevel, +} from '@graasp/sdk'; import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { @@ -8,13 +12,49 @@ import { buildItemMenuButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { - CHILD_HIDDEN_ITEM, - HIDDEN_ITEM, - ITEMS_SETTINGS, -} from '../../../fixtures/items'; +import { MEMBERS } from '../../../fixtures/members'; +import { ItemForTest } from '../../../support/types'; + +const hiddenItem = PackedFolderItemFactory( + {}, + { hiddenTag: { type: ItemTagType.Hidden } }, +); +const HIDDEN_ITEM: ItemForTest = { + ...hiddenItem, + memberships: [ + { + item: hiddenItem, + permission: PermissionLevel.Admin, + member: MEMBERS.ANNA, + creator: MEMBERS.ANNA, + id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', + createdAt: '2021-08-11T12:56:36.834Z', + updatedAt: '2021-08-11T12:56:36.834Z', + }, + { + item: hiddenItem, + permission: PermissionLevel.Read, + member: MEMBERS.BOB, + creator: MEMBERS.ANNA, + id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', + createdAt: '2021-08-11T12:56:36.834Z', + updatedAt: '2021-08-11T12:56:36.834Z', + }, + ], +}; + +const CHILD_HIDDEN_ITEM = PackedFolderItemFactory({ parentItem: HIDDEN_ITEM }); + +const ITEM = PackedFolderItemFactory( + {}, + { + permission: PermissionLevel.Admin, + }, +); const toggleHideButton = (itemId: string, isHidden = false) => { + // todo: remove on table refactor + cy.wait(500); const menuSelector = `#${buildItemMenuButtonId(itemId)}`; cy.get(menuSelector).click(); @@ -26,19 +66,18 @@ const toggleHideButton = (itemId: string, isHidden = false) => { describe('Hiding Item', () => { describe('Successfully hide item in List', () => { beforeEach(() => { - cy.setUpApi(ITEMS_SETTINGS); + cy.setUpApi({ items: [ITEM, HIDDEN_ITEM, CHILD_HIDDEN_ITEM] }); }); it('Hide an item', () => { cy.visit(HOME_PATH); - const item = ITEMS_SETTINGS.items[1]; - toggleHideButton(item.id, false); + toggleHideButton(ITEM.id, false); cy.wait(`@postItemTag-${ItemTagType.Hidden}`).then( ({ request: { url } }) => { expect(url).to.contain(ItemTagType.Hidden); - expect(url).to.contain(item.id); + expect(url).to.contain(ITEM.id); }, ); }); @@ -73,13 +112,13 @@ describe('Hiding Item', () => { describe('Successfully hide item in Grid', () => { beforeEach(() => { - cy.setUpApi(ITEMS_SETTINGS); + cy.setUpApi({ items: [ITEM, HIDDEN_ITEM, CHILD_HIDDEN_ITEM] }); }); it('Hide an item', () => { cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); - const item = ITEMS_SETTINGS.items[1]; + const item = ITEM; toggleHideButton(item.id, false); @@ -94,7 +133,7 @@ describe('Hiding Item', () => { it('Show an Item', () => { cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); - const item = ITEMS_SETTINGS.items[0]; + const item = HIDDEN_ITEM; toggleHideButton(item.id, true); diff --git a/cypress/e2e/item/home/home.cy.ts b/cypress/e2e/item/home/home.cy.ts index 79c15c428..3f8d32989 100644 --- a/cypress/e2e/item/home/home.cy.ts +++ b/cypress/e2e/item/home/home.cy.ts @@ -1,3 +1,8 @@ +import { + PackedFolderItemFactory, + PackedLocalFileItemFactory, +} from '@graasp/sdk'; + import { ITEM_PAGE_SIZE } from '@/config/constants'; import i18n from '../../../../src/config/i18n'; @@ -14,12 +19,22 @@ import { buildItemsTableRowSelector, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { SAMPLE_ITEMS, generateOwnItems } from '../../../fixtures/items'; +import { generateOwnItems } from '../../../fixtures/items'; import { CURRENT_USER } from '../../../fixtures/members'; import { NAVIGATION_LOAD_PAUSE } from '../../../support/constants'; import { ItemForTest } from '../../../support/types'; -const sampleItems = generateOwnItems(30); +const ownItems = generateOwnItems(30); + +const IMAGE_ITEM = PackedLocalFileItemFactory(); +const FOLDER = PackedFolderItemFactory(); +const FOLDER_CHILD = PackedFolderItemFactory({ parentItem: FOLDER }); +const IMAGE_ITEM_CHILD = PackedLocalFileItemFactory({ + parentItem: FOLDER, +}); +const FOLDER2 = PackedFolderItemFactory(); + +const ITEMS = [IMAGE_ITEM, FOLDER, FOLDER2, FOLDER_CHILD, IMAGE_ITEM_CHILD]; // register a custom one time interceptor to listen specifically // to the request made with the search parameter we want @@ -36,7 +51,7 @@ describe('Home', () => { describe('Features', () => { beforeEach(() => { cy.setUpApi({ - items: sampleItems, + items: generateOwnItems(30), }); i18n.changeLanguage(CURRENT_USER.extra.lang as string); cy.visit(HOME_PATH); @@ -91,7 +106,7 @@ describe('Home', () => { expect(query.name).to.eq(searchText); expect(query.page).to.eq('1'); }); - cy.get(`#${buildItemCard(sampleItems[0].id)}`).should('be.visible'); + cy.get(`#${buildItemCard(ownItems[0].id)}`).should('be.visible'); }); }); @@ -130,14 +145,14 @@ describe('Home', () => { it('shows only items of each page', () => { // using default items per page count - checkGridPagination(sampleItems); + checkGridPagination(ownItems); }); }); }); describe('Navigation', () => { beforeEach(() => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items: ITEMS }); i18n.changeLanguage(CURRENT_USER.extra.lang as string); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); @@ -145,7 +160,6 @@ describe('Home', () => { it('visit Home', () => { cy.wait('@getAccessibleItems').then(({ response: { body } }) => { - cy.wait('@getItemMemberships'); // check item is created and displayed for (const item of body.data) { cy.get(`#${buildItemCard(item.id)}`).should('exist'); @@ -153,7 +167,7 @@ describe('Home', () => { }); // visit child - const { id: childId } = SAMPLE_ITEMS.items[0]; + const { id: childId } = FOLDER; cy.goToItemInGrid(childId); // should get children @@ -165,7 +179,7 @@ describe('Home', () => { }); // visit child - const { id: childChildId } = SAMPLE_ITEMS.items[3]; + const { id: childChildId } = FOLDER_CHILD; cy.goToItemInGrid(childChildId); // expect no children @@ -177,11 +191,7 @@ describe('Home', () => { // should get children cy.wait('@getChildren').then(() => { // check item is created and displayed - for (const item of [ - SAMPLE_ITEMS.items[2], - SAMPLE_ITEMS.items[3], - SAMPLE_ITEMS.items[4], - ]) { + for (const item of [IMAGE_ITEM_CHILD, FOLDER_CHILD]) { cy.get(`#${buildItemCard(item.id)}`).should('exist'); } }); @@ -192,14 +202,14 @@ describe('Home', () => { describe('List', () => { describe('Navigation', () => { beforeEach(() => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items: ITEMS }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); }); it('visit Home', () => { // visit child - const { id: childId } = SAMPLE_ITEMS.items[0]; + const { id: childId } = FOLDER; cy.goToItemInList(childId); // should get children @@ -211,7 +221,7 @@ describe('Home', () => { }); // visit child - const { id: childChildId } = SAMPLE_ITEMS.items[3]; + const { id: childChildId } = FOLDER_CHILD; cy.goToItemInList(childChildId); // expect no children @@ -232,7 +242,7 @@ describe('Home', () => { describe('Features', () => { beforeEach(() => { cy.setUpApi({ - items: sampleItems, + items: generateOwnItems(30), }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); diff --git a/cypress/e2e/item/move/gridMoveItem.cy.ts b/cypress/e2e/item/move/gridMoveItem.cy.ts index d162f7096..647fa3fbd 100644 --- a/cypress/e2e/item/move/gridMoveItem.cy.ts +++ b/cypress/e2e/item/move/gridMoveItem.cy.ts @@ -1,3 +1,8 @@ +import { + PackedFolderItemFactory, + PackedLocalFileItemFactory, +} from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEM_MENU_MOVE_BUTTON_CLASS, @@ -6,7 +11,6 @@ import { buildItemMenuButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; const moveItem = ({ id: movedItemId, @@ -24,15 +28,22 @@ const moveItem = ({ cy.handleTreeMenu(toItemPath); }; +const IMAGE_ITEM = PackedLocalFileItemFactory(); +const FOLDER = PackedFolderItemFactory(); +const IMAGE_ITEM_CHILD = PackedLocalFileItemFactory({ parentItem: FOLDER }); +const FOLDER2 = PackedFolderItemFactory(); + +const items = [IMAGE_ITEM, FOLDER, FOLDER2, IMAGE_ITEM_CHILD]; + describe('Move Item in Grid', () => { it('move item from Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); // move - const { id: movedItem } = SAMPLE_ITEMS.items[0]; - const { id: toItem, path: toItemPath } = SAMPLE_ITEMS.items[1]; + const { id: movedItem } = FOLDER2; + const { id: toItem, path: toItemPath } = FOLDER; moveItem({ id: movedItem, toItemPath }); cy.wait('@moveItems').then(({ request: { url, body } }) => { @@ -42,16 +53,15 @@ describe('Move Item in Grid', () => { }); it('move item from item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); // go to children item - cy.visit(buildItemPath(id)); + cy.visit(buildItemPath(FOLDER.id)); cy.switchMode(ItemLayoutMode.Grid); // move - const { id: movedItem } = SAMPLE_ITEMS.items[2]; - const { id: toItem, path: toItemPath } = SAMPLE_ITEMS.items[1]; + const { id: movedItem } = IMAGE_ITEM_CHILD; + const { id: toItem, path: toItemPath } = FOLDER2; moveItem({ id: movedItem, toItemPath }); cy.wait('@moveItems').then(({ request: { body, url } }) => { @@ -61,15 +71,14 @@ describe('Move Item in Grid', () => { }); it('move item to Home', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); // go to children item - cy.visit(buildItemPath(id)); + cy.visit(buildItemPath(FOLDER.id)); cy.switchMode(ItemLayoutMode.Grid); // move - const { id: movedItem } = SAMPLE_ITEMS.items[2]; + const { id: movedItem } = IMAGE_ITEM_CHILD; moveItem({ id: movedItem, toItemPath: MY_GRAASP_ITEM_PATH }); cy.wait('@moveItems').then(({ request: { body, url } }) => { diff --git a/cypress/e2e/item/move/listMoveItem.cy.ts b/cypress/e2e/item/move/listMoveItem.cy.ts index 2637c4f6e..4b3d1e256 100644 --- a/cypress/e2e/item/move/listMoveItem.cy.ts +++ b/cypress/e2e/item/move/listMoveItem.cy.ts @@ -1,3 +1,8 @@ +import { + PackedFolderItemFactory, + PackedLocalFileItemFactory, +} from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEM_MENU_MOVE_BUTTON_CLASS, @@ -7,9 +12,18 @@ import { buildNavigationModalItemId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; + +const IMAGE_ITEM = PackedLocalFileItemFactory(); +const FOLDER = PackedFolderItemFactory(); +const CHILD = PackedFolderItemFactory({ parentItem: FOLDER }); +const CHILD_CHILD = PackedFolderItemFactory({ parentItem: CHILD }); +const FOLDER2 = PackedFolderItemFactory(); + +const items = [IMAGE_ITEM, FOLDER, FOLDER2, CHILD, CHILD_CHILD]; const openMoveModal = ({ id: movedItemId }: { id: string }) => { + // todo: remove on table refactor + cy.wait(1000); cy.get(`#${buildItemMenuButtonId(movedItemId)}`).click(); cy.get( `#${buildItemMenu(movedItemId)} .${ITEM_MENU_MOVE_BUTTON_CLASS}`, @@ -26,20 +40,19 @@ const moveItem = ({ rootId?: string; }) => { openMoveModal({ id: movedItemId }); - cy.handleTreeMenu(toItemPath, rootId); }; describe('Move Item in List', () => { it('move item on Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); // move - const { id: movedItem } = SAMPLE_ITEMS.items[0]; - const { id: toItem, path: toItemPath } = SAMPLE_ITEMS.items[1]; + const { id: movedItem } = FOLDER2; + const { id: toItem, path: toItemPath } = FOLDER; moveItem({ id: movedItem, toItemPath }); cy.wait('@moveItems').then(({ request: { url, body } }) => { @@ -49,8 +62,8 @@ describe('Move Item in List', () => { }); it('move item in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); @@ -58,8 +71,8 @@ describe('Move Item in List', () => { cy.switchMode(ItemLayoutMode.List); // move - const { id: movedItem } = SAMPLE_ITEMS.items[2]; - const { id: toItem, path: toItemPath } = SAMPLE_ITEMS.items[1]; + const { id: movedItem } = CHILD; + const { id: toItem, path: toItemPath } = FOLDER2; moveItem({ id: movedItem, toItemPath }); cy.wait('@moveItems').then(({ request: { body, url } }) => { @@ -69,18 +82,20 @@ describe('Move Item in List', () => { }); it('cannot move inside self children', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.List); - const { id: movedItemId } = SAMPLE_ITEMS.items[2]; - const parentId = SAMPLE_ITEMS.items[0].id; - const childId = SAMPLE_ITEMS.items[6].id; + const { id: movedItemId } = CHILD; + const { id: parentId } = FOLDER; + const { id: childId } = CHILD_CHILD; + openMoveModal({ id: movedItemId }); + // parent is disabled cy.get(`#${buildNavigationModalItemId(parentId)} button`).should( 'be.disabled', @@ -100,8 +115,8 @@ describe('Move Item in List', () => { }); it('move item to Home', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id } = FOLDER; // go to children item cy.visit(buildItemPath(id)); @@ -109,7 +124,7 @@ describe('Move Item in List', () => { cy.switchMode(ItemLayoutMode.List); // move - const { id: movedItem } = SAMPLE_ITEMS.items[2]; + const { id: movedItem } = CHILD; moveItem({ id: movedItem, toItemPath: MY_GRAASP_ITEM_PATH }); cy.wait('@moveItems').then(({ request: { body, url } }) => { diff --git a/cypress/e2e/item/move/listMoveMultiple.cy.ts b/cypress/e2e/item/move/listMoveMultiple.cy.ts index 63696da63..09e3befbb 100644 --- a/cypress/e2e/item/move/listMoveMultiple.cy.ts +++ b/cypress/e2e/item/move/listMoveMultiple.cy.ts @@ -1,3 +1,8 @@ +import { + PackedFolderItemFactory, + PackedLocalFileItemFactory, +} from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { ITEMS_TABLE_MOVE_SELECTED_ITEMS_ID, @@ -5,7 +10,6 @@ import { buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; const moveItems = ({ itemIds, @@ -23,16 +27,34 @@ const moveItems = ({ cy.handleTreeMenu(toItemPath); }; +const IMAGE_ITEM = PackedLocalFileItemFactory(); +const FOLDER = PackedFolderItemFactory(); +const IMAGE_ITEM_CHILD = PackedLocalFileItemFactory({ parentItem: FOLDER }); +const IMAGE_ITEM_CHILD2 = PackedLocalFileItemFactory({ parentItem: FOLDER }); +const FOLDER_CHILD = PackedFolderItemFactory({ parentItem: FOLDER }); +const FOLDER2 = PackedFolderItemFactory(); +const FOLDER3 = PackedFolderItemFactory(); + +const items = [ + IMAGE_ITEM, + FOLDER, + FOLDER3, + FOLDER2, + IMAGE_ITEM_CHILD, + IMAGE_ITEM_CHILD2, + FOLDER_CHILD, +]; + describe('Move Items in List', () => { it('Move items on Home', () => { - cy.setUpApi(SAMPLE_ITEMS); + cy.setUpApi({ items }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.List); // move - const itemIds = [SAMPLE_ITEMS.items[0].id, SAMPLE_ITEMS.items[5].id]; - const { id: toItem, path: toItemPath } = SAMPLE_ITEMS.items[1]; + const itemIds = [FOLDER3.id, FOLDER2.id]; + const { id: toItem, path: toItemPath } = FOLDER; moveItems({ itemIds, toItemPath }); cy.wait('@moveItems').then(({ request: { url, body } }) => { @@ -42,8 +64,8 @@ describe('Move Items in List', () => { }); it('Move items in item', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id: start } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id: start } = FOLDER; // go to children item cy.visit(buildItemPath(start)); @@ -51,8 +73,8 @@ describe('Move Items in List', () => { cy.switchMode(ItemLayoutMode.List); // move - const itemIds = [SAMPLE_ITEMS.items[2].id, SAMPLE_ITEMS.items[4].id]; - const { id: toItem, path: toItemPath } = SAMPLE_ITEMS.items[1]; + const itemIds = [IMAGE_ITEM_CHILD.id, IMAGE_ITEM_CHILD2.id]; + const { id: toItem, path: toItemPath } = FOLDER_CHILD; moveItems({ itemIds, toItemPath }); cy.wait('@moveItems').then(({ request: { body, url } }) => { @@ -62,8 +84,8 @@ describe('Move Items in List', () => { }); it('Move items to Home', () => { - cy.setUpApi(SAMPLE_ITEMS); - const { id: start } = SAMPLE_ITEMS.items[0]; + cy.setUpApi({ items }); + const { id: start } = FOLDER; // go to children item cy.visit(buildItemPath(start)); @@ -71,7 +93,7 @@ describe('Move Items in List', () => { cy.switchMode(ItemLayoutMode.List); // move - const itemIds = [SAMPLE_ITEMS.items[2].id, SAMPLE_ITEMS.items[4].id]; + const itemIds = [IMAGE_ITEM_CHILD.id, IMAGE_ITEM_CHILD2.id]; moveItems({ itemIds, toItemPath: MY_GRAASP_ITEM_PATH }); cy.wait('@moveItems').then(({ request: { body, url } }) => { diff --git a/cypress/e2e/item/order/reorderItems.cy.ts b/cypress/e2e/item/order/reorderItems.cy.ts index 233b8b258..195a2c65a 100644 --- a/cypress/e2e/item/order/reorderItems.cy.ts +++ b/cypress/e2e/item/order/reorderItems.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { buildItemPath } from '../../../../src/config/paths'; import { ROW_DRAGGER_CLASS, @@ -5,9 +7,16 @@ import { buildItemsTableRowId, buildItemsTableRowSelector, } from '../../../../src/config/selectors'; -import { ITEM_REORDER_ITEMS } from '../../../fixtures/items'; import { ROW_HEIGHT } from '../../../support/constants'; +const PARENT = PackedFolderItemFactory(); +const CHILDREN = [ + PackedFolderItemFactory({ parentItem: PARENT }), + PackedFolderItemFactory({ parentItem: PARENT }), + PackedFolderItemFactory({ parentItem: PARENT }), +]; +const ITEM_REORDER_ITEMS = [PARENT, ...CHILDREN]; + const reorderAndCheckItem = ( id: string, currentPosition: number, @@ -36,9 +45,9 @@ describe('Order Items', () => { describe('Move Item', () => { beforeEach(() => { cy.setUpApi({ - items: [ITEM_REORDER_ITEMS.parent, ...ITEM_REORDER_ITEMS.children], + items: ITEM_REORDER_ITEMS, }); - cy.visit(buildItemPath(ITEM_REORDER_ITEMS.parent.id)); + cy.visit(buildItemPath(PARENT.id)); }); // flaky test is skipped @@ -46,7 +55,7 @@ describe('Order Items', () => { const currentPosition = 0; const newPosition = 1; - const { id: childId } = ITEM_REORDER_ITEMS.children[currentPosition]; + const { id: childId } = CHILDREN[currentPosition]; reorderAndCheckItem(childId, currentPosition, newPosition); }); @@ -56,7 +65,7 @@ describe('Order Items', () => { const currentPosition = 0; const newPosition = 2; - const { id: childId } = ITEM_REORDER_ITEMS.children[currentPosition]; + const { id: childId } = CHILDREN[currentPosition]; reorderAndCheckItem(childId, currentPosition, newPosition); }); @@ -66,7 +75,7 @@ describe('Order Items', () => { const currentPosition = 1; const newPosition = 0; - const { id: childId } = ITEM_REORDER_ITEMS.children[currentPosition]; + const { id: childId } = CHILDREN[currentPosition]; reorderAndCheckItem(childId, currentPosition, newPosition); }); @@ -75,14 +84,14 @@ describe('Order Items', () => { describe('Check Order', () => { it('check item order in folder with non-existing item in ordering', () => { cy.setUpApi({ - items: [ITEM_REORDER_ITEMS.parent, ...ITEM_REORDER_ITEMS.children], + items: ITEM_REORDER_ITEMS, }); - cy.visit(buildItemPath(ITEM_REORDER_ITEMS.parent.id)); + cy.visit(buildItemPath(PARENT.id)); - const tableBody = `#${buildItemsTableId(ITEM_REORDER_ITEMS.parent.id)}`; + const tableBody = `#${buildItemsTableId(PARENT.id)}`; - ITEM_REORDER_ITEMS.children.forEach(({ id }, index) => { + CHILDREN.forEach(({ id }, index) => { // this will find multiple row instances because ag-grid renders several // this should be okay as all of them should have the same row-index cy.get(tableBody) diff --git a/cypress/e2e/item/pin/pinItem.cy.ts b/cypress/e2e/item/pin/pinItem.cy.ts index f11f0c95f..7403721c5 100644 --- a/cypress/e2e/item/pin/pinItem.cy.ts +++ b/cypress/e2e/item/pin/pinItem.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; import { PIN_ITEM_BUTTON_CLASS, @@ -6,21 +8,21 @@ import { buildItemMenuButtonId, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { - ITEMS_SETTINGS, - PINNED_ITEM, - PUBLISHED_ITEM, -} from '../../../fixtures/items'; const togglePinButton = (itemId: string) => { + // todo: remove on table refactor + cy.wait(500); cy.get(`#${buildItemMenuButtonId(itemId)}`).click(); cy.get(`#${buildItemMenu(itemId)} .${PIN_ITEM_BUTTON_CLASS}`).click(); }; +const PINNED_ITEM = PackedFolderItemFactory({ settings: { isPinned: true } }); +const ITEM = PackedFolderItemFactory({ settings: { isPinned: false } }); + describe('Anonymous', () => { - const itemId = PUBLISHED_ITEM.id; + const itemId = ITEM.id; beforeEach(() => { - cy.setUpApi({ currentMember: null, items: [PUBLISHED_ITEM] }); + cy.setUpApi({ currentMember: null, items: [ITEM] }); cy.visit(buildItemPath(itemId)); }); it("Can see item but can't pin", () => { @@ -32,12 +34,12 @@ describe('Anonymous', () => { describe('Pinning Item', () => { describe('Successfully pinning item in List', () => { beforeEach(() => { - cy.setUpApi(ITEMS_SETTINGS); + cy.setUpApi({ items: [PINNED_ITEM, ITEM] }); cy.visit(HOME_PATH); }); it('Pin an item', () => { - const item = ITEMS_SETTINGS.items[0]; + const item = ITEM; togglePinButton(item.id); @@ -71,13 +73,13 @@ describe('Pinning Item', () => { describe('Successfully pinning item in Grid', () => { beforeEach(() => { - cy.setUpApi(ITEMS_SETTINGS); + cy.setUpApi({ items: [PINNED_ITEM, ITEM] }); cy.visit(HOME_PATH); cy.switchMode(ItemLayoutMode.Grid); }); it('Pin an item', () => { - const item = ITEMS_SETTINGS.items[0]; + const item = ITEM; togglePinButton(item.id); diff --git a/cypress/e2e/item/publish/ccLicense.cy.ts b/cypress/e2e/item/publish/ccLicense.cy.ts index 736443c48..7e59ec06f 100644 --- a/cypress/e2e/item/publish/ccLicense.cy.ts +++ b/cypress/e2e/item/publish/ccLicense.cy.ts @@ -1,3 +1,5 @@ +import { ItemTagType, PackedFolderItemFactory } from '@graasp/sdk'; + import { buildItemPath } from '../../../../src/config/paths'; import { CC_ALLOW_COMMERCIAL_CONTROL_ID, @@ -9,9 +11,105 @@ import { CC_SHARE_ALIKE_CONTROL_ID, buildPublishButtonId, } from '../../../../src/config/selectors'; -import { PUBLISHED_ITEMS_WITH_CC_LICENSE } from '../../../fixtures/items'; +import { MEMBERS } from '../../../fixtures/members'; import { ItemForTest } from '../../../support/types'; +const itemCCLicenseCCBY = PackedFolderItemFactory({ + name: 'public item with cc by', + settings: { ccLicenseAdaption: 'CC BY' }, +}); +const itemCCLicenseCCBYNC = PackedFolderItemFactory({ + name: 'public item with cc by nc', + settings: { ccLicenseAdaption: 'CC BY-NC' }, +}); +const itemCCLicenseCCBYSA = PackedFolderItemFactory({ + name: 'public item with cc by sa', + settings: { ccLicenseAdaption: 'CC BY-SA' }, +}); +const itemCCLicenseCCBYNCND = PackedFolderItemFactory({ + name: 'public item with cc by nc nd', + settings: { ccLicenseAdaption: 'CC BY-NC-ND' }, +}); + +const PUBLISHED_ITEMS_WITH_CC_LICENSE: ItemForTest[] = [ + { + ...itemCCLicenseCCBY, + tags: [ + { + id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', + type: ItemTagType.Public, + item: itemCCLicenseCCBY, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + }, + ], + published: { + id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', + item: itemCCLicenseCCBY, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + totalViews: 0, + }, + }, + { + ...itemCCLicenseCCBYNC, + tags: [ + { + id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', + type: ItemTagType.Public, + item: itemCCLicenseCCBYNC, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + }, + ], + published: { + id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', + item: itemCCLicenseCCBYNC, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + totalViews: 0, + }, + }, + { + ...itemCCLicenseCCBYSA, + tags: [ + { + id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', + type: ItemTagType.Public, + item: itemCCLicenseCCBYSA, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + }, + ], + published: { + id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', + item: itemCCLicenseCCBYSA, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + totalViews: 0, + }, + }, + { + ...itemCCLicenseCCBYNCND, + tags: [ + { + id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', + type: ItemTagType.Public, + item: itemCCLicenseCCBYNCND, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + }, + ], + published: { + id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', + item: itemCCLicenseCCBYNCND, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + totalViews: 0, + }, + }, +]; + const openPublishItemTab = (id: string) => { cy.get(`#${buildPublishButtonId(id)}`).click(); }; diff --git a/cypress/e2e/item/publish/coEditorSettings.cy.ts b/cypress/e2e/item/publish/coEditorSettings.cy.ts index 3b318fa82..8672151c9 100644 --- a/cypress/e2e/item/publish/coEditorSettings.cy.ts +++ b/cypress/e2e/item/publish/coEditorSettings.cy.ts @@ -1,3 +1,5 @@ +import { ItemTagType, PackedFolderItemFactory } from '@graasp/sdk'; + import { DISPLAY_CO_EDITORS_OPTIONS, SETTINGS, @@ -11,7 +13,6 @@ import { buildPublishButtonId, } from '../../../../src/config/selectors'; import { ITEM_WITH_CATEGORIES_CONTEXT } from '../../../fixtures/categories'; -import { PUBLISHED_ITEM } from '../../../fixtures/items'; import { MEMBERS, SIGNED_OUT_MEMBER } from '../../../fixtures/members'; import { EDIT_TAG_REQUEST_TIMEOUT } from '../../../support/constants'; @@ -63,9 +64,13 @@ describe('Co-editor Setting', () => { }); }); -describe('Co-editor setting permissions', () => { +const item = PackedFolderItemFactory( + {}, + { permission: null, publicTag: { type: ItemTagType.Public } }, +); + +describe.only('Co-editor setting permissions', () => { it('User signed out cannot edit co-editor setting', () => { - const item = PUBLISHED_ITEM; cy.setUpApi({ items: [item], currentMember: SIGNED_OUT_MEMBER, @@ -79,7 +84,6 @@ describe('Co-editor setting permissions', () => { }); it('Read-only user cannot edit co-editor setting', () => { - const item = PUBLISHED_ITEM; cy.setUpApi({ items: [item], currentMember: MEMBERS.BOB, diff --git a/cypress/e2e/item/publish/publishedItem.cy.ts b/cypress/e2e/item/publish/publishedItem.cy.ts index 059ae759d..1bad4ca76 100644 --- a/cypress/e2e/item/publish/publishedItem.cy.ts +++ b/cypress/e2e/item/publish/publishedItem.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory, PermissionLevel } from '@graasp/sdk'; + import { buildItemPath } from '../../../../src/config/paths'; import { ITEM_PUBLISH_BUTTON_ID, @@ -8,8 +10,6 @@ import { import { PUBLISHED_ITEM, PUBLISHED_ITEM_VALIDATIONS, - SAMPLE_ITEMS, - SAMPLE_PUBLIC_ITEMS, } from '../../../fixtures/items'; import { MEMBERS } from '../../../fixtures/members'; import { PAGE_LOAD_WAITING_PAUSE } from '../../../support/constants'; @@ -25,7 +25,10 @@ export const publishItem = (): void => { describe('Public', () => { it('Should not view publish tab', () => { - const item = SAMPLE_PUBLIC_ITEMS.items[0]; + const item = PackedFolderItemFactory( + {}, + { permission: null, publicTag: {} }, + ); cy.setUpApi({ items: [item], currentMember: null, @@ -40,7 +43,10 @@ describe('Public', () => { describe('Read', () => { it('Should not view publish tab', () => { - const item = SAMPLE_ITEMS.items[1]; + const item = PackedFolderItemFactory( + {}, + { permission: PermissionLevel.Read }, + ); cy.setUpApi({ items: [item], currentMember: MEMBERS.BOB, @@ -55,8 +61,12 @@ describe('Read', () => { describe('Public Item', () => { it('Validate item', () => { - cy.setUpApi(SAMPLE_PUBLIC_ITEMS); - const item = SAMPLE_ITEMS.items[0]; + const items = [ + PackedFolderItemFactory({}, { publicTag: {} }), + PackedFolderItemFactory(), + ]; + cy.setUpApi({ items }); + const item = items[0]; cy.visit(buildItemPath(item.id)); openPublishItemTab(item.id); diff --git a/cypress/e2e/item/publish/tags.cy.ts b/cypress/e2e/item/publish/tags.cy.ts index 097b89ddd..db25a2dcc 100644 --- a/cypress/e2e/item/publish/tags.cy.ts +++ b/cypress/e2e/item/publish/tags.cy.ts @@ -1,3 +1,9 @@ +import { + ItemTagType, + PackedFolderItemFactory, + PermissionLevel, +} from '@graasp/sdk'; + import { buildItemPath } from '../../../../src/config/paths'; import { ITEM_HEADER_ID, @@ -11,7 +17,7 @@ import { ITEM_WITH_CATEGORIES_CONTEXT, NEW_CUSTOMIZED_TAG, } from '../../../fixtures/categories'; -import { PUBLISHED_ITEM } from '../../../fixtures/items'; +import { PUBLISHED_ITEM_NO_TAGS } from '../../../fixtures/items'; import { MEMBERS, SIGNED_OUT_MEMBER } from '../../../fixtures/members'; import { EDIT_TAG_REQUEST_TIMEOUT } from '../../../support/constants'; import { ItemForTest } from '../../../support/types'; @@ -29,7 +35,7 @@ const visitItemPage = (item: ItemForTest) => { describe('Customized Tags', () => { it('Display item without tags', () => { // check for not displaying if no tags - const item = PUBLISHED_ITEM; + const item = PUBLISHED_ITEM_NO_TAGS; cy.setUpApi({ items: [item] }); cy.visit(buildItemPath(item.id)); openPublishItemTab(item.id); @@ -67,9 +73,31 @@ describe('Customized Tags', () => { describe('Tags permissions', () => { it('User signed out cannot edit tags', () => { - const item = PUBLISHED_ITEM; + const item = PackedFolderItemFactory( + {}, + { permission: null, publicTag: {} }, + ); + const publishedItem = { + ...item, + tags: [ + { + id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', + type: ItemTagType.Public, + item, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + }, + ], + published: { + id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', + item, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + totalViews: 0, + }, + }; cy.setUpApi({ - items: [item], + items: [publishedItem], currentMember: SIGNED_OUT_MEMBER, }); cy.visit(buildItemPath(item.id)); @@ -81,9 +109,31 @@ describe('Tags permissions', () => { }); it('Read-only user cannot edit tags', () => { - const item = PUBLISHED_ITEM; + const item = PackedFolderItemFactory( + {}, + { permission: PermissionLevel.Read, publicTag: {} }, + ); + const publishedItem = { + ...item, + tags: [ + { + id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', + type: ItemTagType.Public, + item, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + }, + ], + published: { + id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', + item, + createdAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.ANNA, + totalViews: 0, + }, + }; cy.setUpApi({ - items: [item], + items: [publishedItem], currentMember: MEMBERS.BOB, }); cy.visit(buildItemPath(item.id)); diff --git a/cypress/e2e/item/settings/itemSettings.cy.ts b/cypress/e2e/item/settings/itemSettings.cy.ts index ffa73eb92..ff7ef5bbb 100644 --- a/cypress/e2e/item/settings/itemSettings.cy.ts +++ b/cypress/e2e/item/settings/itemSettings.cy.ts @@ -2,13 +2,16 @@ import { DescriptionPlacement, ItemType, MaxWidth, + MimeTypes, + PackedFolderItemFactory, + PackedLinkItemFactory, + PackedLocalFileItemFactory, + PermissionLevel, formatFileSize, getFileExtra, } from '@graasp/sdk'; import { langs } from '@graasp/translations'; -import { getMemberById } from '@/utils/member'; - import { buildItemPath, buildItemSettingsPath, @@ -34,37 +37,31 @@ import { buildItemMenuButtonId, buildSettingsButtonId, } from '../../../../src/config/selectors'; -import { - ITEM_WITH_CHATBOX_MESSAGES, - ITEM_WITH_CHATBOX_MESSAGES_AND_ADMIN, -} from '../../../fixtures/chatbox'; -import { - IMAGE_ITEM_DEFAULT, - IMAGE_ITEM_DEFAULT_WITH_MAX_WIDTH, -} from '../../../fixtures/files'; -import { ITEMS_SETTINGS, SAMPLE_ITEMS } from '../../../fixtures/items'; -import { GRAASP_LINK_ITEM } from '../../../fixtures/links'; -import { MEMBERS } from '../../../fixtures/members'; +import { ITEM_WITH_CHATBOX_MESSAGES } from '../../../fixtures/chatbox'; +import { CURRENT_USER, MEMBERS } from '../../../fixtures/members'; import { EDIT_ITEM_PAUSE } from '../../../support/constants'; describe('Item Settings', () => { describe('read rights', () => { + const item = PackedFolderItemFactory( + {}, + { permission: PermissionLevel.Read }, + ); + beforeEach(() => { cy.setUpApi({ - ...SAMPLE_ITEMS, + items: [item], currentMember: MEMBERS.BOB, }); }); it('settings button does not open settings page', () => { - const item = SAMPLE_ITEMS.items[1]; // manual click to verify settings button works correctly cy.visit(buildItemPath(item.id)); cy.get(`#${buildSettingsButtonId(item.id)}`).should('not.exist'); }); it('settings page redirects to item', () => { - const item = SAMPLE_ITEMS.items[1]; // manual click to verify settings button works correctly cy.visit(buildItemSettingsPath(item.id)); cy.get(`.${ITEM_MAIN_CLASS}`).should('contain', item.name); @@ -72,59 +69,45 @@ describe('Item Settings', () => { }); describe('admin rights', () => { - beforeEach(() => { - cy.setUpApi({ - ...ITEMS_SETTINGS, - items: [ - ...ITEMS_SETTINGS.items, - GRAASP_LINK_ITEM, - ITEM_WITH_CHATBOX_MESSAGES, - ITEM_WITH_CHATBOX_MESSAGES_AND_ADMIN, - IMAGE_ITEM_DEFAULT, - IMAGE_ITEM_DEFAULT_WITH_MAX_WIDTH, - IMAGE_ITEM_DEFAULT, - ], - }); - }); - it('setting button opens settings page', () => { - const itemId = ITEMS_SETTINGS.items[1].id; + const item = PackedFolderItemFactory({ settings: { showChatbox: true } }); + cy.setUpApi({ items: [item] }); // manual click to verify settings button works correctly - cy.visit(buildItemPath(itemId)); - cy.get(`#${buildSettingsButtonId(itemId)}`).click(); + cy.visit(buildItemPath(item.id)); + cy.get(`#${buildSettingsButtonId(item.id)}`).click(); cy.get(`#${SETTINGS_CHATBOX_TOGGLE_ID}`).should('be.checked'); }); describe('Metadata table', () => { it('folder', () => { - const { id, name, type, creator } = ITEMS_SETTINGS.items[1]; + const item = PackedFolderItemFactory({ creator: MEMBERS.BOB }); + const { id, name, type, creator } = item; + cy.setUpApi({ items: [item] }); + cy.visit(buildItemSettingsPath(id)); cy.get(`#${ITEM_PANEL_NAME_ID}`).contains(name); cy.get(`#${ITEM_PANEL_TABLE_ID}`).contains(type); - const creatorName = getMemberById( - Object.values(MEMBERS), - creator?.id, - ).name; - - cy.get(`#${ITEM_PANEL_TABLE_ID}`).should('exist').contains(creatorName); + cy.get(`#${ITEM_PANEL_TABLE_ID}`) + .should('exist') + .contains(creator.name); }); it('file', () => { - const { id, name, type, extra, creator } = IMAGE_ITEM_DEFAULT; + const FILE = PackedLocalFileItemFactory({ creator: MEMBERS.BOB }); + cy.setUpApi({ items: [FILE] }); + + const { id, name, type, extra, creator } = FILE; cy.visit(buildItemSettingsPath(id)); cy.get(`#${ITEM_PANEL_NAME_ID}`).contains(name); cy.get(`#${ITEM_PANEL_TABLE_ID}`).contains(extra.file.mimetype); - const creatorName = getMemberById( - Object.values(MEMBERS), - creator?.id, - ).name; - - cy.get(`#${ITEM_PANEL_TABLE_ID}`).should('exist').contains(creatorName); + cy.get(`#${ITEM_PANEL_TABLE_ID}`) + .should('exist') + .contains(creator.name); if (type === ItemType.LOCAL_FILE || type === ItemType.S3_FILE) { const { mimetype, size } = getFileExtra(extra); @@ -137,7 +120,9 @@ describe('Item Settings', () => { describe('Language', () => { it('change item language', () => { - const { id, lang } = ITEMS_SETTINGS.items[1]; + const FILE = PackedLocalFileItemFactory(); + cy.setUpApi({ items: [FILE] }); + const { id, lang } = FILE; cy.visit(buildItemSettingsPath(id)); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error @@ -154,7 +139,11 @@ describe('Item Settings', () => { describe('Chatbox Settings', () => { it('Disabling Chatbox', () => { - const itemId = ITEMS_SETTINGS.items[1].id; + const FILE = PackedLocalFileItemFactory({ + settings: { showChatbox: true }, + }); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); @@ -176,7 +165,11 @@ describe('Item Settings', () => { }); it('Enabling Chatbox', () => { - const itemId = ITEMS_SETTINGS.items[2].id; + const FILE = PackedLocalFileItemFactory({ + settings: { showChatbox: false }, + }); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); @@ -198,9 +191,32 @@ describe('Item Settings', () => { }); it('Clear Chat', () => { - const itemId = ITEM_WITH_CHATBOX_MESSAGES_AND_ADMIN.id; + const item = PackedFolderItemFactory(); + const ITEM_WITH_CHATBOX_MESSAGES_AND_ADMIN = { + ...item, + chat: [ + { + id: '78ad2166-3862-4593-a10c-d380e7b66674', + body: 'message1', + item, + createdAt: '2021-08-11T12:56:36.834Z', + updatedAt: '2021-08-11T12:56:36.834Z', + creator: CURRENT_USER, + }, + { + id: '78ad1166-3862-1593-a10c-d380e7b66674', + body: 'message2', + item, + createdAt: '2021-08-11T12:56:36.834Z', + updatedAt: '2021-08-11T12:56:36.834Z', + creator: MEMBERS.BOB, + }, + ], + }; + cy.setUpApi({ items: [ITEM_WITH_CHATBOX_MESSAGES_AND_ADMIN] }); + // navigate to the item settings - cy.visit(buildItemSettingsPath(itemId)); + cy.visit(buildItemSettingsPath(item.id)); // click on the clear chat button cy.get(`#${CLEAR_CHAT_SETTING_ID}`).scrollIntoView(); @@ -220,6 +236,8 @@ describe('Item Settings', () => { }); it('Unauthorized to clear Chat', () => { + cy.setUpApi({ items: [ITEM_WITH_CHATBOX_MESSAGES] }); + const itemId = ITEM_WITH_CHATBOX_MESSAGES.id; // navigate to the item settings cy.visit(buildItemSettingsPath(itemId)); @@ -234,7 +252,11 @@ describe('Item Settings', () => { describe('Pinned Settings', () => { it('Unpin items', () => { - const itemId = ITEMS_SETTINGS.items[1].id; + const FILE = PackedLocalFileItemFactory({ + settings: { isPinned: true }, + }); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); @@ -256,7 +278,11 @@ describe('Item Settings', () => { }); it('Pin Item', () => { - const itemId = ITEMS_SETTINGS.items[2].id; + const FILE = PackedLocalFileItemFactory({ + settings: { isPinned: false }, + }); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); cy.get(`#${SETTINGS_PINNED_TOGGLE_ID}`).should('not.be.checked'); @@ -278,19 +304,22 @@ describe('Item Settings', () => { describe('Analytics Settings', () => { it('Layout', () => { - const itemId = ITEMS_SETTINGS.items[2].id; + const FILE = PackedLocalFileItemFactory(); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); cy.get(`#${SETTINGS_SAVE_ACTIONS_TOGGLE_ID}`) .should('exist') - .should('be.disabled') - .should('not.be.checked'); + .should('be.disabled'); }); }); describe('Link Settings', () => { it('Does not show link settings for folder item', () => { - const itemId = ITEMS_SETTINGS.items[0].id; + const FILE = PackedFolderItemFactory(); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); @@ -299,7 +328,11 @@ describe('Item Settings', () => { }); it('Toggle Iframe', () => { - const itemId = GRAASP_LINK_ITEM.id; + const FILE = PackedLinkItemFactory({ + settings: { showLinkIframe: false }, + }); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); @@ -321,7 +354,11 @@ describe('Item Settings', () => { }); it('Toggle Button', () => { - const itemId = GRAASP_LINK_ITEM.id; + const FILE = PackedLinkItemFactory({ + settings: { showLinkIframe: true }, + }); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); cy.get(`#${SETTINGS_LINK_SHOW_BUTTON_ID}`).should('be.checked'); @@ -344,7 +381,19 @@ describe('Item Settings', () => { describe('File Settings', () => { it('Change default maximum width', () => { - const itemId = IMAGE_ITEM_DEFAULT.id; + const FILE = PackedLocalFileItemFactory({ + extra: { + [ItemType.LOCAL_FILE]: { + mimetype: MimeTypes.Image.JPEG, + size: 30, + name: 'name', + path: 'path', + content: '', + }, + }, + }); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); @@ -372,20 +421,38 @@ describe('Item Settings', () => { }); it('Shows set maximum width for file', () => { - const itemId = IMAGE_ITEM_DEFAULT_WITH_MAX_WIDTH.id; + const FILE = PackedLocalFileItemFactory({ + extra: { + [ItemType.LOCAL_FILE]: { + mimetype: MimeTypes.Image.JPEG, + size: 30, + name: 'name', + path: 'path', + content: '', + }, + }, + settings: { + maxWidth: MaxWidth.ExtraLarge, + }, + }); + cy.setUpApi({ items: [FILE] }); + const { id: itemId } = FILE; cy.visit(buildItemSettingsPath(itemId)); cy.get(`#${FILE_SETTING_MAX_WIDTH_ID} + input`).should( 'have.value', - IMAGE_ITEM_DEFAULT_WITH_MAX_WIDTH.settings.maxWidth, + FILE.settings.maxWidth, ); }); }); describe('DescriptionPlacement Settings', () => { it('folder should not have description placement', () => { - const { id, type } = ITEMS_SETTINGS.items[1]; + const FOLDER = PackedFolderItemFactory(); + cy.setUpApi({ items: [FOLDER] }); + const { id, type } = FOLDER; + cy.visit(buildItemSettingsPath(id)); cy.get(`#${ITEM_PANEL_TABLE_ID}`).contains(type); @@ -396,7 +463,10 @@ describe('Item Settings', () => { }); it('update placement to above for file', () => { - const { id } = IMAGE_ITEM_DEFAULT; + const LINK = PackedLinkItemFactory(); + cy.setUpApi({ items: [LINK] }); + const { id } = LINK; + cy.visit(buildItemSettingsPath(id)); cy.get(`#${ITEM_SETTING_DESCRIPTION_PLACEMENT_SELECT_ID}`).click(); @@ -415,33 +485,51 @@ describe('Item Settings', () => { }); describe('in item menu', () => { + const openItemMenu = (itemId: string) => { + cy.get(`#${buildItemMenuButtonId(itemId)}`).click(); + // There is a weird behaviour that scroll on menu button click, causing the close of the menu item. + // To avoid that, the menu button is click again if the menu is not visible. + cy.get(`#${buildItemMenu(itemId)}`).then(($itemMenu) => { + // If the item menu is not visible, click on the button again + if (!$itemMenu.is(':visible')) { + cy.get(`#${buildItemMenuButtonId(itemId)}`).click(); + } + }); + cy.get(`#${buildItemMenu(itemId)}`).should('be.visible'); + }; describe('read', () => { + const item = PackedFolderItemFactory( + {}, + { permission: PermissionLevel.Read }, + ); + const itemId = item.id; beforeEach(() => { cy.setUpApi({ - ...SAMPLE_ITEMS, + items: [item], currentMember: MEMBERS.BOB, }); + cy.visit('/'); }); it('does not have access to settings', () => { - const itemId = SAMPLE_ITEMS.items[1].id; - cy.visit('/'); - cy.get(`#${buildItemMenuButtonId(itemId)}`).click(); - cy.get(`#${buildItemMenu(itemId)}`).should('be.visible'); + openItemMenu(itemId); cy.get(`#${buildSettingsButtonId(itemId)}`).should('not.exist'); }); }); describe('write', () => { + const item = PackedFolderItemFactory( + {}, + { permission: PermissionLevel.Admin }, + ); + const itemId = item.id; beforeEach(() => { cy.setUpApi({ - ...SAMPLE_ITEMS, + items: [item], currentMember: MEMBERS.ALICE, }); + cy.visit('/'); }); it('has access to settings', () => { - const itemId = SAMPLE_ITEMS.items[1].id; - cy.visit('/'); - cy.get(`#${buildItemMenuButtonId(itemId)}`).click(); - cy.get(`#${buildItemMenu(itemId)}`).should('be.visible'); + openItemMenu(itemId); cy.get(`#${buildSettingsButtonId(itemId)}`).should('be.visible'); cy.get(`#${buildSettingsButtonId(itemId)}`).click(); cy.url().should('contain', buildItemSettingsPath(itemId)); diff --git a/cypress/e2e/item/settings/thumbnail.cy.ts b/cypress/e2e/item/settings/thumbnail.cy.ts index 8163ba5ae..420a1d616 100644 --- a/cypress/e2e/item/settings/thumbnail.cy.ts +++ b/cypress/e2e/item/settings/thumbnail.cy.ts @@ -1,26 +1,32 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { buildItemSettingsPath } from '../../../../src/config/paths'; import { CROP_MODAL_CONFIRM_BUTTON_ID, ITEM_THUMBNAIL_DELETE_BTN_ID, THUMBNAIL_SETTING_UPLOAD_INPUT_ID, } from '../../../../src/config/selectors'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; import { - SAMPLE_ITEMS_WITH_THUMBNAILS, + ITEM_THUMBNAIL_LINK, THUMBNAIL_MEDIUM_PATH, -} from '../../../fixtures/thumbnails'; +} from '../../../fixtures/thumbnails/links'; import { FILE_LOADING_PAUSE } from '../../../support/constants'; describe('Item Thumbnail', () => { + const item = PackedFolderItemFactory(); + const itemWithThumbnails = { + ...PackedFolderItemFactory(), + thumnails: ITEM_THUMBNAIL_LINK, + settings: { hasThumbnail: true }, + }; beforeEach(() => { cy.setUpApi({ - items: [...SAMPLE_ITEMS_WITH_THUMBNAILS.items, SAMPLE_ITEMS.items[4]], + items: [item, itemWithThumbnails], }); }); describe('Upload Thumbnails', () => { it(`upload item thumbnail`, () => { - const { items } = SAMPLE_ITEMS_WITH_THUMBNAILS; - cy.visit(buildItemSettingsPath(items[0].id)); + cy.visit(buildItemSettingsPath(item.id)); // change item thumbnail // target visually hidden input @@ -37,20 +43,19 @@ describe('Item Thumbnail', () => { describe('Delete thumbnail', () => { it('Delete thumbnail button should exist for item with thumbnail', () => { - const { items } = SAMPLE_ITEMS_WITH_THUMBNAILS; - cy.visit(buildItemSettingsPath(items[1].id)); + cy.visit(buildItemSettingsPath(itemWithThumbnails.id)); cy.get(`#${ITEM_THUMBNAIL_DELETE_BTN_ID}`) .invoke('show') .should('be.visible'); cy.get(`#${ITEM_THUMBNAIL_DELETE_BTN_ID}`).click(); cy.wait(`@deleteItemThumbnail`).then(({ request: { url } }) => { - expect(url).to.contain(items[1].id); + expect(url).to.contain(itemWithThumbnails.id); }); }); it('Delete thumbnail button should not exist for item with no thumbnail', () => { - cy.visit(buildItemSettingsPath(SAMPLE_ITEMS.items[4].id)); + cy.visit(buildItemSettingsPath(item.id)); Cypress.on('fail', (error) => { expect(error.message).to.include( `Expected to find element: \`#${ITEM_THUMBNAIL_DELETE_BTN_ID}\`, but never found it.`, diff --git a/cypress/e2e/item/share/changeVisibility.cy.ts b/cypress/e2e/item/share/changeVisibility.cy.ts index 3f09eaf6e..72957ff24 100644 --- a/cypress/e2e/item/share/changeVisibility.cy.ts +++ b/cypress/e2e/item/share/changeVisibility.cy.ts @@ -1,4 +1,8 @@ -import { ItemLoginSchemaType, ItemTagType } from '@graasp/sdk'; +import { + ItemLoginSchemaType, + ItemTagType, + PackedFolderItemFactory, +} from '@graasp/sdk'; import { buildItemPath } from '@/config/paths'; @@ -8,11 +12,6 @@ import { SHARE_ITEM_VISIBILITY_SELECT_ID, buildShareButtonId, } from '../../../../src/config/selectors'; -import { - ITEM_LOGIN_ITEMS, - SAMPLE_ITEMS, - SAMPLE_PUBLIC_ITEMS, -} from '../../../fixtures/items'; const changeVisibility = (value: string): void => { cy.get(`#${SHARE_ITEM_VISIBILITY_SELECT_ID}`).click(); @@ -21,8 +20,8 @@ const changeVisibility = (value: string): void => { describe('Visibility of an Item', () => { it('Change Private Item to Public', () => { - const item = SAMPLE_ITEMS.items[0]; - cy.setUpApi({ ...SAMPLE_ITEMS }); + const item = PackedFolderItemFactory(); + cy.setUpApi({ items: [item] }); cy.visit(buildItemPath(item.id)); cy.get(`#${buildShareButtonId(item.id)}`).click(); @@ -43,8 +42,8 @@ describe('Visibility of an Item', () => { }); it('Change Public Item to Private', () => { - const item = SAMPLE_PUBLIC_ITEMS.items[0]; - cy.setUpApi({ ...SAMPLE_PUBLIC_ITEMS }); + const item = PackedFolderItemFactory({}, { publicTag: {} }); + cy.setUpApi({ items: [item] }); cy.visit(buildItemPath(item.id)); cy.get(`#${buildShareButtonId(item.id)}`).click(); cy.wait(1000); @@ -65,8 +64,8 @@ describe('Visibility of an Item', () => { }); it('Change Public Item to Item Login', () => { - const item = SAMPLE_PUBLIC_ITEMS.items[0]; - cy.setUpApi({ ...SAMPLE_PUBLIC_ITEMS }); + const item = PackedFolderItemFactory({}, { publicTag: {} }); + cy.setUpApi({ items: [item] }); cy.visit(buildItemPath(item.id)); cy.get(`#${buildShareButtonId(item.id)}`).click(); cy.wait(1000); @@ -92,8 +91,18 @@ describe('Visibility of an Item', () => { }); it('Change Pseudonymized Item to Private Item', () => { - const item = ITEM_LOGIN_ITEMS.items[0]; - cy.setUpApi({ items: [item] }); + const item = PackedFolderItemFactory(); + const ITEM_LOGIN_ITEM = { + ...item, + itemLoginSchema: { + item, + type: ItemLoginSchemaType.Username, + id: 'efaf3d5a-5688-11eb-ae93-0242ac130002', + createdAt: '2021-08-11T12:56:36.834Z', + updatedAt: '2021-08-11T12:56:36.834Z', + }, + }; + cy.setUpApi({ items: [ITEM_LOGIN_ITEM] }); cy.visit(buildItemPath(item.id)); cy.get(`#${buildShareButtonId(item.id)}`).click(); diff --git a/cypress/e2e/item/share/itemLogin.cy.ts b/cypress/e2e/item/share/itemLogin.cy.ts index a6602b922..25f3226f2 100644 --- a/cypress/e2e/item/share/itemLogin.cy.ts +++ b/cypress/e2e/item/share/itemLogin.cy.ts @@ -1,6 +1,11 @@ -import { ItemLoginSchemaType } from '@graasp/sdk'; +import { + ItemLoginSchemaType, + PackedFolderItemFactory, + PackedItem, + PermissionLevel, +} from '@graasp/sdk'; -import { v4 as uuidv4 } from 'uuid'; +import { v4 } from 'uuid'; import { SETTINGS, @@ -17,10 +22,23 @@ import { SHARE_ITEM_PSEUDONYMIZED_SCHEMA_ID, buildShareButtonId, } from '../../../../src/config/selectors'; -import { ITEM_LOGIN_ITEMS } from '../../../fixtures/items'; import { MEMBERS, SIGNED_OUT_MEMBER } from '../../../fixtures/members'; import { ITEM_LOGIN_PAUSE } from '../../../support/constants'; +const addItemLoginSchema = ( + item: PackedItem, + itemLoginSchemaType: ItemLoginSchemaType, +) => ({ + ...item, + itemLoginSchema: { + item, + type: itemLoginSchemaType, + id: v4(), + createdAt: '2021-08-11T12:56:36.834Z', + updatedAt: '2021-08-11T12:56:36.834Z', + }, +}); + const changeSignInMode = (mode: string) => { cy.get(`#${ITEM_LOGIN_SIGN_IN_MODE_ID}`).click(); cy.get(`li[data-value="${mode}"]`).click(); @@ -94,26 +112,27 @@ const editItemLoginSetting = (mode: string) => { describe('Item Login', () => { it('Item Login not allowed', () => { + const item = PackedFolderItemFactory({}, { permission: null }); cy.setUpApi({ - ...ITEM_LOGIN_ITEMS, + items: [item], currentMember: MEMBERS.BOB, }); - cy.visit(buildItemPath(ITEM_LOGIN_ITEMS.items[4].id)); + cy.visit(buildItemPath(item.id)); cy.wait(ITEM_LOGIN_PAUSE); cy.get(`#${ITEM_LOGIN_SCREEN_FORBIDDEN_ID}`).should('exist'); }); describe('User is signed out', () => { - beforeEach(() => { - cy.setUpApi({ ...ITEM_LOGIN_ITEMS, currentMember: SIGNED_OUT_MEMBER }); - }); - describe('Display Item Login Screen', () => { it('username or member id', () => { - cy.visit(buildItemPath(ITEM_LOGIN_ITEMS.items[0].id)); - checkItemLoginScreenLayout( - ITEM_LOGIN_ITEMS.items[0].itemLoginSchema.type, + const item = addItemLoginSchema( + PackedFolderItemFactory({}, { permission: null }), + ItemLoginSchemaType.Username, ); + cy.setUpApi({ items: [item], currentMember: SIGNED_OUT_MEMBER }); + + cy.visit(buildItemPath(item.id)); + checkItemLoginScreenLayout(item.itemLoginSchema.type); fillItemLoginScreenLayout({ username: 'username', }); @@ -121,7 +140,7 @@ describe('Item Login', () => { // use memberid fillItemLoginScreenLayout({ - memberId: uuidv4(), + memberId: v4(), }); cy.wait('@postItemLogin'); @@ -132,10 +151,14 @@ describe('Item Login', () => { cy.wait('@postItemLogin'); }); it('username or member id and password', () => { - cy.visit(buildItemPath(ITEM_LOGIN_ITEMS.items[3].id)); - checkItemLoginScreenLayout( - ITEM_LOGIN_ITEMS.items[3].itemLoginSchema.type, + const item = addItemLoginSchema( + PackedFolderItemFactory({}, { permission: null }), + ItemLoginSchemaType.UsernameAndPassword, ); + cy.setUpApi({ items: [item], currentMember: SIGNED_OUT_MEMBER }); + + cy.visit(buildItemPath(item.id)); + checkItemLoginScreenLayout(item.itemLoginSchema.type); fillItemLoginScreenLayout({ username: 'username', password: 'password', @@ -144,7 +167,7 @@ describe('Item Login', () => { // use memberid fillItemLoginScreenLayout({ - memberId: uuidv4(), + memberId: v4(), password: 'password', }); cy.wait('@postItemLogin'); @@ -161,11 +184,12 @@ describe('Item Login', () => { describe('User is signed in as normal user', () => { it('Should not be able to access the item', () => { - cy.setUpApi({ - ...ITEM_LOGIN_ITEMS, - currentMember: MEMBERS.BOB, - }); - cy.visit(buildItemPath(ITEM_LOGIN_ITEMS.items[4].id)); + const item = addItemLoginSchema( + PackedFolderItemFactory({}, { permission: null }), + ItemLoginSchemaType.UsernameAndPassword, + ); + cy.setUpApi({ items: [item], currentMember: MEMBERS.BOB }); + cy.visit(buildItemPath(item.id)); // avoid to detect intermediate screens because of loading // to remove when requests loading time is properly managed @@ -177,8 +201,16 @@ describe('Item Login', () => { describe('Display Item Login Setting', () => { it('edit item login setting', () => { - cy.setUpApi(ITEM_LOGIN_ITEMS); - const item = ITEM_LOGIN_ITEMS.items[0]; + const item = addItemLoginSchema( + PackedFolderItemFactory(), + ItemLoginSchemaType.Username, + ); + const child = { + ...PackedFolderItemFactory({ parentItem: item }), + // inherited schema + itemLoginSchema: item.itemLoginSchema, + }; + cy.setUpApi({ items: [item, child] }); // check item with item login enabled cy.visit(buildItemPath(item.id)); cy.get(`#${buildShareButtonId(item.id)}`).click(); @@ -190,9 +222,8 @@ describe('Item Login', () => { editItemLoginSetting(ItemLoginSchemaType.UsernameAndPassword); // disabled at child level - const item2 = ITEM_LOGIN_ITEMS.items[5]; - cy.visit(buildItemPath(item2.id)); - cy.get(`#${buildShareButtonId(item2.id)}`).click(); + cy.visit(buildItemPath(child.id)); + cy.get(`#${buildShareButtonId(child.id)}`).click(); checkItemLoginSetting({ isEnabled: true, mode: ItemLoginSchemaType.UsernameAndPassword, @@ -201,26 +232,33 @@ describe('Item Login', () => { }); it('read permission', () => { + const item = addItemLoginSchema( + PackedFolderItemFactory({}, { permission: PermissionLevel.Read }), + ItemLoginSchemaType.UsernameAndPassword, + ); cy.setUpApi({ - ...ITEM_LOGIN_ITEMS, + items: [item], currentMember: MEMBERS.BOB, }); - cy.visit(buildItemPath(ITEM_LOGIN_ITEMS.items[3].id)); + cy.visit(buildItemPath(item.id)); cy.wait(ITEM_LOGIN_PAUSE); }); }); describe('Error handling', () => { it('error while signing in', () => { + const item = addItemLoginSchema( + PackedFolderItemFactory({}, { permission: null }), + ItemLoginSchemaType.UsernameAndPassword, + ); cy.setUpApi({ - ...ITEM_LOGIN_ITEMS, + items: [item], postItemLoginError: true, currentMember: SIGNED_OUT_MEMBER, }); - const { id } = ITEM_LOGIN_ITEMS.items[4]; // go to children item - cy.visit(buildItemPath(id)); + cy.visit(buildItemPath(item.id)); fillItemLoginScreenLayout({ username: 'username', diff --git a/cypress/e2e/item/share/publicItems.cy.ts b/cypress/e2e/item/share/publicItems.cy.ts index e439ff9a0..cb6e41e04 100644 --- a/cypress/e2e/item/share/publicItems.cy.ts +++ b/cypress/e2e/item/share/publicItems.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { StatusCodes } from 'http-status-codes'; import { buildItemPath } from '../../../../src/config/paths'; @@ -52,13 +54,13 @@ describe('Public Items', () => { }); describe('Disabled', () => { + const item = PackedFolderItemFactory({}, { permission: null }); it('Signed out user cannot access a private item', () => { const currentMember = SIGNED_OUT_MEMBER; cy.setUpApi({ - ...SAMPLE_PUBLIC_ITEMS, + items: [item], currentMember, }); - const item = SAMPLE_PUBLIC_ITEMS.items[1]; cy.visit(buildItemPath(item.id)); cy.wait('@getItem').then(({ response: { statusCode } }) => { expect(statusCode).to.equal(StatusCodes.UNAUTHORIZED); @@ -69,10 +71,9 @@ describe('Public Items', () => { it('User without a membership cannot access a private item', () => { const currentMember = MEMBERS.BOB; cy.setUpApi({ - ...SAMPLE_PUBLIC_ITEMS, + items: [item], currentMember, }); - const item = SAMPLE_PUBLIC_ITEMS.items[1]; cy.visit(buildItemPath(item.id)); cy.wait('@getItem').then(({ response: { statusCode } }) => { expect(statusCode).to.equal(StatusCodes.UNAUTHORIZED); @@ -83,10 +84,9 @@ describe('Public Items', () => { it('User without a membership cannot access a child of a private item', () => { const currentMember = MEMBERS.BOB; cy.setUpApi({ - ...SAMPLE_PUBLIC_ITEMS, + items: [item], currentMember, }); - const item = SAMPLE_PUBLIC_ITEMS.items[6]; cy.visit(buildItemPath(item.id)); cy.wait('@getItem').then(({ response: { statusCode } }) => { expect(statusCode).to.equal(StatusCodes.UNAUTHORIZED); diff --git a/cypress/e2e/item/share/shareItemFromCsv.cy.ts b/cypress/e2e/item/share/shareItemFromCsv.cy.ts index 477b44cc1..7bb000577 100644 --- a/cypress/e2e/item/share/shareItemFromCsv.cy.ts +++ b/cypress/e2e/item/share/shareItemFromCsv.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { buildItemSharePath } from '../../../../src/config/paths'; import { CSV_FILE_SELECTION_DELETE_BUTTON_ID, @@ -13,7 +15,6 @@ import { TREE_MODAL_CONFIRM_BUTTON_ID, buildNavigationModalItemId, } from '../../../../src/config/selectors'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; import { MEMBERS } from '../../../fixtures/members'; const shareItem = ({ fixture }: { id: string; fixture: string }) => { @@ -25,6 +26,8 @@ const shareItem = ({ fixture }: { id: string; fixture: string }) => { ); }; +const ITEMS = [PackedFolderItemFactory(), PackedFolderItemFactory()]; + const selectTemplate = (id: string) => { cy.get(`#${SHARE_CSV_TEMPLATE_SELECTION_BUTTON_ID}`).click(); @@ -35,9 +38,9 @@ const selectTemplate = (id: string) => { describe('Share Item From CSV', () => { it('simple file without group column', () => { const fixture = 'share/simple.csv'; - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + cy.setUpApi({ items: ITEMS, members: Object.values(MEMBERS) }); - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = ITEMS[0]; cy.visit(buildItemSharePath(id)); shareItem({ id, fixture }); @@ -51,9 +54,9 @@ describe('Share Item From CSV', () => { it('add file and remove file', () => { const fixture = 'share/simple.csv'; - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + cy.setUpApi({ items: ITEMS, members: Object.values(MEMBERS) }); - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = ITEMS[0]; cy.visit(buildItemSharePath(id)); shareItem({ id, fixture }); @@ -68,9 +71,9 @@ describe('Share Item From CSV', () => { it('incorrect columns', () => { const fixture = 'share/incorrectColumns.csv'; - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + cy.setUpApi({ items: ITEMS, members: Object.values(MEMBERS) }); - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = ITEMS[0]; cy.visit(buildItemSharePath(id)); shareItem({ id, fixture }); @@ -81,13 +84,13 @@ describe('Share Item From CSV', () => { it('upload file with groups and select template', () => { const fixture = 'share/groups.csv'; - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + cy.setUpApi({ items: ITEMS, members: Object.values(MEMBERS) }); - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = ITEMS[0]; cy.visit(buildItemSharePath(id)); shareItem({ id, fixture }); - const templateItemId = SAMPLE_ITEMS.items[1].id; + const templateItemId = ITEMS[1].id; cy.get(`#${SHARE_CSV_TEMPLATE_SELECTION_BUTTON_ID}`).should('be.visible'); selectTemplate(templateItemId); diff --git a/cypress/e2e/item/share/shortLink.cy.ts b/cypress/e2e/item/share/shortLink.cy.ts index 32545849e..77f1a9bdf 100644 --- a/cypress/e2e/item/share/shortLink.cy.ts +++ b/cypress/e2e/item/share/shortLink.cy.ts @@ -1,4 +1,9 @@ -import { Context, ShortLink } from '@graasp/sdk'; +import { + Context, + PackedFolderItemFactory, + PermissionLevel, + ShortLink, +} from '@graasp/sdk'; import { StatusCodes } from 'http-status-codes'; @@ -18,11 +23,9 @@ import { buildShortLinkShortenBtnId, } from '@/config/selectors'; -import { - PUBLISHED_ITEM, - SAMPLE_ITEMS, - SAMPLE_READ_ITEMS, -} from '../../../fixtures/items'; +import { PUBLISHED_ITEM } from '../../../fixtures/items'; + +const items = [PackedFolderItemFactory(), PackedFolderItemFactory()]; describe('Short links', () => { describe('Admin permission', () => { @@ -31,10 +34,10 @@ describe('Short links', () => { beforeEach(() => { const shortLinks: ShortLink[] = []; - itemId = SAMPLE_ITEMS.items[1].id; + itemId = items[1].id; cy.setUpApi({ - ...SAMPLE_ITEMS, + items, getShortLinkAvailable: true, // indicates that the short link is available shortLinks, itemId, @@ -127,7 +130,7 @@ describe('Short links', () => { let itemId: string; let shortLinks: ShortLink[]; beforeEach(() => { - itemId = SAMPLE_ITEMS.items[1].id; + itemId = items[1].id; shortLinks = [ { @@ -145,7 +148,7 @@ describe('Short links', () => { ]; cy.setUpApi({ - ...SAMPLE_ITEMS, + items, getShortLinkAvailable: true, // indicates that the short link is available shortLinks, itemId, @@ -273,7 +276,7 @@ describe('Short links', () => { let patchAlias: string; beforeEach(() => { - itemId = SAMPLE_ITEMS.items[1].id; + itemId = items[1].id; shortLinks = [ { @@ -293,7 +296,7 @@ describe('Short links', () => { patchAlias = shortLinks[0].alias; cy.setUpApi({ - ...SAMPLE_ITEMS, + items, getShortLinkAvailable: false, // indicates that the short link is not available shortLinks, itemId, @@ -429,8 +432,14 @@ describe('Short links', () => { describe('Read permission', () => { let itemId: string; let shortLinks: ShortLink[]; + + const READ_ITEMS = [ + PackedFolderItemFactory({}, { permission: PermissionLevel.Read }), + PackedFolderItemFactory({}, { permission: PermissionLevel.Read }), + ]; + beforeEach(() => { - itemId = SAMPLE_READ_ITEMS.items[0].id; + itemId = READ_ITEMS[0].id; shortLinks = [ { @@ -442,7 +451,7 @@ describe('Short links', () => { ]; cy.setUpApi({ - ...SAMPLE_READ_ITEMS, + items: READ_ITEMS, getShortLinkAvailable: true, // indicates that the short link is available shortLinks, itemId, diff --git a/cypress/e2e/item/upload/dropzoneUpload.cy.ts b/cypress/e2e/item/upload/dropzoneUpload.cy.ts index a46976eab..b0f5413b6 100644 --- a/cypress/e2e/item/upload/dropzoneUpload.cy.ts +++ b/cypress/e2e/item/upload/dropzoneUpload.cy.ts @@ -1,7 +1,9 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import { buildItemPath } from '@/config/paths'; import { DROPZONE_HELPER_ID } from '@/config/selectors'; -import { SAMPLE_ITEMS, SAMPLE_PUBLIC_ITEMS } from '../../../fixtures/items'; +import { SAMPLE_PUBLIC_ITEMS } from '../../../fixtures/items'; describe('Dropzone Helper Visibility', () => { describe('Home screen', () => { @@ -17,8 +19,9 @@ describe('Dropzone Helper Visibility', () => { describe('Empty folder', () => { it('should show dropzone helper when no items (logged in)', () => { - cy.setUpApi(SAMPLE_ITEMS); - cy.visit(buildItemPath(SAMPLE_ITEMS.items[1].id)); + const ITEMS = [PackedFolderItemFactory()]; + cy.setUpApi({ items: ITEMS }); + cy.visit(buildItemPath(ITEMS[0].id)); cy.get(`#${DROPZONE_HELPER_ID}`).should('be.visible'); }); diff --git a/cypress/e2e/item/upload/gridItemUpload.cy.ts b/cypress/e2e/item/upload/gridItemUpload.cy.ts deleted file mode 100644 index c7154c9c4..000000000 --- a/cypress/e2e/item/upload/gridItemUpload.cy.ts +++ /dev/null @@ -1,80 +0,0 @@ -// import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; -// import { UPLOADER_ID } from '../../../../src/config/selectors'; -// import ItemLayoutMode from '../../../../src/enums/itemLayoutModes'; -// import { ICON_FILEPATH, TEXT_FILEPATH } from '../../../fixtures/files'; -// import { SAMPLE_ITEMS } from '../../../fixtures/items'; - -// BUG: These tests work but not in CI - -// const dragUploadItem = (filenames) => -// cy.attachFiles(cy.get(`#${UPLOADER_ID} button input`), filenames, { -// action: 'drag-drop', -// force: true, -// }); - -// describe('Upload Item in Grid', () => { -// beforeEach(() => { -// cy.setUpApi(SAMPLE_ITEMS); -// }); - -// describe('Drag Upload', () => { -// describe('upload item on Home', () => { -// beforeEach(() => { -// cy.visit(HOME_PATH); -// cy.switchMode(ItemLayoutMode.Grid); -// }); - -// it('upload one file successfully', () => { -// dragUploadItem([ICON_FILEPATH]).then(() => { -// cy.wait('@uploadItem').then(() => { -// // todo: check response - -// // should update view -// cy.wait('@getOwnItems'); -// }); -// }); -// }); - -// it('upload two files successfully', () => { -// dragUploadItem([ICON_FILEPATH, TEXT_FILEPATH]).then(() => { -// cy.wait('@uploadItem').then(() => { -// // todo: check response - -// // should update view -// cy.wait('@getOwnItems'); -// }); -// }); -// }); -// }); -// describe('upload item in item', () => { -// const { id } = SAMPLE_ITEMS.items[0]; - -// beforeEach(() => { -// cy.visit(buildItemPath(id)); -// cy.switchMode(ItemLayoutMode.Grid); -// }); - -// it('upload one file successfully', () => { -// dragUploadItem([ICON_FILEPATH]).then(() => { -// cy.wait('@uploadItem').then(() => { -// // todo: check response - -// // should update view -// cy.wait('@getItem'); -// }); -// }); -// }); - -// it('upload two files successfully', () => { -// dragUploadItem([ICON_FILEPATH, TEXT_FILEPATH]).then(() => { -// cy.wait('@uploadItem').then(() => { -// // todo: check response - -// // should update view -// cy.wait('@getItem'); -// }); -// }); -// }); -// }); -// }); -// }); diff --git a/cypress/e2e/item/upload/listItemUpload.cy.ts b/cypress/e2e/item/upload/listItemUpload.cy.ts deleted file mode 100644 index c42bcadbb..000000000 --- a/cypress/e2e/item/upload/listItemUpload.cy.ts +++ /dev/null @@ -1,82 +0,0 @@ -// import { HOME_PATH, buildItemPath } from '../../../../src/config/paths'; -// import { UPLOADER_ID } from '../../../../src/config/selectors'; -// import { ItemLayoutMode } from '../../../../src/enums'; -// import { ICON_FILEPATH, TEXT_FILEPATH } from '../../../fixtures/files'; -// import { SAMPLE_ITEMS } from '../../../fixtures/items'; - -// BUG: These tests work but not in CI - -// const dragUploadItem = (filenames) => -// cy.attachFiles(cy.get(`#${UPLOADER_ID} button input`), filenames, { -// subjectType: 'drag-drop', -// force: true, -// }); - -// describe('Upload Item in List', () => { -// beforeEach(() => { -// cy.setUpApi(SAMPLE_ITEMS); -// }); - -// describe('Drag Upload', () => { -// describe('upload item on Home', () => { -// beforeEach(() => { -// cy.visit(HOME_PATH); - -// cy.switchMode(ItemLayoutMode.List); -// }); - -// it('upload one file successfully', () => { -// dragUploadItem([ICON_FILEPATH]).then(() => { -// cy.wait('@uploadItem').then(() => { -// // todo: check response - -// // should update view -// cy.wait('@getOwnItems'); -// }); -// }); -// }); - -// it('upload two files successfully', () => { -// dragUploadItem([ICON_FILEPATH, TEXT_FILEPATH]).then(() => { -// cy.wait('@uploadItem').then(() => { -// // todo: check response - -// // should update view -// cy.wait('@getOwnItems'); -// }); -// }); -// }); -// }); -// describe('upload item in item', () => { -// const { id } = SAMPLE_ITEMS.items[0]; - -// beforeEach(() => { -// cy.visit(buildItemPath(id)); - -// cy.switchMode(ItemLayoutMode.List); -// }); - -// it('upload one file successfully', () => { -// dragUploadItem([ICON_FILEPATH]).then(() => { -// cy.wait('@uploadItem').then(() => { -// // todo: check response - -// // should update view -// cy.wait('@getItem'); -// }); -// }); -// }); - -// it('upload two files successfully', () => { -// dragUploadItem([ICON_FILEPATH, TEXT_FILEPATH]).then(() => { -// cy.wait('@uploadItem').then(() => { -// // todo: check response - -// // should update view -// cy.wait('@getItem'); -// }); -// }); -// }); -// }); -// }); -// }); diff --git a/cypress/e2e/item/view/viewDocument.cy.ts b/cypress/e2e/item/view/viewDocument.cy.ts index 3561892d6..d07793007 100644 --- a/cypress/e2e/item/view/viewDocument.cy.ts +++ b/cypress/e2e/item/view/viewDocument.cy.ts @@ -1,19 +1,22 @@ +import { PackedDocumentItemFactory } from '@graasp/sdk'; + import { buildItemPath } from '../../../../src/config/paths'; -import { GRAASP_DOCUMENT_ITEM } from '../../../fixtures/documents'; import { CURRENT_USER } from '../../../fixtures/members'; import { buildItemMembership } from '../../../fixtures/memberships'; import { expectDocumentViewScreenLayout } from '../../../support/viewUtils'; +const DOCUMENT = PackedDocumentItemFactory(); + describe('View Document', () => { describe('Grid', () => { beforeEach(() => { cy.setUpApi({ items: [ { - ...GRAASP_DOCUMENT_ITEM, + ...DOCUMENT, memberships: [ buildItemMembership({ - item: GRAASP_DOCUMENT_ITEM, + item: DOCUMENT, member: CURRENT_USER, }), ], @@ -23,9 +26,9 @@ describe('View Document', () => { }); it('visit document', () => { - cy.visit(buildItemPath(GRAASP_DOCUMENT_ITEM.id)); + cy.visit(buildItemPath(DOCUMENT.id)); - expectDocumentViewScreenLayout({ item: GRAASP_DOCUMENT_ITEM }); + expectDocumentViewScreenLayout({ item: DOCUMENT }); }); }); }); diff --git a/cypress/e2e/item/view/viewFolder.cy.ts b/cypress/e2e/item/view/viewFolder.cy.ts index 6e50a9102..2d29733f5 100644 --- a/cypress/e2e/item/view/viewFolder.cy.ts +++ b/cypress/e2e/item/view/viewFolder.cy.ts @@ -1,3 +1,5 @@ +import { PackedFolderItemFactory } from '@graasp/sdk'; + import i18n from '../../../../src/config/i18n'; import { buildItemPath } from '../../../../src/config/paths'; import { @@ -7,30 +9,29 @@ import { buildItemsTableRowIdAttribute, } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; -import { IMAGE_ITEM_DEFAULT, VIDEO_ITEM_S3 } from '../../../fixtures/files'; -import { SAMPLE_ITEMS } from '../../../fixtures/items'; -import { GRAASP_LINK_ITEM } from '../../../fixtures/links'; import { CURRENT_USER } from '../../../fixtures/members'; -import { SHARED_ITEMS } from '../../../fixtures/sharedItems'; import { expectFolderViewScreenLayout } from '../../../support/viewUtils'; +const parentItem = PackedFolderItemFactory(); +const item1 = PackedFolderItemFactory(); + +const child1 = PackedFolderItemFactory({ parentItem }); +const child2 = PackedFolderItemFactory({ parentItem }); +const children = [child1, child2]; + +const items = [parentItem, item1, child1, child2]; + describe('View Folder', () => { describe('Grid', () => { beforeEach(() => { cy.setUpApi({ - items: [ - ...SAMPLE_ITEMS.items, - ...SHARED_ITEMS.items, - GRAASP_LINK_ITEM, - IMAGE_ITEM_DEFAULT, - VIDEO_ITEM_S3, - ], + items, }); i18n.changeLanguage(CURRENT_USER.extra.lang as string); }); it('visit item by id', () => { - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = parentItem; cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.Grid); @@ -38,13 +39,13 @@ describe('View Folder', () => { cy.wait('@getItem'); // should get children - cy.wait('@getChildren').then(({ response: { body } }) => { + cy.wait('@getChildren').then(() => { // check all children are created and displayed - for (const item of body) { + for (const item of children) { cy.get(`#${buildItemCard(item.id)}`).should('exist'); } }); - expectFolderViewScreenLayout({ item: SAMPLE_ITEMS.items[0] }); + expectFolderViewScreenLayout({ item: parentItem }); // visit home cy.get(`#${NAVIGATION_HOME_ID}`).click(); @@ -59,36 +60,26 @@ describe('View Folder', () => { }); it('search', () => { - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = parentItem; cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.Grid); - cy.get(`#${buildItemCard(SAMPLE_ITEMS.items[2].id)}`).should( - 'be.visible', - ); - cy.get(`#${ITEM_SEARCH_INPUT_ID}`).type(SAMPLE_ITEMS.items[3].name); - cy.get(`#${buildItemCard(SAMPLE_ITEMS.items[3].id)}`).should( - 'be.visible', - ); + cy.get(`#${buildItemCard(child1.id)}`).should('be.visible'); + cy.get(`#${ITEM_SEARCH_INPUT_ID}`).type(child1.name); + cy.get(`#${buildItemCard(child1.id)}`).should('be.visible'); }); }); describe('List', () => { - const allItems = [ - ...SAMPLE_ITEMS.items, - GRAASP_LINK_ITEM, - IMAGE_ITEM_DEFAULT, - VIDEO_ITEM_S3, - ]; beforeEach(() => { cy.setUpApi({ - items: allItems, + items, }); }); describe('Navigation', () => { it('visit folder by id', () => { - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = parentItem; cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.List); @@ -103,7 +94,7 @@ describe('View Folder', () => { } }); - expectFolderViewScreenLayout({ item: SAMPLE_ITEMS.items[0] }); + expectFolderViewScreenLayout({ item: parentItem }); // visit home cy.get(`#${NAVIGATION_HOME_ID}`).click(); @@ -117,17 +108,13 @@ describe('View Folder', () => { }); it('search', () => { - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = parentItem; cy.visit(buildItemPath(id)); cy.switchMode(ItemLayoutMode.List); - cy.get(buildItemsTableRowIdAttribute(SAMPLE_ITEMS.items[2].id)).should( - 'be.visible', - ); - cy.get(`#${ITEM_SEARCH_INPUT_ID}`).type(SAMPLE_ITEMS.items[3].name); - cy.get(buildItemsTableRowIdAttribute(SAMPLE_ITEMS.items[3].id)).should( - 'be.visible', - ); + cy.get(buildItemsTableRowIdAttribute(child1.id)).should('be.visible'); + cy.get(`#${ITEM_SEARCH_INPUT_ID}`).type(child1.name); + cy.get(buildItemsTableRowIdAttribute(child1.id)).should('be.visible'); }); }); }); diff --git a/cypress/e2e/item/view/viewThumbnails.cy.ts b/cypress/e2e/item/view/viewThumbnails.cy.ts index a7a4031c8..ee93dda92 100644 --- a/cypress/e2e/item/view/viewThumbnails.cy.ts +++ b/cypress/e2e/item/view/viewThumbnails.cy.ts @@ -1,4 +1,6 @@ -import { HOME_PATH, SHARED_ITEMS_PATH } from '../../../../src/config/paths'; +import { PackedFolderItemFactory } from '@graasp/sdk'; + +import { HOME_PATH } from '../../../../src/config/paths'; import { HEADER_MEMBER_MENU_BUTTON_ID, buildItemCard, @@ -6,54 +8,61 @@ import { } from '../../../../src/config/selectors'; import { ItemLayoutMode } from '../../../../src/enums'; import { MEMBERS } from '../../../fixtures/members'; -import { SAMPLE_ITEMS_WITH_THUMBNAILS } from '../../../fixtures/thumbnails'; +import { ITEM_THUMBNAIL_LINK } from '../../../fixtures/thumbnails/links'; + +const ITEM_WITHOUT_THUMBNAIL = PackedFolderItemFactory({ + name: 'own_item_name1', +}); +const ITEM_WITH_THUMBNAIL = { + ...PackedFolderItemFactory({ + name: 'own_item_name2', + settings: { + hasThumbnail: true, + }, + }), + thumbnails: ITEM_THUMBNAIL_LINK, +}; describe('View Thumbnails', () => { it(`display thumbnail icons`, () => { - cy.setUpApi(SAMPLE_ITEMS_WITH_THUMBNAILS); + cy.setUpApi({ items: [ITEM_WITHOUT_THUMBNAIL, ITEM_WITH_THUMBNAIL] }); cy.visit(HOME_PATH); - const { items } = SAMPLE_ITEMS_WITH_THUMBNAILS; - // check default material icon // first item doesn't have a thumbnail so it displays the material icon - cy.get(`#${buildNameCellRendererId(items[0].id)} svg path`).should('exist'); + cy.get( + `#${buildNameCellRendererId(ITEM_WITHOUT_THUMBNAIL.id)} svg path`, + ).should('exist'); // the second item has a defined thumbnail - cy.get(`#${buildNameCellRendererId(items[1].id)} img`).should('exist'); + cy.get(`#${buildNameCellRendererId(ITEM_WITH_THUMBNAIL.id)} img`).should( + 'exist', + ); // GRID cy.switchMode(ItemLayoutMode.Grid); // first element has default folder svg - cy.get(`#${buildItemCard(items[0].id)} svg path`).should('exist'); + cy.get(`#${buildItemCard(ITEM_WITH_THUMBNAIL.id)} svg path`).should( + 'exist', + ); - cy.get(`#${buildItemCard(items[1].id)} img`) + cy.get(`#${buildItemCard(ITEM_WITH_THUMBNAIL.id)} img`) .should('have.attr', 'src') - .and('contain', items[1].thumbnails); + .and('contain', ITEM_WITH_THUMBNAIL.thumbnails); }); it(`display member avatar`, () => { cy.setUpApi({ - ...SAMPLE_ITEMS_WITH_THUMBNAILS, + items: [PackedFolderItemFactory()], currentMember: MEMBERS.BOB, }); cy.visit(HOME_PATH); - const { items } = SAMPLE_ITEMS_WITH_THUMBNAILS; - // display member avatar in header cy.get(`#${HEADER_MEMBER_MENU_BUTTON_ID} img`) .should('have.attr', 'src') .and('contain', MEMBERS.BOB.thumbnails); - - cy.visit(SHARED_ITEMS_PATH); - - // check bob avatar in shared items, grid mode - cy.switchMode(ItemLayoutMode.Grid); - cy.get(`#${buildItemCard(items[1].id)} img`) - .should('have.attr', 'src') - .and('contain', MEMBERS.BOB.thumbnails); }); }); diff --git a/cypress/e2e/memberships/createItemMembership.cy.ts b/cypress/e2e/memberships/createItemMembership.cy.ts index 5eb532191..7ea8beb72 100644 --- a/cypress/e2e/memberships/createItemMembership.cy.ts +++ b/cypress/e2e/memberships/createItemMembership.cy.ts @@ -1,4 +1,8 @@ -import { PermissionLevel } from '@graasp/sdk'; +import { + PackedFolderItemFactory, + PackedLocalFileItemFactory, + PermissionLevel, +} from '@graasp/sdk'; import { buildItemPath } from '../../../src/config/paths'; import { @@ -7,7 +11,6 @@ import { SHARE_ITEM_SHARE_BUTTON_ID, buildShareButtonId, } from '../../../src/config/selectors'; -import { SAMPLE_ITEMS } from '../../fixtures/items'; import { MEMBERS } from '../../fixtures/members'; const shareItem = ({ @@ -31,12 +34,17 @@ const shareItem = ({ }); }; +const IMAGE_ITEM = PackedLocalFileItemFactory(); +const FOLDER = PackedFolderItemFactory(); + +const ITEMS = [IMAGE_ITEM, FOLDER]; + describe('Create Membership', () => { it('share item', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + cy.setUpApi({ items: ITEMS, members: Object.values(MEMBERS) }); // go to children item - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = FOLDER; cy.visit(buildItemPath(id)); // share @@ -62,14 +70,29 @@ describe('Create Membership', () => { }); it('cannot share item twice', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + const ITEM = PackedFolderItemFactory(); + const member = MEMBERS.ANNA; + cy.setUpApi({ + items: [ + { + ...ITEM, + memberships: [ + { + item: ITEM, + permission: PermissionLevel.Read, + member, + }, + ], + }, + ], + members: Object.values(MEMBERS), + }); // go to children item - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = ITEM; cy.visit(buildItemPath(id)); // fill - const member = MEMBERS.ANNA; const permission = PermissionLevel.Read; shareItem({ id, member, permission }); @@ -77,10 +100,10 @@ describe('Create Membership', () => { }); it('cannot share item with invalid data', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, members: Object.values(MEMBERS) }); + cy.setUpApi({ items: ITEMS, members: Object.values(MEMBERS) }); // go to children item - const { id } = SAMPLE_ITEMS.items[0]; + const { id } = FOLDER; cy.visit(buildItemPath(id)); // fill diff --git a/cypress/e2e/memberships/editItemMembership.cy.ts b/cypress/e2e/memberships/editItemMembership.cy.ts index f8bfd9f9f..40f21ff36 100644 --- a/cypress/e2e/memberships/editItemMembership.cy.ts +++ b/cypress/e2e/memberships/editItemMembership.cy.ts @@ -8,7 +8,6 @@ import { buildShareButtonId, } from '../../../src/config/selectors'; import { ITEMS_WITH_MEMBERSHIPS } from '../../fixtures/memberships'; -import { TABLE_MEMBERSHIP_RENDER_TIME } from '../../support/constants'; const editItemMembership = ({ itemId, @@ -21,8 +20,6 @@ const editItemMembership = ({ }) => { cy.get(`#${buildShareButtonId(itemId)}`).click(); - cy.wait(TABLE_MEMBERSHIP_RENDER_TIME); - const select = cy.get( `${buildItemMembershipRowSelector( id, @@ -34,7 +31,7 @@ const editItemMembership = ({ describe('Edit Membership', () => { it('edit item membership', () => { - cy.setUpApi({ ...ITEMS_WITH_MEMBERSHIPS }); + cy.setUpApi(ITEMS_WITH_MEMBERSHIPS); // go to children item const { id, memberships } = ITEMS_WITH_MEMBERSHIPS.items[0]; diff --git a/cypress/e2e/memberships/viewMemberships.cy.ts b/cypress/e2e/memberships/viewMemberships.cy.ts index fbaa9613e..171bcc290 100644 --- a/cypress/e2e/memberships/viewMemberships.cy.ts +++ b/cypress/e2e/memberships/viewMemberships.cy.ts @@ -14,7 +14,7 @@ import { describe('View Memberships', () => { beforeEach(() => { - cy.setUpApi({ ...ITEMS_WITH_MEMBERSHIPS }); + cy.setUpApi(ITEMS_WITH_MEMBERSHIPS); }); it('view membership in settings', () => { diff --git a/cypress/e2e/redirection.cy.ts b/cypress/e2e/redirection.cy.ts index e2a455507..bcbcc7a4d 100644 --- a/cypress/e2e/redirection.cy.ts +++ b/cypress/e2e/redirection.cy.ts @@ -1,8 +1,7 @@ -import { saveUrlForRedirection } from '@graasp/sdk'; +import { PackedFolderItemFactory, saveUrlForRedirection } from '@graasp/sdk'; import { REDIRECT_PATH } from '../../src/config/paths'; import { ACCESSIBLE_ITEMS_TABLE_ID } from '../../src/config/selectors'; -import { SAMPLE_ITEMS } from '../fixtures/items'; const DOMAIN = Cypress.env('VITE_GRAASP_DOMAIN'); @@ -18,7 +17,8 @@ describe('Redirection', () => { }); it('Redirection to home if no url is saved', () => { - cy.setUpApi(SAMPLE_ITEMS); + const items = [PackedFolderItemFactory()]; + cy.setUpApi({ items }); cy.visit(REDIRECT_PATH); diff --git a/cypress/e2e/ws/item.cy.ts b/cypress/e2e/ws/item.cy.ts deleted file mode 100644 index 0608e8b5d..000000000 --- a/cypress/e2e/ws/item.cy.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { MockWebSocket } from '@graasp/query-client'; - -import { SHARED_ITEMS_PATH, buildItemPath } from '../../../src/config/paths'; -import { buildItemsTableRowIdAttribute } from '../../../src/config/selectors'; -import { SAMPLE_ITEMS } from '../../fixtures/items'; -import { CURRENT_USER } from '../../fixtures/members'; -import { WEBSOCKETS_DELAY_TIME } from '../../support/constants'; - -// parameterized before, to be called in each test or in beforeEach -function beforeWs( - visitRoute: string, - sampleData: unknown, - wsClientStub: MockWebSocket, -) { - cy.setUpApi(sampleData); - cy.visit(visitRoute, { - onBeforeLoad: (win) => { - cy.stub(win, 'WebSocket').callsFake(() => wsClientStub); - }, - }); -} - -describe('Websocket interactions', () => { - let client: MockWebSocket; - - beforeEach(() => { - client = new MockWebSocket(); - }); - - describe('sharedWith me items updates', () => { - it('displays sharedWith create update', () => { - beforeWs(SHARED_ITEMS_PATH, { items: [] }, client); - - cy.wait(WEBSOCKETS_DELAY_TIME); - - const item = SAMPLE_ITEMS.items[0]; - cy.wait('@getSharedItems').then(() => { - // send mock sharedItem create update - client.receive({ - realm: 'notif', - type: 'update', - topic: 'item/member', - channel: CURRENT_USER.id, - body: { - kind: 'shared', - op: 'create', - item, - }, - }); - }); - - cy.wait(WEBSOCKETS_DELAY_TIME); - - // assert item is in list - cy.get(buildItemsTableRowIdAttribute(item.id)).should('exist'); - }); - - it('displays sharedWith delete update', () => { - // create items that do not belong to current user - const items = SAMPLE_ITEMS.items.map((i) => ({ - ...i, - creator: 'someoneElse', - })); - const item = items[0]; - beforeWs(SHARED_ITEMS_PATH, { items }, client); - - cy.get(buildItemsTableRowIdAttribute(item.id)).then(() => { - // send mock sharedItem delete update - client.receive({ - realm: 'notif', - type: 'update', - topic: 'item/member', - channel: CURRENT_USER.id, - body: { - kind: 'shared', - op: 'delete', - item, - }, - }); - }); - - cy.wait(WEBSOCKETS_DELAY_TIME); - // assert item is not in list anymore - cy.get(buildItemsTableRowIdAttribute(item.id)).should('not.exist'); - }); - }); - - describe('childItem updates', () => { - const { id } = SAMPLE_ITEMS.items[0]; - - beforeEach(() => { - beforeWs(buildItemPath(id), SAMPLE_ITEMS, client); - - // should get children - cy.wait('@getChildren').then(({ response: { body } }) => { - // check item is created and displayed - for (const item of body) { - cy.get(buildItemsTableRowIdAttribute(item.id)).should('exist'); - } - }); - }); - - it('displays childItem create update', () => { - const item = { ...SAMPLE_ITEMS.items[0], id: 'child0' }; - // send mock childItem create update - client.receive({ - realm: 'notif', - type: 'update', - topic: 'item', - channel: id, - body: { - kind: 'child', - op: 'create', - item, - }, - }); - - cy.wait(WEBSOCKETS_DELAY_TIME); - // assert item is in list - cy.get(buildItemsTableRowIdAttribute(item.id)).should('exist'); - }); - - it('displays childItem delete update', () => { - // this item MUST be a child of id above - const item = SAMPLE_ITEMS.items[2]; - // send mock childItem delete update - client.receive({ - realm: 'notif', - type: 'update', - topic: 'item', - channel: id, - body: { - kind: 'child', - op: 'delete', - item, - }, - }); - - cy.wait(WEBSOCKETS_DELAY_TIME); - // assert item is not in list - cy.get(buildItemsTableRowIdAttribute(item.id)).should('not.exist'); - }); - }); -}); diff --git a/cypress/fixtures/apps.ts b/cypress/fixtures/apps.ts index b4d52eb8f..f49a72408 100644 --- a/cypress/fixtures/apps.ts +++ b/cypress/fixtures/apps.ts @@ -2,15 +2,12 @@ import { AppItemType, FolderItemType, ItemType, - PermissionLevel, + PackedAppItemFactory, + PackedFolderItemFactory, } from '@graasp/sdk'; -import { ItemForTest } from '../support/types'; import { APPS_LIST } from './apps/apps'; -import { DEFAULT_FOLDER_ITEM } from './items'; -import { CURRENT_USER, MEMBERS } from './members'; - -const API_HOST = Cypress.env('VITE_GRAASP_API_HOST'); +import { CURRENT_USER } from './members'; export const buildAppApiAccessTokenRoute = (id: string): string => `app-items/${id}/api-access-token`; @@ -19,81 +16,37 @@ export const buildGetAppData = (id: string): string => export const buildAppItemLinkForTest = (filename = '.*'): string => `apps/${filename}`; -export const GRAASP_APP_ITEM: AppItemType = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-12eb-ae91-0272ac130012', - path: 'ecafbd2a_5688_12eb_ae91_0272ac130012', +export const GRAASP_APP_ITEM: AppItemType = PackedAppItemFactory({ name: 'test app', - description: 'my app description', - type: ItemType.APP, extra: { [ItemType.APP]: { url: APPS_LIST[0].url }, }, creator: CURRENT_USER, -}; -export const GRAASP_CUSTOM_APP_ITEM: AppItemType = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-12eb-ae91-0272ac130002', - path: 'ecafbd2a_5688_12eb_ae91_0272ac130002', +}); +export const GRAASP_CUSTOM_APP_ITEM: AppItemType = PackedAppItemFactory({ name: 'Add Your Custom App', - description: 'my app description', - type: ItemType.APP, extra: { [ItemType.APP]: { url: APPS_LIST[0].url }, }, creator: CURRENT_USER, -}; +}); -export const GRAASP_APP_PARENT_FOLDER: FolderItemType = { - ...DEFAULT_FOLDER_ITEM, - id: 'bdf09f5a-5688-11eb-ae93-0242ac130002', - name: 'graasp app parent', - path: 'bdf09f5a_5688_11eb_ae93_0242ac130002', -}; +export const GRAASP_APP_PARENT_FOLDER: FolderItemType = PackedFolderItemFactory( + { + name: 'graasp app parent', + }, +); -export const GRAASP_APP_CHILDREN_ITEM: AppItemType = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-12eb-ae91-0272ac130002', - path: 'bdf09f5a_5688_11eb_ae93_0242ac130002.ecafbd2a_5688_12eb_ae91_0272ac130002', +export const GRAASP_APP_CHILDREN_ITEM: AppItemType = PackedAppItemFactory({ name: 'my app', - description: 'my app description', - type: ItemType.APP, extra: { [ItemType.APP]: { url: 'http://localhost.com:3333', }, }, creator: CURRENT_USER, -}; -const app: AppItemType = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-12eb-ae91-0272ac130002', - path: 'ecafbd2a_5688_12eb_ae91_0272ac130002', - name: 'my app', - description: 'my app description', - type: ItemType.APP, - extra: { - [ItemType.APP]: { - url: `${API_HOST}/${buildAppItemLinkForTest('app.html')}`, - }, - }, - creator: CURRENT_USER, -}; - -export const APP_USING_CONTEXT_ITEM: ItemForTest = { - ...app, - memberships: [ - { - item: app, - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - id: '2d44cae9-592a-417a-86d3-99432b223c18', - }, - ], -}; + parentItem: GRAASP_APP_PARENT_FOLDER, +}); export const GRAASP_APP_ITEMS_FIXTURE = [ GRAASP_APP_ITEM, diff --git a/cypress/fixtures/chatbox.ts b/cypress/fixtures/chatbox.ts index 1b386b2c9..c42e3564c 100644 --- a/cypress/fixtures/chatbox.ts +++ b/cypress/fixtures/chatbox.ts @@ -4,6 +4,7 @@ import { FolderItemType, ItemType, MentionStatus, + PackedFolderItemFactory, PermissionLevel, } from '@graasp/sdk'; @@ -22,8 +23,9 @@ const item: FolderItemType = { settings: {}, }; +// warning: permission admin by default export const ITEM_WITH_CHATBOX_MESSAGES: ItemForTest = { - ...item, + ...PackedFolderItemFactory(item), memberships: [ { item, @@ -64,7 +66,7 @@ const items: DiscriminatedItem[] = [ }, ]; -export const ITEM_WITH_CHATBOX_MESSAGES_AND_ADMIN: ItemForTest = { +const ITEM_WITH_CHATBOX_MESSAGES_AND_ADMIN: ItemForTest = { ...items[0], memberships: [ { diff --git a/cypress/fixtures/documents.ts b/cypress/fixtures/documents.ts deleted file mode 100644 index e3569973f..000000000 --- a/cypress/fixtures/documents.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { - DocumentItemFactory, - DocumentItemType, - FolderItemType, - ItemType, - buildDocumentExtra, -} from '@graasp/sdk'; -import { DEFAULT_LANG } from '@graasp/translations'; - -import { DEFAULT_FOLDER_ITEM } from './items'; -import { CURRENT_USER } from './members'; - -export const GRAASP_DOCUMENT_ITEM: DocumentItemType = DocumentItemFactory({ - id: 'ecafbd2a-5688-12eb-ae91-0242ac130002', - type: ItemType.DOCUMENT, - name: 'graasp text', - description: 'a description for graasp text', - path: 'ecafbd2a_5688_12eb_ae93_0242ac130002', - settings: {}, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - lang: DEFAULT_LANG, - creator: CURRENT_USER, - extra: buildDocumentExtra({ - content: '

Some Title

', - }), -}); - -export const GRAASP_DOCUMENT_BLANK_NAME_ITEM: DocumentItemType = - DocumentItemFactory({ - id: 'ecafbd2a-5688-12eb-ae91-0242ac130004', - type: ItemType.DOCUMENT, - name: ' ', - description: 'a description for graasp text', - path: 'ecafbd2a_5688_12eb_ae93_0242ac130002', - settings: {}, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - creator: CURRENT_USER, - extra: buildDocumentExtra({ - content: '

Some Title

', - }), - }); - -export const GRAASP_DOCUMENT_PARENT_FOLDER: FolderItemType = { - ...DEFAULT_FOLDER_ITEM, - id: 'bdf09f5a-5688-11eb-ae93-0242ac130002', - name: 'graasp document parent', - path: 'bdf09f5a_5688_11eb_ae93_0242ac130002', -}; - -export const GRAASP_DOCUMENT_CHILDREN_ITEM: DocumentItemType = - DocumentItemFactory({ - type: ItemType.DOCUMENT, - name: 'children graasp text', - description: 'a description for graasp text', - creator: CURRENT_USER, - settings: {}, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - extra: buildDocumentExtra({ - content: '

Some Title

', - }), - parentItem: GRAASP_DOCUMENT_PARENT_FOLDER, - }); - -export const GRAASP_DOCUMENT_ITEMS_FIXTURE = [ - GRAASP_DOCUMENT_ITEM, - GRAASP_DOCUMENT_PARENT_FOLDER, - GRAASP_DOCUMENT_CHILDREN_ITEM, -]; diff --git a/cypress/fixtures/etherpad.ts b/cypress/fixtures/etherpad.ts deleted file mode 100644 index c279ebd2d..000000000 --- a/cypress/fixtures/etherpad.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { EtherpadItemFactory, EtherpadItemType, ItemType } from '@graasp/sdk'; -import { DEFAULT_LANG } from '@graasp/translations'; - -import { CURRENT_USER } from './members'; - -// eslint-disable-next-line import/prefer-default-export -export const GRAASP_ETHERPAD_ITEM: EtherpadItemType = EtherpadItemFactory({ - id: 'ecaf1d2a-5688-11eb-ae91-0242ac130002', - type: ItemType.ETHERPAD, - name: 'graasp etherpad', - description: 'a description for graasp link', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', - creator: CURRENT_USER, - settings: {}, - lang: DEFAULT_LANG, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - extra: { - [ItemType.ETHERPAD]: { - padID: 'padId', - groupID: 'groupId', - }, - }, -}); diff --git a/cypress/fixtures/h5p.ts b/cypress/fixtures/h5p.ts deleted file mode 100644 index c7376b316..000000000 --- a/cypress/fixtures/h5p.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { H5PItemFactory, H5PItemType, ItemType } from '@graasp/sdk'; - -import { CURRENT_USER } from './members'; - -// eslint-disable-next-line import/prefer-default-export -export const GRAASP_H5P_ITEM: H5PItemType = H5PItemFactory({ - id: 'ecaf1d2a-5688-11eb-ae91-0242ac130002', - type: ItemType.H5P, - name: 'graasp h5p', - description: 'a description for graasp h5p', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', - creator: CURRENT_USER, - settings: {}, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - extra: { - [ItemType.H5P]: { - contentId: 'contentId', - h5pFilePath: 'h5pFilePath', - contentFilePath: 'contentFilePath', - }, - }, -}); diff --git a/cypress/fixtures/invitations.ts b/cypress/fixtures/invitations.ts index 177378c46..62dc0d48d 100644 --- a/cypress/fixtures/invitations.ts +++ b/cypress/fixtures/invitations.ts @@ -1,9 +1,13 @@ -import { DiscriminatedItem, Invitation, PermissionLevel } from '@graasp/sdk'; +import { + DiscriminatedItem, + Invitation, + PackedFolderItemFactory, + PermissionLevel, +} from '@graasp/sdk'; import { v4 } from 'uuid'; import { ApiConfig } from '../support/types'; -import { DEFAULT_FOLDER_ITEM } from './items'; import { MEMBERS } from './members'; export const buildInvitation = (args: { @@ -24,20 +28,19 @@ export const buildInvitation = (args: { }; }; +// warning: default permission admin const itemsWithInvitations: DiscriminatedItem[] = [ - { - ...DEFAULT_FOLDER_ITEM, + PackedFolderItemFactory({ id: 'bcafbd2a-5688-11eb-ae93-0242ac130002', name: 'parent', path: 'bcafbd2a_5688_11eb_ae93_0242ac130002', - }, - { - ...DEFAULT_FOLDER_ITEM, + }), + PackedFolderItemFactory({ id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', name: 'own_item_name1', creator: MEMBERS.BOB, path: 'bcafbd2a_5688_11eb_ae93_0242ac130002.ecafbd2a_5688_11eb_ae93_0242ac130002', - }, + }), ]; // eslint-disable-next-line import/prefer-default-export @@ -101,36 +104,45 @@ export const ITEMS_WITH_INVITATIONS: ApiConfig = { members: [MEMBERS.FANNY, MEMBERS.ANNA, MEMBERS.EVAN], }; +// warning: default permission admin +const itemsWithInvitationsWriteAccess: DiscriminatedItem[] = [ + PackedFolderItemFactory( + { + id: 'bcafbd2a-5688-11eb-ae93-0242ac130002', + path: 'bcafbd2a_5688_11eb_ae93_0242ac130002', + }, + { permission: PermissionLevel.Write }, + ), + PackedFolderItemFactory( + { + id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', + creator: MEMBERS.BOB, + path: 'bcafbd2a_5688_11eb_ae93_0242ac130002.ecafbd2a_5688_11eb_ae93_0242ac130002', + }, + { permission: PermissionLevel.Write }, + ), +]; export const ITEM_WITH_INVITATIONS_WRITE_ACCESS: ApiConfig = { items: [ { - ...itemsWithInvitations[1], + ...itemsWithInvitationsWriteAccess[1], // for tests only memberships: [ { id: 'ecafbd2a-5688-11eb-be93-0242ac130002', - item: itemsWithInvitations[0], + item: itemsWithInvitationsWriteAccess[0], permission: PermissionLevel.Write, member: MEMBERS.ANNA, createdAt: '2021-08-11T12:56:36.834Z', updatedAt: '2021-08-11T12:56:36.834Z', creator: MEMBERS.ANNA, }, - // { - // id: 'ecafbd2a-5688-11eb-be93-0242ac130004', - // item: itemsWithInvitations[0], - // permission: PermissionLevel.Admin, - // email: MEMBERS.BOB.email, - // createdAt: '2021-08-11T12:56:36.834Z', - // updatedAt: '2021-08-11T12:56:36.834Z', - // creator: MEMBERS.ANNA - // }, ], invitations: [ { id: 'ecafbd2a-5688-11eb-be92-0242ac130005', - item: itemsWithInvitations[0], + item: itemsWithInvitationsWriteAccess[0], permission: PermissionLevel.Write, email: MEMBERS.CEDRIC.email, createdAt: '2021-08-11T12:56:36.834Z', @@ -139,7 +151,7 @@ export const ITEM_WITH_INVITATIONS_WRITE_ACCESS: ApiConfig = { }, { id: 'ecafbd1a-5688-11eb-be93-0242ac130006', - item: itemsWithInvitations[1], + item: itemsWithInvitationsWriteAccess[1], permission: PermissionLevel.Read, email: MEMBERS.DAVID.email, createdAt: '2021-08-11T12:56:36.834Z', diff --git a/cypress/fixtures/items.ts b/cypress/fixtures/items.ts index 21a6d4fe2..1d5920f85 100644 --- a/cypress/fixtures/items.ts +++ b/cypress/fixtures/items.ts @@ -1,290 +1,23 @@ import { - DiscriminatedItem, - FolderItemFactory, - FolderItemType, - ItemFavorite, - ItemLoginSchemaType, ItemTagType, ItemType, ItemValidation, ItemValidationProcess, ItemValidationStatus, + PackedFolderItemFactory, + PackedItem, PermissionLevel, - RecycledItemData, - ShortcutItemType, } from '@graasp/sdk'; import { ApiConfig, ItemForTest } from '../support/types'; import { CURRENT_USER, MEMBERS } from './members'; -export const DEFAULT_FOLDER_ITEM: FolderItemType = FolderItemFactory({ - id: 'folder-id', - name: 'folder', - path: 'folder-path', +export const DEFAULT_FOLDER_ITEM = PackedFolderItemFactory({ + name: 'default folder', extra: { [ItemType.FOLDER]: { childrenOrder: [] } }, creator: CURRENT_USER, - type: ItemType.FOLDER, - createdAt: '2020-01-01T01:01:01Z', - updatedAt: '2020-01-01T01:01:01Z', - description: 'mydescription', - settings: {}, }); -export const CREATED_ITEM: Partial = { - name: 'created item', - type: ItemType.FOLDER, - extra: { [ItemType.FOLDER]: { childrenOrder: [] } }, -}; - -export const CREATED_BLANK_NAME_ITEM: Partial = { - name: ' ', - type: ItemType.FOLDER, - extra: { [ItemType.FOLDER]: { childrenOrder: [] } }, -}; - -export const EDITED_FIELDS = { - name: 'new name', -}; -const sampleItems: DiscriminatedItem[] = [ - { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', - name: 'own_item_name1', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', - settings: { - hasThumbnail: false, - }, - extra: { - [ItemType.FOLDER]: { - childrenOrder: ['fdf09f5a-5688-11eb-ae93-0242ac130004'], - }, - }, - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130002', - name: 'own_item_name2', - path: 'fdf09f5a_5688_11eb_ae93_0242ac130002', - settings: { - hasThumbnail: false, - }, - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130003', - name: 'own_item_name3', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130003', - settings: { - hasThumbnail: false, - }, - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130004', - name: 'own_item_name4', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130004', - settings: { - hasThumbnail: false, - }, - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130005', - name: 'own_item_name5', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130005', - settings: { - hasThumbnail: false, - }, - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130006', - name: 'own_item_name6', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130006', - settings: { - hasThumbnail: false, - }, - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'eef09f5a-5688-11eb-ae93-0242ac130003', - name: 'own_item_name7', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130003.eef09f5a_5688_11eb_ae93_0242ac130003', - settings: { - hasThumbnail: false, - }, - }, -]; -export const SAMPLE_ITEMS: ApiConfig = { - items: [ - { - ...sampleItems[0], - memberships: [ - { - item: sampleItems[0], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130034', - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...sampleItems[1], - memberships: [ - { - item: sampleItems[1], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - id: '2d44caf9-592a-417a-86d3-99432b223c18', - }, - { - item: sampleItems[1], - permission: PermissionLevel.Read, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - id: '2d44caf9-598a-417a-86d3-99432b223c18', - }, - ], - }, - { - ...sampleItems[2], - memberships: [ - { - item: sampleItems[2], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - id: '2d44caf9-598a-417b-86d3-99432b223c18', - }, - ], - }, - { - ...sampleItems[3], - memberships: [ - { - item: sampleItems[3], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - id: '2d44caf9-598a-317a-86d3-99432b223c18', - }, - ], - }, - { - ...sampleItems[4], - memberships: [ - { - item: sampleItems[4], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - id: '2dd4caf9-598a-317a-86d3-99432b223c18', - }, - ], - }, - { - ...sampleItems[5], - memberships: [ - { - item: sampleItems[5], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - id: '2dd4caf9-538a-317a-86d3-99432b223c18', - }, - ], - }, - { - ...sampleItems[6], - memberships: [ - { - item: sampleItems[6], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - id: '2dd4caf9-538a-317a-86d3-99432b223c12', - }, - ], - }, - ], - // memberships: [], -}; - -export const SAMPLE_READ_ITEMS: ApiConfig = { - items: [ - { - ...sampleItems[0], - memberships: [ - { - item: sampleItems[0], - permission: PermissionLevel.Read, - member: MEMBERS.ANNA, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130034', - creator: MEMBERS.BOB, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - ], -}; - -export const SAMPLE_BOOKMARK: ItemFavorite[] = [ - { - id: '49883c9b-050b-43d5-bd37-6921e25b55da5', - createdAt: '2021-08-11T12:56:36.834Z', - item: sampleItems[1], - }, - { - id: '49883c9b-050b-43d5-bd37-6921e25b55da', - createdAt: '2021-08-11T12:56:36.834Z', - item: sampleItems[2], - }, -]; - -export const RECYCLED_ITEM_DATA: RecycledItemData[] = [ - { - id: 'fdf09f5a-5688-22eb-ae93-0242ac130005', - creator: CURRENT_USER, - createdAt: '2021-08-11T12:56:36.834Z', - item: { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130005', - name: 'recycled item 1', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130005', - }, - }, - { - id: 'fdf12f5a-5688-22eb-ae93-0242ac130005', - creator: CURRENT_USER, - createdAt: '2021-08-11T12:56:36.834Z', - item: { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130006', - name: 'recycled item 2', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130006', - }, - }, -]; - export const generateOwnItems = (number: number): ItemForTest[] => { const id = (i: number) => `cafebabe-dead-beef-1234-${`${i}`.padStart(12, '0')}`; @@ -318,183 +51,7 @@ export const generateOwnItems = (number: number): ItemForTest[] => { }); }; -const sampleItemsforItemLogin: DiscriminatedItem[] = [ - { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', - name: 'item login with username', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130002', - name: 'no item login', - path: 'fdf09f5a_5688_11eb_ae93_0242ac130002', - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130003', - name: 'child of item login with username', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130003', - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130004', - name: 'item login with username and password', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130004', - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'ega2bd2a-5688-11eb-ae93-0242ac130002', - name: 'item login with username and password', - path: 'egafbd2a_5688_11eb_ae93_0242ac130002', - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'bdf09f5a-5688-11eb-ae93-0242ac130004', - name: 'child of item login with username and password', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130004.bdf09f5a_5688_11eb_ae93_0242ac130004', - }, -]; - -export const ITEM_LOGIN_ITEMS: ApiConfig = { - items: [ - { - ...sampleItemsforItemLogin[0], - itemLoginSchema: { - item: sampleItemsforItemLogin[0], - type: ItemLoginSchemaType.Username, - id: 'efaf3d5a-5688-11eb-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - - memberships: [ - { - id: 'edaf3d5a-5688-11eb-ae93-0242ac130002', - item: sampleItemsforItemLogin[0], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: sampleItemsforItemLogin[0], - permission: PermissionLevel.Read, - member: MEMBERS.BOB, - id: 'edaf3d5a-5688-21eb-ae93-0242ac130002', - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...sampleItemsforItemLogin[1], - memberships: [ - { - item: sampleItems[1], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - id: 'edaf3d5a-5688-21db-ae93-0242ac130002', - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...sampleItemsforItemLogin[2], - memberships: [ - { - item: sampleItemsforItemLogin[2], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - id: 'edaf3d3a-5688-21eb-ae93-0242ac130002', - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...sampleItemsforItemLogin[3], - itemLoginSchema: { - item: sampleItemsforItemLogin[3], - type: ItemLoginSchemaType.UsernameAndPassword, - id: 'efaf3d5a-5688-11eb-ae93-0242ac530002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - memberships: [ - { - item: sampleItemsforItemLogin[3], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - id: 'edaf2d5a-5688-21eb-ae93-0242ac130002', - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: sampleItemsforItemLogin[3], - permission: PermissionLevel.Read, - member: MEMBERS.BOB, - id: 'edaf3d5a-5682-21eb-ae93-0242ac130002', - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...sampleItemsforItemLogin[4], - itemLoginSchema: { - item: sampleItemsforItemLogin[4], - type: ItemLoginSchemaType.UsernameAndPassword, - id: 'efaf3d5a-5688-11eb-ae93-0242ac130102', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - - memberships: [ - { - item: sampleItemsforItemLogin[4], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - id: 'edaf3d5a-5682-22eb-ae93-0242ac130002', - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...sampleItemsforItemLogin[5], - memberships: [ - { - item: sampleItemsforItemLogin[5], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - id: 'edaf3d5a-5682-22eb-ee93-0242ac130002', - creator: MEMBERS.ANNA, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - itemLoginSchema: { - item: sampleItemsforItemLogin[3], - type: ItemLoginSchemaType.UsernameAndPassword, - id: 'efaf3d5a-5688-11eb-ae93-0242ac730002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - }, - ], -}; - -const samplePublicItems: DiscriminatedItem[] = [ +const samplePublicItems: PackedItem[] = [ { ...DEFAULT_FOLDER_ITEM, id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', @@ -665,65 +222,23 @@ export const SAMPLE_PUBLIC_ITEMS: ApiConfig = { id: 'ecbfbd2a-9644-12de-ae93-0242ac130002', }, ], - // memberships: [ - // { - // itemId: 'bdf09f5a-5688-11eb-ae93-0242ac130004', - // itemPath: 'bdf09f5a_5688_11eb_ae93_0242ac130004', - // permission: PermissionLevel.Admin, - // member: MEMBERS.ANNA, - // }, - // ], }, samplePublicItems[6], ], }; -export const SHORTCUT: ShortcutItemType = { - ...DEFAULT_FOLDER_ITEM, - id: 'gcafbd2a-5688-11eb-ae92-0242ac130002', - name: 'shortcut for own_item_name1', - path: 'gcafbd2a_5688_11eb_ae92_0242ac130002', - type: ItemType.SHORTCUT, - extra: { - [ItemType.SHORTCUT]: { target: 'gcafbd2a-5681-11eb-ae92-0242ac130002' }, - }, -}; - -export const ITEM_REORDER_ITEMS = { - parent: { - ...DEFAULT_FOLDER_ITEM, +// warning: admin permission on item +const item = PackedFolderItemFactory( + { id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', - name: 'parent', + name: 'parent public item', path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', }, - children: [ - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130003', - name: 'child1', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130003', - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130004', - name: 'child2', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130004', - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'fdf09f5a-5688-11eb-ae93-0242ac130005', - name: 'child3', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fdf09f5a_5688_11eb_ae93_0242ac130005', - }, - ], -}; - -const item: DiscriminatedItem = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', - name: 'parent public item', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', -}; + { + permission: PermissionLevel.Admin, + publicTag: { type: ItemTagType.Public }, + }, +); export const PUBLISHED_ITEM: ItemForTest = { ...item, @@ -764,6 +279,13 @@ export const PUBLISHED_ITEM: ItemForTest = { }, ], }; +export const PUBLISHED_ITEM_NO_TAGS: ItemForTest = { + ...PUBLISHED_ITEM, + settings: { + ...PUBLISHED_ITEM.settings, + tags: undefined, + }, +}; export const PUBLISHED_ITEM_VALIDATIONS = [ { id: '65c57d69-0e59-4569-a422-f330c31c995c', @@ -794,302 +316,3 @@ export const PUBLISHED_ITEM_VALIDATIONS = [ ] as unknown as ItemValidation[], }, ]; - -const hiddenItem: DiscriminatedItem = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130011', - name: 'parent hidden public item', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130011', -}; -export const HIDDEN_ITEM: ItemForTest = { - ...hiddenItem, - tags: [ - { - id: 'ecbfbd2a-5688-11eb-ae93-0242ac130001', - type: ItemTagType.Public, - item: hiddenItem, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - }, - { - id: 'ecbfbd2a-5688-12eb-ae93-0242ac130001', - type: ItemTagType.Hidden, - item: hiddenItem, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - }, - ], - memberships: [ - { - item: hiddenItem, - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: hiddenItem, - permission: PermissionLevel.Read, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], -}; - -export const CHILD_HIDDEN_ITEM: DiscriminatedItem = { - ...HIDDEN_ITEM, - id: 'ecafbd2a-3688-11eb-ae93-0242ac130003', - name: 'child of hidden item', - path: `${HIDDEN_ITEM.path}.ecafbd2a_3688_11eb_ae93_0242ac130003`, -}; - -const pinnedItem: DiscriminatedItem = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', - name: 'parent public item', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', -}; -export const PINNED_ITEM: ItemForTest = { - ...pinnedItem, - settings: { - isPinned: true, - showChatbox: true, - }, - memberships: [ - { - item: pinnedItem, - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae13-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], -}; - -const itemSetting: DiscriminatedItem = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130003', - name: 'parent public item', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130003', -}; -export const ITEMS_SETTINGS: ApiConfig = { - items: [ - HIDDEN_ITEM, - PINNED_ITEM, - { - ...itemSetting, - settings: { - isPinned: false, - showChatbox: false, - enableSaveActions: false, - }, - memberships: [ - { - item: itemSetting, - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'ecbfbd6a-5688-12db-ae13-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - CHILD_HIDDEN_ITEM, - ], -}; - -const itemCCLicenseCCBY: DiscriminatedItem = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130012', - name: 'public item with cc by', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130012', - settings: { ccLicenseAdaption: 'CC BY' }, -}; -const itemCCLicenseCCBYNC: DiscriminatedItem = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130022', - name: 'public item with cc by nc', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130022', - settings: { ccLicenseAdaption: 'CC BY-NC' }, -}; -const itemCCLicenseCCBYSA: DiscriminatedItem = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130032', - name: 'public item with cc by sa', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130032', - settings: { ccLicenseAdaption: 'CC BY-SA' }, -}; -const itemCCLicenseCCBYNCND: DiscriminatedItem = { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130042', - name: 'public item with cc by nc nd', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130042', - settings: { ccLicenseAdaption: 'CC BY-NC-ND' }, -}; - -export const PUBLISHED_ITEMS_WITH_CC_LICENSE: ItemForTest[] = [ - { - ...itemCCLicenseCCBY, - tags: [ - { - id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', - type: ItemTagType.Public, - item: itemCCLicenseCCBY, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - }, - ], - published: { - id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', - item: itemCCLicenseCCBY, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - totalViews: 0, - }, - memberships: [ - { - item: itemCCLicenseCCBY, - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: itemCCLicenseCCBY, - permission: PermissionLevel.Read, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...itemCCLicenseCCBYNC, - tags: [ - { - id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', - type: ItemTagType.Public, - item: itemCCLicenseCCBYNC, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - }, - ], - published: { - id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', - item: itemCCLicenseCCBYNC, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - totalViews: 0, - }, - memberships: [ - { - item: itemCCLicenseCCBYNC, - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: itemCCLicenseCCBYNC, - permission: PermissionLevel.Read, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...itemCCLicenseCCBYSA, - tags: [ - { - id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', - type: ItemTagType.Public, - item: itemCCLicenseCCBYSA, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - }, - ], - published: { - id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', - item: itemCCLicenseCCBYSA, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - totalViews: 0, - }, - memberships: [ - { - item: itemCCLicenseCCBYSA, - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: itemCCLicenseCCBYSA, - permission: PermissionLevel.Read, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...itemCCLicenseCCBYNCND, - tags: [ - { - id: 'ecbfbd2a-5688-11eb-ae93-0242ac130002', - type: ItemTagType.Public, - item: itemCCLicenseCCBYNCND, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - }, - ], - published: { - id: 'ecbfbd2a-5688-12eb-ae93-0242ac130002', - item: itemCCLicenseCCBYNCND, - createdAt: '2021-08-11T12:56:36.834Z', - creator: MEMBERS.ANNA, - totalViews: 0, - }, - memberships: [ - { - item: itemCCLicenseCCBYNCND, - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: itemCCLicenseCCBYNCND, - permission: PermissionLevel.Read, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - id: 'ecbfbd2a-5688-12db-ae93-0242ac130002', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, -]; diff --git a/cypress/fixtures/links.ts b/cypress/fixtures/links.ts index b5e240356..df0637f5b 100644 --- a/cypress/fixtures/links.ts +++ b/cypress/fixtures/links.ts @@ -1,22 +1,14 @@ import { ItemType, - LinkItemFactory, LinkItemType, + PackedLinkItemFactory, buildLinkExtra, } from '@graasp/sdk'; import { CURRENT_USER } from './members'; -export const GRAASP_LINK_ITEM: LinkItemType = LinkItemFactory({ - id: 'ecafbd2a-5688-11eb-ae91-0242ac130002', - type: ItemType.LINK, - name: 'graasp link', - description: 'a description for graasp link', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', +export const GRAASP_LINK_ITEM: LinkItemType = PackedLinkItemFactory({ creator: CURRENT_USER, - settings: {}, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', extra: buildLinkExtra({ url: 'https://graasp.eu', html: '', @@ -27,45 +19,36 @@ export const GRAASP_LINK_ITEM: LinkItemType = LinkItemFactory({ }), }); -export const GRAASP_LINK_ITEM_NO_PROTOCOL: LinkItemType = LinkItemFactory({ - id: 'ecafbd2a-5688-11eb-ae91-0242ac130002', - type: ItemType.LINK, - name: 'graasp link', - description: 'a description for graasp link', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', - creator: CURRENT_USER, - settings: {}, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - extra: buildLinkExtra({ - url: 'graasp.eu', - html: '', - thumbnails: ['https://graasp.eu/img/epfl/logo-tile.png'], - icons: [ - 'https://graasp.eu/cdn/img/epfl/favicons/favicon-32x32.png?v=yyxJ380oWY', - ], - }), -}); +export const GRAASP_LINK_ITEM_NO_PROTOCOL: LinkItemType = PackedLinkItemFactory( + { + creator: CURRENT_USER, + extra: buildLinkExtra({ + url: 'graasp.eu', + html: '', + thumbnails: ['https://graasp.eu/img/epfl/logo-tile.png'], + icons: [ + 'https://graasp.eu/cdn/img/epfl/favicons/favicon-32x32.png?v=yyxJ380oWY', + ], + }), + }, +); -export const GRAASP_LINK_ITEM_IFRAME_ONLY: LinkItemType = LinkItemFactory({ - ...GRAASP_LINK_ITEM, - id: 'ecafbd2a-5688-11eb-ae91-0242ac130122', - settings: { - showLinkIframe: true, - showLinkButton: false, +export const GRAASP_LINK_ITEM_IFRAME_ONLY: LinkItemType = PackedLinkItemFactory( + { + ...GRAASP_LINK_ITEM, + id: 'ecafbd2a-5688-11eb-ae91-0242ac130122', + settings: { + showLinkIframe: true, + showLinkButton: false, + }, }, -}); +); -export const YOUTUBE_LINK_ITEM: LinkItemType = LinkItemFactory({ - id: 'gcafbd2a-5688-11eb-ae93-0242ac130002', +export const YOUTUBE_LINK_ITEM: LinkItemType = PackedLinkItemFactory({ type: ItemType.LINK, name: 'graasp youtube link', description: 'a description for graasp youtube link', - settings: {}, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', creator: CURRENT_USER, - path: 'gcafbd2a_5688_11eb_ae93_0242ac130002', extra: buildLinkExtra({ url: 'https://www.youtube.com/watch?v=FmiEgBMTPLo', html: '
', @@ -74,14 +57,8 @@ export const YOUTUBE_LINK_ITEM: LinkItemType = LinkItemFactory({ }), }); -export const INVALID_LINK_ITEM: LinkItemType = LinkItemFactory({ - id: 'gcafbd2a-5688-11eb-ae93-0242ac130001', - path: 'gcafbd2a_5688_11eb_ae93_0242ac130001', - type: ItemType.LINK, +export const INVALID_LINK_ITEM: LinkItemType = PackedLinkItemFactory({ creator: CURRENT_USER, - settings: {}, - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', name: 'graasp youtube link', description: 'a description for graasp youtube link', extra: buildLinkExtra({ diff --git a/cypress/fixtures/memberships.ts b/cypress/fixtures/memberships.ts index b22996764..319ef5be0 100644 --- a/cypress/fixtures/memberships.ts +++ b/cypress/fixtures/memberships.ts @@ -2,6 +2,7 @@ import { DiscriminatedItem, ItemMembership, Member, + PackedFolderItemFactory, PermissionLevel, } from '@graasp/sdk'; @@ -27,27 +28,24 @@ export const buildItemMembership = (args: { }); const sampleItems: DiscriminatedItem[] = [ - { - ...DEFAULT_FOLDER_ITEM, + PackedFolderItemFactory({ id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', name: 'own_item_name1', path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', - }, - { - ...DEFAULT_FOLDER_ITEM, + }), + PackedFolderItemFactory({ id: 'fcafbd2a-5688-11eb-ae93-0242ac130002', name: 'own_item_name1', path: 'ecafbd2a_5688_11eb_ae93_0242ac130002.fcafbd2a_5688_11eb_ae93_0242ac130002', - }, - { - ...DEFAULT_FOLDER_ITEM, + }), + PackedFolderItemFactory({ id: 'fdf09f5a-5688-11eb-ae93-0242ac130002', name: 'own_item_name2', path: 'fdf09f5a_5688_11eb_ae93_0242ac130002', - }, + }), ]; -// eslint-disable-next-line import/prefer-default-export +// warning: actor has admin permission export const ITEMS_WITH_MEMBERSHIPS: ApiConfig = { items: [ { @@ -118,14 +116,17 @@ export const ITEMS_WITH_MEMBERSHIPS: ApiConfig = { ], }; -const sampleItemsWithWriteAccess: DiscriminatedItem[] = [ - { - ...DEFAULT_FOLDER_ITEM, - id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', - creator: MEMBERS.BOB, - name: 'own_item_name1', - path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', - }, +const sampleItemsWithWriteAccess = [ + PackedFolderItemFactory( + { + ...DEFAULT_FOLDER_ITEM, + id: 'ecafbd2a-5688-11eb-ae93-0242ac130002', + creator: MEMBERS.BOB, + name: 'own_item_name1', + path: 'ecafbd2a_5688_11eb_ae93_0242ac130002', + }, + { permission: PermissionLevel.Write }, + ), ]; export const ITEM_WITH_WRITE_ACCESS: ApiConfig = { diff --git a/cypress/fixtures/sharedItems.ts b/cypress/fixtures/sharedItems.ts deleted file mode 100644 index 8e2cf8bbd..000000000 --- a/cypress/fixtures/sharedItems.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { DiscriminatedItem, PermissionLevel } from '@graasp/sdk'; - -import { ApiConfig } from '../support/types'; -import { DEFAULT_FOLDER_ITEM } from './items'; -import { MEMBERS } from './members'; - -const items: DiscriminatedItem[] = [ - { - ...DEFAULT_FOLDER_ITEM, - creator: MEMBERS.BOB, - id: 'ecdfbd2a-5688-11eb-ae93-0242ac130002', - name: 'shared_item_name1', - path: 'ecdfbd2a_5688_11eb_ae93_0242ac130002', - }, - { - ...DEFAULT_FOLDER_ITEM, - creator: MEMBERS.CEDRIC, - id: 'fdf19f5a-5688-11eb-ae93-0242ac130002', - name: 'shared_item_name2', - path: 'fdf19f5a_5688_11eb_ae93_0242ac130002', - }, -]; - -// eslint-disable-next-line import/prefer-default-export -export const SHARED_ITEMS: ApiConfig = { - items: [ - { - ...items[0], - memberships: [ - { - item: items[0], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-04-13 14:56:34.749946', - updatedAt: '2021-04-13 14:56:34.749946', - id: 'e51797ec-c639-44c2-8681-2bb024a96db5', - }, - ], - }, - { - ...items[1], - memberships: [ - { - item: items[1], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - createdAt: '2021-04-13 14:56:34.749946', - updatedAt: '2021-04-13 14:56:34.749946', - id: 'e51797ec-c639-14c2-8681-2bb024a96db5', - }, - { - item: items[1], - permission: PermissionLevel.Read, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - createdAt: '2021-04-13 14:56:34.749946', - updatedAt: '2021-04-13 14:56:34.749946', - id: 'e51797ec-c639-44c2-4681-2bb024a96db5', - }, - ], - }, - ], -}; diff --git a/cypress/fixtures/thumbnails.ts b/cypress/fixtures/thumbnails.ts deleted file mode 100644 index 3eb3a370c..000000000 --- a/cypress/fixtures/thumbnails.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { DiscriminatedItem, PermissionLevel } from '@graasp/sdk'; - -import { ApiConfig } from '../support/types'; -import { DEFAULT_FOLDER_ITEM } from './items'; -import { MEMBERS } from './members'; -import { ITEM_THUMBNAIL_LINK } from './thumbnails/links'; - -export const THUMBNAIL_MEDIUM_PATH = 'cypress/fixtures/thumbnails/medium.jpeg'; - -const sampleItems: DiscriminatedItem[] = [ - { - ...DEFAULT_FOLDER_ITEM, - id: 'bfafbd2a-5688-11eb-ae93-0242ac130002', - name: 'own_item_name1', - path: 'bfafbd2a_5688_11eb_ae93_0242ac130002', - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'bfa09f5a-5688-11eb-ae93-0242ac130002', - name: 'own_item_name2', - path: 'bfa09f5a_5688_11eb_ae93_0242ac130002', - }, - { - ...DEFAULT_FOLDER_ITEM, - id: 'bfa09f5a-5688-11eb-ae93-0242ac130001', - name: 'own_item_name3', - path: 'bfa09f5a_5688_11eb_ae93_0242ac130001', - creator: MEMBERS.CEDRIC, - }, -]; - -// eslint-disable-next-line import/prefer-default-export -export const SAMPLE_ITEMS_WITH_THUMBNAILS: ApiConfig = { - items: [ - { - ...sampleItems[0], - memberships: [ - { - item: sampleItems[0], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'eb1a0d13-2a9b-489f-b2da-93a15ce574c0', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: sampleItems[0], - permission: PermissionLevel.Admin, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - id: 'eb1a0d13-2a9b-489f-b2fa-93a15ce574c0', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - { - ...sampleItems[1], - memberships: [ - { - item: sampleItems[1], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'eb1a0d13-2a9b-489e-b2fa-93a15ce574c0', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: sampleItems[1], - permission: PermissionLevel.Admin, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - id: 'eb1a0d13-2a9b-489f-b2fa-23a15ce574c0', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - thumbnails: ITEM_THUMBNAIL_LINK, - settings: { hasThumbnail: true }, - }, - { - ...sampleItems[2], - memberships: [ - { - item: sampleItems[2], - permission: PermissionLevel.Admin, - member: MEMBERS.CEDRIC, - creator: MEMBERS.ANNA, - id: 'eb1a0d13-2a9b-489f-b2fa-93a15ce174c0', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: sampleItems[2], - permission: PermissionLevel.Admin, - member: MEMBERS.BOB, - creator: MEMBERS.ANNA, - id: 'eb1a0d13-2a9b-489f-b2fa-93a17ce574c0', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - { - item: sampleItems[2], - permission: PermissionLevel.Admin, - member: MEMBERS.ANNA, - creator: MEMBERS.ANNA, - id: 'eb1a0d13-2a9b-489f-b2fa-93a15ce571c0', - createdAt: '2021-08-11T12:56:36.834Z', - updatedAt: '2021-08-11T12:56:36.834Z', - }, - ], - }, - ], -}; diff --git a/cypress/fixtures/thumbnails/links.ts b/cypress/fixtures/thumbnails/links.ts index a2b99cef6..11fd6a0a1 100644 --- a/cypress/fixtures/thumbnails/links.ts +++ b/cypress/fixtures/thumbnails/links.ts @@ -1,2 +1,4 @@ export const ITEM_THUMBNAIL_LINK = 'https://picsum.photos/200/200'; export const AVATAR_LINK = 'https://picsum.photos/200/200'; + +export const THUMBNAIL_MEDIUM_PATH = 'cypress/fixtures/thumbnails/medium.jpeg'; diff --git a/cypress/support/actionsUtils.ts b/cypress/support/actionsUtils.ts index 6c3601cc7..d9df4768d 100644 --- a/cypress/support/actionsUtils.ts +++ b/cypress/support/actionsUtils.ts @@ -5,6 +5,9 @@ import { } from '@/config/selectors'; const duplicateItem = ({ id }: { id: string }): void => { + // sorry I need this timeout otherwise the table reload and lose the click.. + // todo: to remove on table refactor + cy.wait(500); cy.get(`#${buildItemMenuButtonId(id)}`).click(); cy.get(`#${buildItemMenu(id)} .${ITEM_MENU_DUPLICATE_BUTTON_CLASS}`).click(); }; diff --git a/cypress/support/constants.ts b/cypress/support/constants.ts index 1f000b1a0..fbb068f25 100644 --- a/cypress/support/constants.ts +++ b/cypress/support/constants.ts @@ -20,7 +20,7 @@ export const REDIRECTION_TIME = 500; export const CAPTION_EDIT_PAUSE = 2000; export const ROW_HEIGHT = 48; -export const TABLE_MEMBERSHIP_RENDER_TIME = 3000; +export const TABLE_MEMBERSHIP_RENDER_TIME = 1000; export const FIXTURES_THUMBNAILS_FOLDER = './thumbnails'; export const CHATBOX_LOADING_TIME = 5000; export const PUBLISH_TAB_LOADING_TIME = 3000; diff --git a/cypress/support/editUtils.ts b/cypress/support/editUtils.ts index a39e94514..9e27ccfcc 100644 --- a/cypress/support/editUtils.ts +++ b/cypress/support/editUtils.ts @@ -23,6 +23,8 @@ export const editItem = ( }, mode = DEFAULT_ITEM_LAYOUT_MODE, ): void => { + // todo: remove on table refactor + cy.wait(500); const { id, type } = payload; switch (mode) { case ItemLayoutMode.Grid: { diff --git a/cypress/support/server.ts b/cypress/support/server.ts index bb021a8b0..9ed69e920 100644 --- a/cypress/support/server.ts +++ b/cypress/support/server.ts @@ -14,6 +14,7 @@ import { ItemValidationReview, Member, PermissionLevel, + PermissionLevelCompare, RecycledItemData, ShortLink, ShortLinkPayload, @@ -106,18 +107,16 @@ const API_HOST = Cypress.env('VITE_GRAASP_API_HOST'); const checkMembership = ({ item, - currentMember, }: { item: ItemForTest; currentMember: Member; + // eslint-disable-next-line arrow-body-style }) => { - // mock membership - const creator = item?.creator; - const haveMembership = - creator?.id === currentMember?.id || - item.memberships?.find(({ member }) => member.id === currentMember?.id); - - return haveMembership; + // todo: public + // TODO!!! + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + return PermissionLevelCompare.gte(item.permission, PermissionLevel.Read); }; export const redirectionReply = { @@ -357,7 +356,7 @@ export const mockGetItem = ( }); } - if (item?.tags?.find(({ type }) => type === ItemTagType.Public)) { + if (item.public) { return reply({ body: item, statusCode: StatusCodes.OK, @@ -398,13 +397,7 @@ export const mockGetItems = ({ itemIds.forEach((id) => { const item = getItemById(items, id); - // mock membership - const creator = item?.creator; - const haveMembership = - creator?.id === currentMember.id || - item?.memberships?.find( - ({ member }) => member.id === currentMember.id, - ); + const haveMembership = checkMembership({ item, currentMember }); if (!haveMembership) { result.errors.push({ @@ -441,7 +434,7 @@ export const mockGetChildren = ({ const children = items.filter(isChild(id)); - if (item?.tags?.find(({ type }) => type === ItemTagType.Public)) { + if (item.public) { return reply(children); } @@ -1278,7 +1271,7 @@ export const mockGetItemChat = ( const itemId = url.slice(API_HOST.length).split('/')[2]; const item = items.find(({ id }) => itemId === id); - return reply(item?.chat); + return reply(item?.chat ?? []); }, ).as('getItemChat'); }; diff --git a/cypress/support/types.ts b/cypress/support/types.ts index 7ac0fa399..04ff7e779 100644 --- a/cypress/support/types.ts +++ b/cypress/support/types.ts @@ -13,6 +13,7 @@ import { ItemValidationGroup, LocalFileItemType, Member, + PermissionLevel, S3FileItemType, } from '@graasp/sdk'; @@ -27,6 +28,8 @@ export type ItemForTest = DiscriminatedItem & { memberships?: ItemMembership[]; invitations?: Invitation[]; published?: ItemPublished; + permission?: PermissionLevel; + public?: ItemTag; }; // TODO: not ideal, to change? diff --git a/cypress/support/viewUtils.ts b/cypress/support/viewUtils.ts index 2d9db2452..752973913 100644 --- a/cypress/support/viewUtils.ts +++ b/cypress/support/viewUtils.ts @@ -27,6 +27,8 @@ import { import { CURRENT_USER } from '../fixtures/members'; import { ItemForTest, MemberForTest } from './types'; +const BR_REGEX = //g; + export const expectItemHeaderLayout = ({ item: { id, type, memberships, path }, currentMember, @@ -110,7 +112,12 @@ export const expectLinkViewScreenLayout = ({ } if (description) { - cy.get(`.${TEXT_EDITOR_CLASS}`).should('contain', description); + cy.get(`.${TEXT_EDITOR_CLASS}`).then((element) => { + // fix a few flacky tests that fail because the element contains br tags, + // as opposed to the description, which contains \n. + const cleanElement = element.html().replace(BR_REGEX, '\n'); + expect(cleanElement).to.contain(description); + }); } expectItemHeaderLayout({ item, currentMember }); diff --git a/package.json b/package.json index 66f3bb580..802587ca3 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,10 @@ "@emotion/styled": "11.11.5", "@graasp/chatbox": "3.1.0", "@graasp/map": "1.11.1", - "@graasp/query-client": "3.7.0", + "@graasp/query-client": "3.8.0", "@graasp/sdk": "4.9.0", "@graasp/translations": "1.28.0", - "@graasp/ui": "4.17.0", + "@graasp/ui": "4.17.1", "@mui/icons-material": "5.15.15", "@mui/lab": "5.0.0-alpha.170", "@mui/material": "5.15.15", diff --git a/src/components/App.tsx b/src/components/App.tsx index 75111169f..c9df3a867 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -18,7 +18,6 @@ import { PUBLISHED_ITEMS_PATH, RECYCLE_BIN_PATH, REDIRECT_PATH, - SHARED_ITEMS_PATH, buildItemPath, } from '../config/paths'; import { hooks } from '../config/queryClient'; @@ -30,7 +29,6 @@ import HomeScreen from './pages/HomeScreen'; import MapItemsScreen from './pages/MapItemsScreen'; import PublishedItemsScreen from './pages/PublishedItemsScreen'; import RecycledItemsScreen from './pages/RecycledItemsScreen'; -import SharedItemsScreen from './pages/SharedItemsScreen'; import ItemInformationPage from './pages/item/ItemInformationPage'; import ItemPageLayout from './pages/item/ItemPageLayout'; import ItemScreen from './pages/item/ItemScreen'; @@ -67,10 +65,6 @@ const App = (): JSX.Element => { HomeScreen, withAuthorizationProps, ); - const SharedWithAuthorization = withAuthorization( - SharedItemsScreen, - withAuthorizationProps, - ); const FavoriteWithAuthorization = withAuthorization( BookmarkedItemsScreen, withAuthorizationProps, @@ -95,7 +89,6 @@ const App = (): JSX.Element => { } > } /> - } /> } diff --git a/src/components/common/Chatbox.tsx b/src/components/common/Chatbox.tsx index 551aee60c..c31ab6fb2 100644 --- a/src/components/common/Chatbox.tsx +++ b/src/components/common/Chatbox.tsx @@ -1,5 +1,5 @@ import { Chatbox as GraaspChatbox } from '@graasp/chatbox'; -import { DiscriminatedItem, PermissionLevel } from '@graasp/sdk'; +import { PackedItem, PermissionLevel } from '@graasp/sdk'; import { Loader } from '@graasp/ui'; import { hooks, mutations } from '../../config/queryClient'; @@ -14,7 +14,7 @@ const { } = mutations; type Props = { - item: DiscriminatedItem; + item: PackedItem; }; const Chatbox = ({ item }: Props): JSX.Element | null => { @@ -39,9 +39,7 @@ const Chatbox = ({ item }: Props): JSX.Element | null => { } // only show export chat when user has admin right on the item - const isAdmin = - itemPermissions?.find((perms) => perms.member.id === currentMember.id) - ?.permission === PermissionLevel.Admin; + const isAdmin = item.permission === PermissionLevel.Admin; return ( void; }; @@ -25,13 +25,10 @@ const HideButton = ({ }: Props): JSX.Element => { const { t: translateBuilder } = useBuilderTranslation(); - const { data: tags } = hooks.useItemTags(item.id); const postTag = mutations.usePostItemTag(); const deleteTag = mutations.useDeleteItemTag(); - const hiddenTag = tags?.filter( - ({ type: tagType }) => tagType === ItemTagType.Hidden, - )?.[0]; + const hiddenTag = item.hidden; // since children items are hidden because parent is hidden, the hidden tag should be removed from the root item // if hiddenTag is undefined -> the item is not hidden const isOriginalHiddenItem = diff --git a/src/components/common/MoveButton.tsx b/src/components/common/MoveButton.tsx index 83bcfe04f..3dbd6be83 100644 --- a/src/components/common/MoveButton.tsx +++ b/src/components/common/MoveButton.tsx @@ -69,7 +69,7 @@ const MoveButton = ({ item: NavigationElement, homeId: string, ) => { - if (items) { + if (items?.length) { // cannot move inside self and below const moveInSelf = items.some((i) => item.path.includes(i.path)); @@ -81,9 +81,8 @@ const MoveButton = ({ // cannot move to home if was already on home let moveToHome = false; - if (items) { - moveToHome = item.id === homeId && !getDirectParentId(items[0].path); - } + moveToHome = item.id === homeId && !getDirectParentId(items[0].path); + return moveInSelf || moveInDirectParent || moveToHome; } return false; diff --git a/src/components/item/ItemContent.tsx b/src/components/item/ItemContent.tsx index 71966061e..cc4d4bbd6 100644 --- a/src/components/item/ItemContent.tsx +++ b/src/components/item/ItemContent.tsx @@ -109,6 +109,7 @@ const LinkContent = ({ }): JSX.Element => ( (({ theme, open }) => { type Props = { children: JSX.Element | JSX.Element[]; - item: DiscriminatedItem; + item: PackedItem; id?: string; }; diff --git a/src/components/item/header/ItemHeaderActions.tsx b/src/components/item/header/ItemHeaderActions.tsx index d44be26ae..63d5b21a5 100644 --- a/src/components/item/header/ItemHeaderActions.tsx +++ b/src/components/item/header/ItemHeaderActions.tsx @@ -7,7 +7,6 @@ import { ChatboxButton } from '@graasp/ui'; import EditButton from '@/components/common/EditButton'; import DownloadButton from '@/components/main/DownloadButton'; -import { useGetPermissionForItem } from '@/hooks/authorization'; import { ITEM_TYPES_WITH_CAPTIONS } from '../../../config/constants'; import { useBuilderTranslation } from '../../../config/i18n'; @@ -31,12 +30,11 @@ const ItemHeaderActions = (): JSX.Element => { const { data: item } = useItem(itemId); - const { data: permission } = useGetPermissionForItem(item); - const canWrite = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Write) + const canWrite = item?.permission + ? PermissionLevelCompare.gte(item.permission, PermissionLevel.Write) : false; - const canAdmin = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Admin) + const canAdmin = item?.permission + ? PermissionLevelCompare.gte(item.permission, PermissionLevel.Admin) : false; const onClickChatbox = () => { diff --git a/src/components/item/publish/ItemPublishButton.tsx b/src/components/item/publish/ItemPublishButton.tsx index caec99460..ee29860c6 100644 --- a/src/components/item/publish/ItemPublishButton.tsx +++ b/src/components/item/publish/ItemPublishButton.tsx @@ -31,7 +31,6 @@ const ItemPublishButton = ({ }: Props): JSX.Element | null => { const { t: translateBuilder } = useBuilderTranslation(); - // item tags const { mutate: unpublish, isLoading: isUnPublishing } = useUnpublishItem(); const { mutate: publishItem, isLoading: isPublishing } = usePublishItem(); diff --git a/src/components/item/publish/ItemPublishTab.tsx b/src/components/item/publish/ItemPublishTab.tsx index d7996b6b6..006228e9a 100644 --- a/src/components/item/publish/ItemPublishTab.tsx +++ b/src/components/item/publish/ItemPublishTab.tsx @@ -21,19 +21,11 @@ import { Typography, } from '@mui/material'; -import { - ItemTagType, - ItemValidationStatus, - PermissionLevel, - PermissionLevelCompare, - redirect, -} from '@graasp/sdk'; -import { Loader } from '@graasp/ui'; +import { ItemValidationStatus, redirect } from '@graasp/sdk'; import groupBy from 'lodash.groupby'; import { OutletType } from '@/components/pages/item/type'; -import { useGetPermissionForItem } from '@/hooks/authorization'; import { ADMIN_CONTACT, CC_LICENSE_ABOUT_URL } from '../../../config/constants'; import { useBuilderTranslation } from '../../../config/i18n'; @@ -51,7 +43,7 @@ import CoEditorSettings from './CoEditorSettings'; import CustomizedTagsEdit from './CustomizedTagsEdit'; import ItemPublishButton from './ItemPublishButton'; -const { useItemTags, useLastItemValidationGroup } = hooks; +const { useLastItemValidationGroup } = hooks; const { usePostItemValidation } = mutations; @@ -63,28 +55,12 @@ const enum PublishFlow { const ItemPublishTab = (): JSX.Element => { const { t: translateBuilder } = useBuilderTranslation(); - const { item } = useOutletContext(); - - const { data: itemTags, isLoading: isItemTagsLoading } = useItemTags( - item?.id, - ); - - const { - data: permission, - isCurrentMemberLoading, - isMembershipsLoading, - } = useGetPermissionForItem(item); - const canWrite = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Write) - : false; - const canAdmin = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Admin) - : false; + const { item, canWrite, canAdmin } = useOutletContext(); const [validationStatus, setValidationStatus] = useState(null); - const isPublic = itemTags?.find(({ type }) => type === ItemTagType.Public); + const isPublic = item.public; // item validation const { mutate: validateItem } = usePostItemValidation(); @@ -131,10 +107,6 @@ const ItemPublishTab = (): JSX.Element => { return PublishFlow.PUBLISH_STEP; })(); - if (isMembershipsLoading || isCurrentMemberLoading || isItemTagsLoading) { - return ; - } - if (!canWrite || !canAdmin) { return ( diff --git a/src/components/item/settings/AdminChatSettings.tsx b/src/components/item/settings/AdminChatSettings.tsx index 9910f0212..e009a4e1d 100644 --- a/src/components/item/settings/AdminChatSettings.tsx +++ b/src/components/item/settings/AdminChatSettings.tsx @@ -1,30 +1,26 @@ -import { DiscriminatedItem, PermissionLevel } from '@graasp/sdk'; +import { PackedItem, PermissionLevel } from '@graasp/sdk'; import { useBuilderTranslation } from '@/config/i18n'; import { BUILDER } from '@/langs/constants'; -import { hooks } from '../../../config/queryClient'; import { useCurrentUserContext } from '../../context/CurrentUserContext'; import ClearChatButton from './ClearChatButton'; import ItemSettingProperty from './ItemSettingProperty'; type Props = { - item: DiscriminatedItem; + item: PackedItem; }; const AdminChatSettings = ({ item }: Props): JSX.Element | null => { const itemId = item.id; const { t } = useBuilderTranslation(); - const { data: itemPermissions, isLoading: isLoadingItemPermissions } = - hooks.useItemMemberships(item.id); const { data: currentMember } = useCurrentUserContext(); // only show export chat when user has admin right on the item const isAdmin = currentMember - ? itemPermissions?.find((perms) => perms.member.id === currentMember.id) - ?.permission === PermissionLevel.Admin + ? item?.permission === PermissionLevel.Admin : false; - if (!isAdmin || isLoadingItemPermissions) { + if (!isAdmin) { return null; } diff --git a/src/components/item/settings/LanguageSelect.tsx b/src/components/item/settings/LanguageSelect.tsx index c9e0dcff5..97b5f123d 100644 --- a/src/components/item/settings/LanguageSelect.tsx +++ b/src/components/item/settings/LanguageSelect.tsx @@ -1,7 +1,7 @@ import { SelectProps } from '@mui/material'; import { - DiscriminatedItem, + PackedItem, PermissionLevel, PermissionLevelCompare, } from '@graasp/sdk'; @@ -10,14 +10,12 @@ import { Select } from '@graasp/ui'; import { mutations } from '@/config/queryClient'; import { LANGUAGE_SELECTOR_ID } from '@/config/selectors'; -import { useGetPermissionForItem } from '@/hooks/authorization'; -const LanguageSelect = ({ item }: { item: DiscriminatedItem }): JSX.Element => { +const LanguageSelect = ({ item }: { item: PackedItem }): JSX.Element => { const { mutate: changeLang } = mutations.useEditItem(); - const { data: permission } = useGetPermissionForItem(item); - const canWrite = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Write) + const canWrite = item.permission + ? PermissionLevelCompare.gte(item.permission, PermissionLevel.Write) : false; const onChange: SelectProps['onChange'] = (e) => { diff --git a/src/components/item/sharing/ItemLoginMembershipsTable.tsx b/src/components/item/sharing/ItemLoginMembershipsTable.tsx new file mode 100644 index 000000000..bd54e4f6e --- /dev/null +++ b/src/components/item/sharing/ItemLoginMembershipsTable.tsx @@ -0,0 +1,51 @@ +import { useOutletContext } from 'react-router'; + +import { Typography } from '@mui/material'; + +import { DiscriminatedItem, ItemMembership } from '@graasp/sdk'; + +import { OutletType } from '@/components/pages/item/type'; +import { useBuilderTranslation } from '@/config/i18n'; +import { hooks } from '@/config/queryClient'; +import { BUILDER } from '@/langs/constants'; +import { selectHighestMemberships } from '@/utils/membership'; + +import ItemMembershipsTable from './ItemMembershipsTable'; + +type Props = { item: DiscriminatedItem; memberships: ItemMembership[] }; + +const ItemLoginMembershipsTable = ({ + item, + memberships, +}: Props): JSX.Element | null => { + const { t: translateBuilder } = useBuilderTranslation(); + const { canAdmin } = useOutletContext(); + const { data: itemLoginSchema } = hooks.useItemLoginSchema({ + itemId: item.id, + }); + + if (itemLoginSchema) { + // show authenticated members if login schema is defined + // todo: show only if item is pseudomized + return ( + <> + + {translateBuilder(BUILDER.SHARING_AUTHENTICATED_MEMBERS_TITLE)} + + + + ); + } + + return null; +}; + +export default ItemLoginMembershipsTable; diff --git a/src/components/item/sharing/ItemMembershipsTable.tsx b/src/components/item/sharing/ItemMembershipsTable.tsx index 8d870a050..f8f8ac541 100644 --- a/src/components/item/sharing/ItemMembershipsTable.tsx +++ b/src/components/item/sharing/ItemMembershipsTable.tsx @@ -225,6 +225,9 @@ const ItemMembershipsTable = ({ isClickable={false} emptyMessage={emptyMessage} countTextFunction={countTextFunction} + totalCount={memberships.length} + pageSize={memberships.length} + page={0} /> {open && ( { - const permissionMap = memberships.reduce((acc, curr) => { - const { member, permission } = curr; - - if ( - !acc[member.id] || - PermissionLevelCompare.gt(permission, acc[member.id].permission) - ) { - acc[member.id] = curr; - } - return acc; - }, {}); - - return Object.values(permissionMap); -}; - const ItemSharingTab = (): JSX.Element => { const { t: translateBuilder } = useBuilderTranslation(); - const { item } = useOutletContext(); + const { item, canWrite, canAdmin } = useOutletContext(); const { itemId } = useParams(); const { data: memberships } = hooks.useItemMemberships(itemId); - const { data: invitations } = hooks.useItemInvitations(item?.id); - const { data: itemLoginSchema, isLoading: isItemLoginLoading } = - hooks.useItemLoginSchema({ itemId: item.id }); - - const { data: permission, isLoading } = useGetPermissionForItem(item); - - const canWrite = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Write) - : false; - const canAdmin = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Admin) - : false; + const [authenticatedMemberships, authorizedMemberships] = partition( + memberships, + ({ member }) => member?.email && isPseudoMember(member), + ); - if (isLoading && isItemLoginLoading) { - return ; - } + const { data: invitations } = hooks.useItemInvitations(item?.id); const renderMembershipSettings = () => { // do not display settings if cannot access memberships if (!memberships || !canWrite) { return null; } - const [authenticatedMemberships, authorizedMemberships] = partition( - memberships, - ({ member }) => member?.email && isPseudoMember(member), - ); return ( <> @@ -102,27 +61,11 @@ const ItemSharingTab = (): JSX.Element => { memberships={selectHighestMemberships(authorizedMemberships)} readOnly={!canAdmin} /> - - {/* show authenticated members if login schema is defined - todo: show only if item is pseudomized - */} - {itemLoginSchema && ( - <> - - - {translateBuilder(BUILDER.SHARING_AUTHENTICATED_MEMBERS_TITLE)} - - - - )} + + {invitations && Boolean(invitations?.length) && ( <> diff --git a/src/components/item/sharing/VisibilitySelect.tsx b/src/components/item/sharing/VisibilitySelect.tsx index 0a1fd9707..162628b78 100644 --- a/src/components/item/sharing/VisibilitySelect.tsx +++ b/src/components/item/sharing/VisibilitySelect.tsx @@ -1,13 +1,8 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { MenuItem, Select, SelectChangeEvent, Typography } from '@mui/material'; -import { - DiscriminatedItem, - ItemLoginSchemaType, - ItemTag, - ItemTagType, -} from '@graasp/sdk'; +import { ItemLoginSchemaType, ItemTagType, PackedItem } from '@graasp/sdk'; import { Loader } from '@graasp/ui'; import { SETTINGS } from '../../../config/constants'; @@ -17,7 +12,7 @@ import { SHARE_ITEM_VISIBILITY_SELECT_ID } from '../../../config/selectors'; import { BUILDER } from '../../../langs/constants'; import ItemLoginSchemaSelect from './ItemLoginSchemaSelect'; -const { useItemTags, useItemLoginSchema, useItemPublishedInformation } = hooks; +const { useItemLoginSchema, useItemPublishedInformation } = hooks; const { useDeleteItemTag, usePostItemTag, @@ -27,34 +22,25 @@ const { } = mutations; type Props = { - item: DiscriminatedItem; + item: PackedItem; edit?: boolean; }; -const useVisibility = (item: DiscriminatedItem) => { - const [itemId] = useState(item.id); - - // get item public - const { - data: itemTags, - isLoading: isItemTagsLoading, - isError: isItemTagsError, - } = useItemTags(itemId); +const useVisibility = (item: PackedItem) => { const { mutate: postItemTag } = usePostItemTag(); const { mutate: deleteItemTag } = useDeleteItemTag(); - const [publicTag, setPublicTag] = useState(); - useEffect(() => { - setPublicTag(itemTags?.find(({ type }) => type === ItemTagType.Public)); - }, [itemTags]); // get item published const { data: itemPublishEntry, isLoading: isItemPublishEntryLoading } = - useItemPublishedInformation({ itemId }, { enabled: Boolean(publicTag) }); + useItemPublishedInformation( + { itemId: item.id }, + { enabled: Boolean(item.public) }, + ); const { mutate: unpublish } = useUnpublishItem(); // item login tag and item extra value const { data: itemLoginSchema, isLoading: isItemLoginLoading } = - useItemLoginSchema({ itemId }); + useItemLoginSchema({ itemId: item.id }); const { mutate: deleteItemLoginSchema } = useDeleteItemLoginSchema(); const { mutate: putItemLoginSchema } = usePutItemLoginSchema(); @@ -65,30 +51,25 @@ const useVisibility = (item: DiscriminatedItem) => { setIsDisabled( Boolean( (itemLoginSchema && itemLoginSchema?.item?.path !== item?.path) || - (publicTag && publicTag?.item?.path !== item?.path), + (item?.public && item?.public?.item?.path !== item?.path), ), ); - }, [publicTag, itemLoginSchema, item]); + }, [itemLoginSchema, item]); // is loading const [isLoading, setIsLoading] = useState(false); useEffect(() => { - setIsLoading( - isItemPublishEntryLoading || isItemTagsLoading || isItemLoginLoading, - ); - }, [isItemPublishEntryLoading, isItemTagsLoading, isItemLoginLoading]); + setIsLoading(isItemPublishEntryLoading || isItemLoginLoading); + }, [isItemPublishEntryLoading, isItemLoginLoading]); // is error - const [isError, setIsError] = useState(false); - useEffect(() => { - setIsError(isItemTagsError); - }, [isItemTagsError]); + const [isError] = useState(false); // visibility const [visibility, setVisibility] = useState(); useEffect(() => { switch (true) { - case Boolean(publicTag?.id): { + case Boolean(item.public): { setVisibility(SETTINGS.ITEM_PUBLIC.name); break; } @@ -99,67 +80,92 @@ const useVisibility = (item: DiscriminatedItem) => { default: setVisibility(SETTINGS.ITEM_PRIVATE.name); } - }, [itemPublishEntry, publicTag, itemLoginSchema]); - - const handleChange = (event: SelectChangeEvent) => { - const newTag = event.target.value; - - // deletes both public and published tags if they exists - const deletePublishedAndPublic = () => { - if (itemPublishEntry) { - unpublish({ id: itemId }); - } - - if (publicTag) { - deleteItemTag({ itemId, type: ItemTagType.Public }); - } - }; - - const deleteLoginSchema = () => { - if (itemLoginSchema) { - deleteItemLoginSchema({ - itemId, - }); - } - }; - - switch (newTag) { - case SETTINGS.ITEM_PRIVATE.name: { - deletePublishedAndPublic(); - deleteLoginSchema(); - break; - } - case SETTINGS.ITEM_LOGIN.name: { - deletePublishedAndPublic(); - putItemLoginSchema({ - itemId, - type: ItemLoginSchemaType.Username, - }); - break; - } - case SETTINGS.ITEM_PUBLIC.name: { - postItemTag({ - itemId, - type: ItemTagType.Public, - }); - deleteLoginSchema(); - break; + }, [itemPublishEntry, item, itemLoginSchema]); + + const handleChange = useMemo( + () => (event: SelectChangeEvent) => { + const newTag = event.target.value; + + // deletes both public and published tags if they exists + const deletePublishedAndPublic = () => { + if (itemPublishEntry) { + unpublish({ id: item.id }); + } + + if (item.public) { + deleteItemTag({ itemId: item.id, type: ItemTagType.Public }); + } + }; + + const deleteLoginSchema = () => { + if (itemLoginSchema) { + deleteItemLoginSchema({ + itemId: item.id, + }); + } + }; + + switch (newTag) { + case SETTINGS.ITEM_PRIVATE.name: { + deletePublishedAndPublic(); + deleteLoginSchema(); + break; + } + case SETTINGS.ITEM_LOGIN.name: { + deletePublishedAndPublic(); + putItemLoginSchema({ + itemId: item.id, + type: ItemLoginSchemaType.Username, + }); + break; + } + case SETTINGS.ITEM_PUBLIC.name: { + postItemTag({ + itemId: item.id, + type: ItemTagType.Public, + }); + deleteLoginSchema(); + break; + } + default: + break; } - default: - break; - } - }; + }, + [ + deleteItemLoginSchema, + deleteItemTag, + item.id, + itemLoginSchema, + itemPublishEntry, + postItemTag, + item.public, + putItemLoginSchema, + unpublish, + ], + ); - return { - isLoading, - isError, - isDisabled, - itemPublishEntry, - itemLoginSchema, - publicTag, - visibility, - handleChange, - }; + return useMemo( + () => ({ + isLoading, + isError, + isDisabled, + itemPublishEntry, + itemLoginSchema, + publicTag: item.public, + visibility, + handleChange, + }), + [ + isLoading, + isError, + isDisabled, + itemPublishEntry, + itemLoginSchema, + item.public, + visibility, + handleChange, + ], + ); }; const VisibilitySelect = ({ item, edit }: Props): JSX.Element | null => { diff --git a/src/components/main/ItemCard.tsx b/src/components/main/ItemCard.tsx index 960023c32..fc8e41fca 100644 --- a/src/components/main/ItemCard.tsx +++ b/src/components/main/ItemCard.tsx @@ -4,9 +4,8 @@ import { Link } from 'react-router-dom'; import { Box } from '@mui/material'; import { - DiscriminatedItem, - ItemMembership, ItemType, + PackedItem, PermissionLevel, PermissionLevelCompare, ThumbnailSize, @@ -15,8 +14,6 @@ import { Card as GraaspCard, ItemIcon, Thumbnail } from '@graasp/ui'; import truncate from 'lodash.truncate'; -import { useGetPermissionForItem } from '@/hooks/authorization'; - import { DESCRIPTION_MAX_LENGTH } from '../../config/constants'; import { buildItemPath } from '../../config/paths'; import { hooks } from '../../config/queryClient'; @@ -41,15 +38,13 @@ const NameWrapper = ({ id, style }: { id: string; style: CSSProperties }) => { }; type Props = { - item: DiscriminatedItem; - memberships?: ItemMembership[]; + item: PackedItem; itemsStatuses?: ItemsStatuses; canMove?: boolean; }; const ItemComponent = ({ item, - memberships, itemsStatuses, canMove = true, }: Props): JSX.Element => { @@ -94,13 +89,12 @@ const ItemComponent = ({ ); const { data: member } = useCurrentUserContext(); - const { data: permission } = useGetPermissionForItem(item, memberships); - const canWrite = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Write) + const canWrite = item.permission + ? PermissionLevelCompare.gte(item.permission, PermissionLevel.Write) : false; - const canAdmin = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Admin) + const canAdmin = item.permission + ? PermissionLevelCompare.gte(item.permission, PermissionLevel.Admin) : false; const Actions = ( diff --git a/src/components/main/ItemMenu.tsx b/src/components/main/ItemMenu.tsx index 56faccff9..fe5545509 100644 --- a/src/components/main/ItemMenu.tsx +++ b/src/components/main/ItemMenu.tsx @@ -11,10 +11,10 @@ import { MenuItem, } from '@mui/material'; -import { DiscriminatedItem } from '@graasp/sdk'; +import { PackedItem } from '@graasp/sdk'; import { ActionButton } from '@graasp/ui'; -import { hooks, mutations } from '@/config/queryClient'; +import { mutations } from '@/config/queryClient'; import { getParentsIdsFromPath } from '@/utils/item'; import { useBuilderTranslation } from '../../config/i18n'; @@ -39,7 +39,7 @@ import CopyButton from './CopyButton'; import CreateShortcutButton from './CreateShortcutButton'; type Props = { - item: DiscriminatedItem; + item: PackedItem; canWrite?: boolean; canAdmin?: boolean; canMove?: boolean; @@ -56,7 +56,6 @@ const ItemMenu = ({ const { t: translateBuilder } = useBuilderTranslation(); const { openModal: openFlagModal } = useContext(FlagItemModalContext); const { mutate: copyItems } = mutations.useCopyItems(); - const { data: memberships } = hooks.useItemMemberships(item.id); const handleClick: IconButtonProps['onClick'] = (event) => { setAnchorEl(event.currentTarget); @@ -118,7 +117,7 @@ const ItemMenu = ({ return null; }; - if (memberships && member?.id) { + if (member?.id) { return ( <> JSX.Element; @@ -30,7 +27,6 @@ type Props = { }; parentId?: string; showThumbnails?: boolean; - enableMemberships?: boolean; canMove?: boolean; onShowOnlyMeChange?: ShowOnlyMeChangeType; showOnlyMe?: boolean; @@ -55,7 +51,6 @@ const Items = ({ parentId, defaultSortedColumn, showThumbnails = true, - enableMemberships = true, canMove = true, showOnlyMe = false, itemSearch, @@ -68,14 +63,8 @@ const Items = ({ showDropzoneHelper = false, }: Props): JSX.Element | null => { const { mode } = useLayoutContext(); - const itemIds = items?.map(({ id: itemId }) => itemId); - const { data: manyMemberships } = useManyItemMemberships( - enableMemberships ? itemIds : [], - ); - const { data: itemsTags } = useItemsTags(itemIds); const itemsStatuses = useItemsStatuses({ items, - itemsTags, }); switch (mode) { case ItemLayoutMode.Map: { @@ -102,7 +91,6 @@ const Items = ({ parentId={parentId} title={title} items={items} - manyMemberships={manyMemberships} itemsStatuses={itemsStatuses} // This enables the possibility to display messages (item is empty, no search result) itemSearch={itemSearch} @@ -124,7 +112,6 @@ const Items = ({ defaultSortedColumn={defaultSortedColumn} onSortChanged={onSortChanged} items={items} - manyMemberships={manyMemberships} itemsStatuses={itemsStatuses} headerElements={headerElements} isSearching={Boolean(itemSearch?.text)} diff --git a/src/components/main/ItemsGrid.tsx b/src/components/main/ItemsGrid.tsx index 494ff0040..25c1a79c6 100644 --- a/src/components/main/ItemsGrid.tsx +++ b/src/components/main/ItemsGrid.tsx @@ -1,12 +1,11 @@ import { Box, Grid, Pagination } from '@mui/material'; -import { DiscriminatedItem, ItemMembership, ResultOf } from '@graasp/sdk'; +import { PackedItem } from '@graasp/sdk'; import { ShowOnlyMeChangeType } from '@/config/types'; import { ITEM_PAGE_SIZE } from '../../config/constants'; import { ITEMS_GRID_PAGINATION_ID } from '../../config/selectors'; -import { getMembershipsForItem } from '../../utils/membership'; import FolderDescription from '../item/FolderDescription'; import { NoItemSearchResult } from '../item/ItemSearch'; import { ItemsStatuses } from '../table/BadgesCellRenderer'; @@ -16,8 +15,7 @@ import ItemsToolbar from './ItemsToolbar'; type Props = { id?: string; - items?: DiscriminatedItem[]; - manyMemberships?: ResultOf; + items?: PackedItem[]; itemsStatuses?: ItemsStatuses; title: string; itemSearch?: { @@ -39,7 +37,6 @@ const ItemsGrid = ({ title, itemSearch, headerElements = [], - manyMemberships, itemsStatuses, parentId, onShowOnlyMeChange, @@ -61,15 +58,7 @@ const ItemsGrid = ({ return items.map((item) => ( - + )); }; diff --git a/src/components/main/ItemsTable.tsx b/src/components/main/ItemsTable.tsx index 0062a49e7..7426048d6 100644 --- a/src/components/main/ItemsTable.tsx +++ b/src/components/main/ItemsTable.tsx @@ -3,9 +3,9 @@ import { useNavigate, useParams } from 'react-router-dom'; import { DiscriminatedItem, - ItemMembership, ItemType, - ResultOf, + PermissionLevel, + PermissionLevelCompare, formatDate, getFolderExtra, getShortcutExtra, @@ -21,7 +21,6 @@ import { } from '@ag-grid-community/core'; import { ShowOnlyMeChangeType } from '@/config/types'; -import { useGetPermissionForItem } from '@/hooks/authorization'; import { ITEMS_TABLE_CONTAINER_HEIGHT } from '../../config/constants'; import i18n, { @@ -33,7 +32,6 @@ import { buildItemPath } from '../../config/paths'; import { hooks, mutations } from '../../config/queryClient'; import { buildItemsTableRowId } from '../../config/selectors'; import { BUILDER } from '../../langs/constants'; -import { useCurrentUserContext } from '../context/CurrentUserContext'; import DropzoneHelper from '../file/DropzoneHelper'; import FolderDescription from '../item/FolderDescription'; import ActionsCellRenderer from '../table/ActionsCellRenderer'; @@ -47,7 +45,6 @@ const { useItem } = hooks; export type ItemsTableProps = { id?: string; items?: DiscriminatedItem[]; - manyMemberships?: ResultOf; itemsStatuses?: ItemsStatuses; tableTitle: string; headerElements?: JSX.Element[]; @@ -77,7 +74,6 @@ const ItemsTable = ({ tableTitle, id: tableId = '', items: rows = [], - manyMemberships, itemsStatuses, headerElements = [], isSearching = false, @@ -104,7 +100,6 @@ const ItemsTable = ({ const { itemId } = useParams(); const { data: parentItem } = useItem(itemId); - const { data: member } = useCurrentUserContext(); const { mutate: editItem } = mutations.useEditItem(); @@ -178,8 +173,6 @@ const ItemsTable = ({ translateBuilder(BUILDER.ITEMS_TABLE_DRAG_DEFAULT_MESSAGE); const ActionComponent = ActionsCellRenderer({ - manyMemberships, - member, canMove, }); @@ -274,9 +267,10 @@ const ItemsTable = ({ count: selected.length, }); - const { data: itemPermission } = useGetPermissionForItem(parentItem); const shouldShowDropzoneHelper = showDropzoneHelper && rows?.length === 0; - const canEditItem = itemPermission === 'admin' || itemPermission === 'write'; + const canEditItem = parentItem?.permission + ? PermissionLevelCompare.gte(parentItem.permission, PermissionLevel.Write) + : false; return ( <> diff --git a/src/components/main/MainMenu.tsx b/src/components/main/MainMenu.tsx index b07691483..3cbd022c6 100644 --- a/src/components/main/MainMenu.tsx +++ b/src/components/main/MainMenu.tsx @@ -1,13 +1,7 @@ import { useLocation, useNavigate } from 'react-router'; // import { BugReport } from '@mui/icons-material'; -import { - AutoStories, - Bookmark, - Delete, - Folder, - FolderShared, -} from '@mui/icons-material'; +import { AutoStories, Bookmark, Delete, Folder } from '@mui/icons-material'; import { ListItem, ListItemButton, @@ -27,7 +21,6 @@ import { HOME_PATH, PUBLISHED_ITEMS_PATH, RECYCLE_BIN_PATH, - SHARED_ITEMS_PATH, } from '../../config/paths'; import { BUILDER } from '../../langs/constants'; import { useCurrentUserContext } from '../context/CurrentUserContext'; @@ -105,12 +98,6 @@ const MainMenu = (): JSX.Element => { icon={} text={translateBuilder(BUILDER.MY_ITEMS_TITLE)} /> - goTo(SHARED_ITEMS_PATH)} - text={translateBuilder(BUILDER.SHARED_ITEMS_TITLE)} - icon={} - selected={pathname === SHARED_ITEMS_PATH} - /> goTo(BOOKMARKED_ITEMS_PATH)} selected={pathname === BOOKMARKED_ITEMS_PATH} diff --git a/src/components/main/itemSelectionModal/ItemSelectionModal.tsx b/src/components/main/itemSelectionModal/ItemSelectionModal.tsx index 2fefe3c7c..5e64609f5 100644 --- a/src/components/main/itemSelectionModal/ItemSelectionModal.tsx +++ b/src/components/main/itemSelectionModal/ItemSelectionModal.tsx @@ -59,7 +59,6 @@ const ItemSelectionModal = ({ }: ItemSelectionModalProps): JSX.Element => { const { t: translateBuilder } = useBuilderTranslation(); const { data: items, isLoading } = hooks.useItems(itemIds); - const title = items ? ( computeTitle({ items, diff --git a/src/components/main/itemSelectionModal/RootNavigationTree.tsx b/src/components/main/itemSelectionModal/RootNavigationTree.tsx index 14a03e485..a7db12bad 100644 --- a/src/components/main/itemSelectionModal/RootNavigationTree.tsx +++ b/src/components/main/itemSelectionModal/RootNavigationTree.tsx @@ -46,8 +46,9 @@ const RootNavigationTree = ({ ); const { data: parents } = hooks.useParents({ - id: items[0].id, - path: items[0].path, + id: items[0]?.id, + path: items[0]?.path, + enabled: Boolean(items[0]), }); if (recentItems?.data?.length) { diff --git a/src/components/pages/RecycledItemsScreen.tsx b/src/components/pages/RecycledItemsScreen.tsx index a4718cd04..e85bd49b8 100644 --- a/src/components/pages/RecycledItemsScreen.tsx +++ b/src/components/pages/RecycledItemsScreen.tsx @@ -74,7 +74,6 @@ const RecycleBinLoadableContent = (): JSX.Element | null => { actions={RowActions} ToolbarActions={ToolbarActions} showThumbnails={false} - enableMemberships={false} totalCount={recycledItems?.length} /> diff --git a/src/components/pages/SharedItemsScreen.tsx b/src/components/pages/SharedItemsScreen.tsx deleted file mode 100644 index f65bdfaee..000000000 --- a/src/components/pages/SharedItemsScreen.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { Helmet } from 'react-helmet'; - -import { Alert, Box } from '@mui/material'; - -import { Loader } from '@graasp/ui'; - -import { BUILDER } from '@/langs/constants'; - -import { useBuilderTranslation } from '../../config/i18n'; -import { hooks } from '../../config/queryClient'; -import { - SHARED_ITEMS_ERROR_ALERT_ID, - SHARED_ITEMS_ID, - SHARED_ITEMS_ROOT_CONTAINER, -} from '../../config/selectors'; -import ErrorAlert from '../common/ErrorAlert'; -import { useFilterItemsContext } from '../context/FilterItemsContext'; -import ItemHeader from '../item/header/ItemHeader'; -import Items from '../main/Items'; - -const SharedItemsLoadableContent = (): JSX.Element | null => { - const { t: translateBuilder } = useBuilderTranslation(); - const { data: sharedItems, isLoading, isError } = hooks.useSharedItems(); - const { shouldDisplayItem } = useFilterItemsContext(); - // TODO: implement filter in the hooks directly ? - const filteredItems = sharedItems?.filter((i) => shouldDisplayItem(i.type)); - - if (filteredItems) { - return ( - <> - - {translateBuilder(BUILDER.SHARED_ITEMS_TITLE)} - - - - {translateBuilder( - "You can also find the items of this page in ''My Graasp''. This page will be unavailable soon.", - )} - - - - - - ); - } - if (isError) { - return ; - } - - if (isLoading) { - return ; - } - - return null; -}; - -const SharedItemsScreen = (): JSX.Element => ; - -export default SharedItemsScreen; diff --git a/src/components/pages/item/ItemScreenLayout.tsx b/src/components/pages/item/ItemScreenLayout.tsx index c4dafc8c4..3da8353cf 100644 --- a/src/components/pages/item/ItemScreenLayout.tsx +++ b/src/components/pages/item/ItemScreenLayout.tsx @@ -4,43 +4,44 @@ import { Outlet, useParams } from 'react-router'; import { PermissionLevel, PermissionLevelCompare } from '@graasp/sdk'; import { Loader } from '@graasp/ui'; -import { useGetPermissionForItem } from '@/hooks/authorization'; - import { hooks } from '../../../config/queryClient'; import ErrorAlert from '../../common/ErrorAlert'; import { useLayoutContext } from '../../context/LayoutContext'; import { UppyContextProvider } from '../../file/UppyContext'; import WrappedAuthItemScreen from './ItemLoginWrapper'; -const { useItem, useItemMemberships } = hooks; +const { useItem } = hooks; const ItemScreenLayout = (): JSX.Element => { const { itemId } = useParams(); const { data: item, isLoading } = useItem(itemId); const { setEditingItemId } = useLayoutContext(); - const { data: memberships, isLoading: isLoadingItemMemberships } = - useItemMemberships(itemId); useEffect(() => { setEditingItemId(null); // eslint-disable-next-line react-hooks/exhaustive-deps }, [itemId]); - const { data: permission } = useGetPermissionForItem(item); - const canWrite = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Write) + const canWrite = item?.permission + ? PermissionLevelCompare.gte(item.permission, PermissionLevel.Write) + : false; + + const canAdmin = item?.permission + ? PermissionLevelCompare.gte(item.permission, PermissionLevel.Admin) : false; - if (item && itemId && memberships) { + if (item && itemId) { return ( - + ); } - if (isLoading || isLoadingItemMemberships) { + if (isLoading) { return ; } return ; diff --git a/src/components/pages/item/type.ts b/src/components/pages/item/type.ts index 371651f6d..8ba1d4935 100644 --- a/src/components/pages/item/type.ts +++ b/src/components/pages/item/type.ts @@ -1,7 +1,8 @@ -import { DiscriminatedItem, PermissionLevel } from '@graasp/sdk'; +import { PackedItem, PermissionLevel } from '@graasp/sdk'; export interface OutletType { - item: DiscriminatedItem; + item: PackedItem; permission?: PermissionLevel; canWrite: boolean; + canAdmin: boolean; } diff --git a/src/components/table/ActionsCellRenderer.tsx b/src/components/table/ActionsCellRenderer.tsx index 36a40a6ba..3350b4112 100644 --- a/src/components/table/ActionsCellRenderer.tsx +++ b/src/components/table/ActionsCellRenderer.tsx @@ -1,26 +1,19 @@ import { - DiscriminatedItem, - ItemMembership, - Member, + PackedItem, PermissionLevel, PermissionLevelCompare, - ResultOf, } from '@graasp/sdk'; -import { useGetPermissionForItem } from '@/hooks/authorization'; - import EditButton from '../common/EditButton'; import DownloadButton from '../main/DownloadButton'; import ItemMenu from '../main/ItemMenu'; type Props = { - manyMemberships?: ResultOf; - member?: Member | null; canMove?: boolean; }; type ChildCompProps = { - data: DiscriminatedItem; + data: PackedItem; }; // items and memberships match by index @@ -28,13 +21,11 @@ const ActionsCellRenderer = ({ canMove, }: Props): ((arg: ChildCompProps) => JSX.Element) => { const ChildComponent = ({ data: item }: ChildCompProps) => { - const { data: permission } = useGetPermissionForItem(item); - - const canWrite = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Write) + const canWrite = item.permission + ? PermissionLevelCompare.gte(item.permission, PermissionLevel.Write) : false; - const canAdmin = permission - ? PermissionLevelCompare.gte(permission, PermissionLevel.Admin) + const canAdmin = item.permission + ? PermissionLevelCompare.gte(item.permission, PermissionLevel.Admin) : false; const renderAnyoneActions = () => ( diff --git a/src/components/table/BadgesCellRenderer.tsx b/src/components/table/BadgesCellRenderer.tsx index 7f16ff593..5a4d9ed67 100644 --- a/src/components/table/BadgesCellRenderer.tsx +++ b/src/components/table/BadgesCellRenderer.tsx @@ -1,10 +1,9 @@ -import { DiscriminatedItem, ItemTag, ResultOf } from '@graasp/sdk'; +import { DiscriminatedItem, PackedItem } from '@graasp/sdk'; import { ItemBadges } from '@graasp/ui'; import { useBuilderTranslation } from '../../config/i18n'; import { hooks } from '../../config/queryClient'; import { BUILDER } from '../../langs/constants'; -import { isItemHidden, isItemPublic } from '../../utils/itemTag'; const { useManyItemPublishedInformations } = hooks; @@ -38,23 +37,20 @@ type ChildCompProps = { export const useItemsStatuses = ({ items = [], - itemsTags, }: { - items?: DiscriminatedItem[]; - itemsTags?: ResultOf; + items?: PackedItem[]; }): ItemsStatuses => { const { data: publishedInformations } = useManyItemPublishedInformations({ itemIds: items.map((i) => i.id), }); return items.reduce((acc, r) => { - const itemTags = itemsTags?.data?.[r.id]; const { showChatbox, isPinned, isCollapsible } = { ...DEFAULT_ITEM_STATUSES, ...r.settings, }; - const isHidden = isItemHidden({ itemTags }); - const isPublic = isItemPublic({ itemTags }); + const isHidden = Boolean(r.hidden); + const isPublic = Boolean(r.public); const isPublished = Boolean(publishedInformations?.data?.[r.id]); return { diff --git a/src/config/paths.ts b/src/config/paths.ts index e0a083d8b..39fd1405f 100644 --- a/src/config/paths.ts +++ b/src/config/paths.ts @@ -1,5 +1,4 @@ export const HOME_PATH = '/'; -export const SHARED_ITEMS_PATH = '/shared'; export const BOOKMARKED_ITEMS_PATH = '/bookmarks'; export const PUBLISHED_ITEMS_PATH = '/published'; export const SIGN_UP_PATH = '/signUp'; diff --git a/src/hooks/authorization.ts b/src/hooks/authorization.ts deleted file mode 100644 index e937ffc4e..000000000 --- a/src/hooks/authorization.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - DiscriminatedItem, - ItemMembership, - PermissionLevel, -} from '@graasp/sdk'; - -import { hooks } from '@/config/queryClient'; -import { getHighestPermissionForMemberFromMemberships } from '@/utils/item'; - -// todo: to be replaced by a query client hook get item that would contain the permission -// eslint-disable-next-line import/prefer-default-export -export const useGetPermissionForItem = ( - item?: DiscriminatedItem, - allMemberships?: ItemMembership[], -): { - data?: PermissionLevel; - memberships?: ItemMembership[]; - isMembershipsLoading: boolean; - isCurrentMemberLoading: boolean; - isLoading: boolean; -} => { - // does not fetch memberships if they are given - const { data: memberships, isLoading: isMembershipsLoading } = - hooks.useItemMemberships(allMemberships ? undefined : item?.id); - const { data: currentMember, isLoading: isCurrentMemberLoading } = - hooks.useCurrentMember(); - const isLoading = isMembershipsLoading || isCurrentMemberLoading; - - return { - data: item - ? getHighestPermissionForMemberFromMemberships({ - memberships: allMemberships ?? memberships, - memberId: currentMember?.id, - itemPath: item?.path, - })?.permission - : undefined, - isLoading, - memberships, - isMembershipsLoading, - isCurrentMemberLoading, - }; -}; diff --git a/src/utils/itemTag.ts b/src/utils/itemTag.ts deleted file mode 100644 index 198c27a74..000000000 --- a/src/utils/itemTag.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ItemTag, ItemTagType } from '@graasp/sdk'; - -export const isItemHidden = ({ itemTags }: { itemTags?: ItemTag[] }): boolean => - Boolean(itemTags?.find(({ type }) => type === ItemTagType.Hidden)); - -export const isItemPublic = ({ itemTags }: { itemTags?: ItemTag[] }): boolean => - Boolean(itemTags?.find(({ type }) => type === ItemTagType.Public)); diff --git a/src/utils/membership.ts b/src/utils/membership.ts index 237092fc1..1e42add3e 100644 --- a/src/utils/membership.ts +++ b/src/utils/membership.ts @@ -1,4 +1,4 @@ -import { ItemMembership, ResultOf } from '@graasp/sdk'; +import { ItemMembership, PermissionLevelCompare } from '@graasp/sdk'; // todo: better check with typescript export const isError = ( @@ -12,10 +12,24 @@ export const membershipsWithoutUser = ( ): ItemMembership[] => memberships?.filter(({ member: { id: memberId } }) => memberId !== userId); -export const getMembershipsForItem = ({ - itemId, - manyMemberships, -}: { - itemId: string; - manyMemberships?: ResultOf; -}): ItemMembership[] | undefined => manyMemberships?.data?.[itemId]; +interface PermissionMap { + [key: string]: ItemMembership; +} + +export const selectHighestMemberships = ( + memberships: ItemMembership[], +): ItemMembership[] => { + const permissionMap = memberships.reduce((acc, curr) => { + const { member, permission } = curr; + + if ( + !acc[member.id] || + PermissionLevelCompare.gt(permission, acc[member.id].permission) + ) { + acc[member.id] = curr; + } + return acc; + }, {}); + + return Object.values(permissionMap); +}; diff --git a/yarn.lock b/yarn.lock index 309991ef5..601b6179b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1494,9 +1494,9 @@ __metadata: languageName: node linkType: hard -"@graasp/query-client@npm:3.7.0": - version: 3.7.0 - resolution: "@graasp/query-client@npm:3.7.0" +"@graasp/query-client@npm:3.8.0": + version: 3.8.0 + resolution: "@graasp/query-client@npm:3.8.0" dependencies: "@tanstack/react-query": "npm:4.36.1" "@tanstack/react-query-devtools": "npm:4.36.1" @@ -1507,7 +1507,7 @@ __metadata: "@graasp/sdk": ^4.0.0 "@graasp/translations": ^1.23.0 react: ^18.0.0 - checksum: 10/649e0f1f1db5355f50ec5af4ce5ed1c77aae5eeb330d56d50309e3a0317b2f96727ef9caea21de13cb88c8621a3c5d2fed787f9de2409005d8bf8ade8e6fab3d + checksum: 10/8657f66530cfe5e28c28c54cb29cf392d41aae9365bf7f1dceb9ed1876211b34d7032a892d33c0317e6a90d48d4a203bd44a3cecb8f2337121f35dcc789fdbef languageName: node linkType: hard @@ -1558,45 +1558,6 @@ __metadata: languageName: node linkType: hard -"@graasp/ui@npm:4.17.0": - version: 4.17.0 - resolution: "@graasp/ui@npm:4.17.0" - dependencies: - "@ag-grid-community/client-side-row-model": "npm:31.2.1" - "@ag-grid-community/react": "npm:^31.1.1" - "@ag-grid-community/styles": "npm:^31.1.1" - "@storybook/react-vite": "npm:7.6.18" - http-status-codes: "npm:2.3.0" - interweave: "npm:13.1.0" - katex: "npm:0.16.10" - lodash.truncate: "npm:4.4.2" - lucide-react: "npm:0.373.0" - react-cookie-consent: "npm:9.0.0" - react-quill: "npm:2.0.0" - react-rnd: "npm:10.4.1" - react-text-mask: "npm:5.5.0" - uuid: "npm:9.0.1" - vitest: "npm:1.5.2" - peerDependencies: - "@emotion/cache": ~11.10.7 || ~11.11.0 - "@emotion/react": ~11.10.6 || ~11.11.0 - "@emotion/styled": ~11.10.6 || ~11.11.0 - "@graasp/sdk": ^4.0.0 - "@graasp/translations": ^1.23.0 - "@mui/icons-material": ~5.14.0 || ~5.15.0 - "@mui/lab": ~5.0.0-alpha.150 - "@mui/material": ~5.14.0 || ~5.15.0 - i18next: ^22.4.15 || ^23.0.0 - react: ^18.0.0 - react-dom: ^18.0.0 - react-i18next: ^13.0.0 || ^14.0.0 - react-router-dom: ^6.11.0 - stylis: ^4.1.3 - stylis-plugin-rtl: ^2.1.1 - checksum: 10/97f94c7ca77010b1363af2ccc1c9c64e8d2e5457fd8d350e8938afe522db2049ff7ec5901e6185a57281555b9c37e313177b66709d77b5508df35a8ba674685b - languageName: node - linkType: hard - "@graasp/ui@npm:4.17.1": version: 4.17.1 resolution: "@graasp/ui@npm:4.17.1" @@ -7370,10 +7331,10 @@ __metadata: "@emotion/styled": "npm:11.11.5" "@graasp/chatbox": "npm:3.1.0" "@graasp/map": "npm:1.11.1" - "@graasp/query-client": "npm:3.7.0" + "@graasp/query-client": "npm:3.8.0" "@graasp/sdk": "npm:4.9.0" "@graasp/translations": "npm:1.28.0" - "@graasp/ui": "npm:4.17.0" + "@graasp/ui": "npm:4.17.1" "@mui/icons-material": "npm:5.15.15" "@mui/lab": "npm:5.0.0-alpha.170" "@mui/material": "npm:5.15.15" @@ -9188,15 +9149,6 @@ __metadata: languageName: node linkType: hard -"lucide-react@npm:0.373.0": - version: 0.373.0 - resolution: "lucide-react@npm:0.373.0" - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 - checksum: 10/e474e456fadee6595a25738507102985bc50a754164d7daba4252e8301cdbacf5499ba206529058ac3dadcf7d57937c565ac8bc0ee2a90d0dcd0204e3a8e5b39 - languageName: node - linkType: hard - "lucide-react@npm:0.376.0": version: 0.376.0 resolution: "lucide-react@npm:0.376.0"