diff --git a/assets/components/SidebarFolder.jsx b/assets/components/SidebarFolder.jsx index c71a17ccd..9fe045394 100644 --- a/assets/components/SidebarFolder.jsx +++ b/assets/components/SidebarFolder.jsx @@ -6,7 +6,7 @@ export function SidebarFolder({folder, children}) { return ( <div className={`collapsible-box collapsible-box--active-within ${open ? 'collapsible-box--open' : 'collapsible-box--closed'}`}> - <div className="collapsible-box__header" onClick={() => setOpen(!open)} role='button'> + <div className="collapsible-box__header" onClick={() => setOpen(!open)} role='button' data-test-id="toggle-box-button"> <h4 className="collapsible-box__header-title">{folder.name}</h4> <div className="collapsible-box__header-caret"> <i className="icon--arrow-start"></i> @@ -24,4 +24,4 @@ export function SidebarFolder({folder, children}) { SidebarFolder.propTypes = { folder: PropTypes.object, children: PropTypes.node, -}; \ No newline at end of file +}; diff --git a/assets/search/components/SearchBar.tsx b/assets/search/components/SearchBar.tsx index 39b9a1bf2..c8d60ba3c 100644 --- a/assets/search/components/SearchBar.tsx +++ b/assets/search/components/SearchBar.tsx @@ -78,7 +78,7 @@ class SearchBar extends React.Component<any, any> { <path clipRule="evenodd" d="m9 18c4.9706 0 9-4.0294 9-9 0-4.97056-4.0294-9-9-9-4.97056 0-9 4.02944-9 9 0 4.9706 4.02944 9 9 9zm4.9884-12.58679-3.571 3.57514 3.5826 3.58675-1.4126 1.4143-3.58252-3.5868-3.59233 3.5965-1.41255-1.4142 3.59234-3.59655-3.54174-3.54592 1.41254-1.41422 3.54174 3.54593 3.57092-3.57515z" fill="var(--color-text)" fillRule="evenodd" opacity="1"/> </svg> </button> - <button className='search__button-submit' type='submit' aria-label={gettext('Search')}> + <button className='search__button-submit' type='submit' aria-label={gettext('Search')} data-test-id="search-submit-button"> <i className="icon--search"></i> </button> </div> diff --git a/assets/search/components/TopicFolder.tsx b/assets/search/components/TopicFolder.tsx index 50cd00060..757fa1f31 100644 --- a/assets/search/components/TopicFolder.tsx +++ b/assets/search/components/TopicFolder.tsx @@ -72,7 +72,8 @@ export function TopicFolder({ <div key={folder._id} className="simple-card__group" - data-test-id={`folder-card--${folder.name}`} + data-test-id="folder-card" + data-test-value={folder.name} ref={setNodeRef} > {editing ? ( @@ -95,12 +96,15 @@ export function TopicFolder({ <button type="button" className="icon-button icon-button--tertiary" + data-test-id="collapse" title={gettext('Close')} onClick={() => setOpened(false)} ><i className="icon--minus"></i></button> ) : ( <button - type="button" className="icon-button icon-button--tertiary" + type="button" + className="icon-button icon-button--tertiary" + data-test-id="expand" title={gettext('Open')} onClick={() => setOpened(true)} disabled={topics.length === 0} @@ -121,7 +125,9 @@ export function TopicFolder({ }} ref={buttonRef} className="icon-button icon-button--tertiary" - aria-label={gettext('Folder Actions')}> + aria-label={gettext('Folder Actions')} + data-test-id="menu" + > <i className='icon--more'></i> </button> { diff --git a/assets/search/components/TopicFolderActions.tsx b/assets/search/components/TopicFolderActions.tsx index d694f00ee..6f7772dc0 100644 --- a/assets/search/components/TopicFolderActions.tsx +++ b/assets/search/components/TopicFolderActions.tsx @@ -47,6 +47,8 @@ export function TopicFolderActions({folder, toggleFolderPopover, folderPopover, toggle(e); action.callback(); }} + data-test-id="action-folder" + data-test-value={action.name} > <i className={'icon--' + action.icon} /> {action.name} diff --git a/assets/search/components/TopicFolderEditor.jsx b/assets/search/components/TopicFolderEditor.jsx index fe8f26cfc..c99e59cb5 100644 --- a/assets/search/components/TopicFolderEditor.jsx +++ b/assets/search/components/TopicFolderEditor.jsx @@ -35,6 +35,7 @@ export function TopicFolderEditor ({folder, onSave, onCancel, error}) { type="button" className="icon-button icon-button--secondary icon-button--bordered icon-button--small" aria-label={gettext('Cancel')} + data-test-id="create-folder--cancel-btn" title={gettext('Cancel')} onClick={() => onCancel()} > diff --git a/assets/search/components/TopicItem.tsx b/assets/search/components/TopicItem.tsx index 113ea5eb9..f70b6913e 100644 --- a/assets/search/components/TopicItem.tsx +++ b/assets/search/components/TopicItem.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; export function TopicItem({topic, isActive, onClick, newItems}: any) { return ( - <li className="topic-list__item"> + <li className="topic-list__item" data-test-id="topic-list-item" data-test-value={topic.label}> <a className={`topic-list__item-link ${isActive ? 'topic-list__item-link--active' : ''}`} aria-selected={isActive} href="" onClick={(event) => onClick(event, topic)} diff --git a/assets/user-profile/components/UserProfileApp.tsx b/assets/user-profile/components/UserProfileApp.tsx index 853d31714..68b8b3368 100644 --- a/assets/user-profile/components/UserProfileApp.tsx +++ b/assets/user-profile/components/UserProfileApp.tsx @@ -132,7 +132,7 @@ class UserProfileApp extends React.Component<any, any> { <h5 className="profile__profile-content-title"> {links.find((link: any) => link.active).label} </h5> - <button className="profile__profile-content-close" aria-label={gettext('Close')} role="button" onClick={this.hideModal}> + <button className="profile__profile-content-close" aria-label={gettext('Close')} role="button" onClick={this.hideModal} data-test-id="profile-page-close"> <i className="icon--close-thin" /> </button> </section> diff --git a/e2e/cypress/e2e/wire/wire_topic.cy.js b/e2e/cypress/e2e/wire/wire_topic.cy.js new file mode 100644 index 000000000..cb3ff9276 --- /dev/null +++ b/e2e/cypress/e2e/wire/wire_topic.cy.js @@ -0,0 +1,347 @@ +import {setup, addDefaultResources, addResources} from '../../support/e2e'; +import {NewshubLayout} from '../../support/pages/layout'; +import {USERS} from '../../fixtures/users'; +import {UserTopicForm} from '../../support/forms/userTopicForm'; +import {COMPANIES} from '../../fixtures/companies'; +import {profileTopics} from '../../support/pages/profile_topics'; + +const navigateToMyWireTopic = () => { + cy.get('[data-test-id="sidenav-link-wire"]').click(); + cy.get('[data-test-id="toggle-filter-panel"]').click(); + cy.get('[data-test-id="filter-panel-tab--topics"]').click(); + cy.get('[data-test-id="edit-btn"]').click(); +} + +const navigateToCreationNewTopicContent = () => { + cy.get('[data-test-id="sidenav-link-wire"]').click(); + cy.get('[data-test-id="top-search-bar"]').click().type('My Topic'); + cy.get('[data-test-id="search-submit-button"]').click(); + cy.get('[data-test-id="save-topic-btn"]').click(); +} + +describe('Wire - Topic', function () { + beforeEach(() => { + setup(); + addDefaultResources(); + }); + + it('Create a new folder in My Wire Topics', () => { + addResources([ + { + resource: 'topics', + items: [ + { + "_id": "672d3d26f27b4d52d8d5a37b", + "query": "Topic 1", + "topic_type": "wire", + "label": "Topic 1", + "user": USERS.none.admin._id, + }, + ], + }, + ]); + NewshubLayout.login('admin@example.com', 'admin'); + navigateToMyWireTopic(); + + profileTopics.createNewFolder('New Folder'); + + // check if new folder appears in the list of My Wire Topics + profileTopics.getFolderCard('New Folder').should('exist'); + + /** + check if new folder appears in topic detail when editing My Wire Topic + */ + profileTopics.getTopicCardAction("Topic 1", "Edit").click(); + UserTopicForm + .getFormGroup('folder', '[data-test-id="dropdown-btn"]') + .contains('[data-test-id="dropdown-item--New Folder"]', 'New Folder'); + cy.get('[data-test-id="profile-page-close"]').click(); + + /** + create new topic to check if folder exist in select folder dropdown + */ + cy.get('[data-test-id="sidenav-link-wire"]').click(); + cy.get('[data-test-id="top-search-bar"]').click().type('New Topic'); + cy.get('[data-test-id="search-submit-button"]').click(); + cy.get('[data-test-id="save-topic-btn"]').click(); + UserTopicForm + .getFormGroup('folder', '[data-test-id="dropdown-btn"]') + .contains('[data-test-id="dropdown-item--New Folder"]', 'New Folder'); + }); + + it('Rename folder in My Wire Topics', () => { + addResources([ + { + resource: 'topic_folders', + items: [ + { + "_id": "652d2535b7e10e09ec704d6d", + "name": "Folder 1", + "section": "wire", + "user": USERS.none.admin._id + }, + ], + }, + ]); + NewshubLayout.login('admin@example.com', 'admin'); + navigateToMyWireTopic(); + + /** + cancel rename + */ + profileTopics.getFolderAction("Folder 1", "Rename").click(); + cy.get('[data-test-id="folder-name--input"]').clear().type('Renamed Folder'); + cy.get('[data-test-id="create-folder--cancel-btn"]').click(); + // check if folder exist + profileTopics.getFolderCard('Renamed Folder').should('not.exist'); + + /** + save rename + */ + profileTopics.getFolderAction("Folder 1", "Rename").click(); + cy.get('[data-test-id="folder-name--input"]').clear().type('Renamed Folder'); + cy.get('[data-test-id="create-folder--submit-btn"]').click(); + // check if folder exist + profileTopics.getFolderCard('Renamed Folder').should('exist'); + }); + + it('Delete a folder with content in My Wire Topic', () => { + addResources([ + { + resource: 'topic_folders', + items: [ + { + "_id": "652d2535b7e10e09ec704d6d", + "name": "Folder 1", + "section": "wire", + "user": USERS.none.admin._id + }, + ], + }, + { + resource: 'topics', + items: [ + { + "_id": "672d3d26f27b4d56d8d5a27s", + "query": "Topic 1", + "topic_type": "wire", + "label": "Topic 1", + "user": USERS.none.admin._id, + "folder": "652d2535b7e10e09ec704d6d", + }, + ], + }, + ]); + NewshubLayout.login('admin@example.com', 'admin'); + navigateToMyWireTopic(); + + // delete folder with content + profileTopics.getFolderAction("Folder 1", "Delete").click(); + + /** + check that folder and content exist on DOM + */ + profileTopics.getFolderCard('Folder 1').should('not.exist'); + profileTopics.getTopicCard('Topic 1').should('not.exist'); + + /** + refresh the page and check again + */ + cy.reload(); + cy.get('[data-test-id="edit-btn"]').click(); + profileTopics.getFolderCard('Folder 1').should('not.exist'); + profileTopics.getTopicCard('Topic 1').should('not.exist'); + cy.get('[data-test-id="profile-page-close"]').click(); + + /** + create new topic to check if folder exist in select folder dropdown + */ + cy.get('[data-test-id="sidenav-link-wire"]').click(); + cy.get('[data-test-id="top-search-bar"]').click().type('My New Topic'); + cy.get('[data-test-id="search-submit-button"]').click(); + cy.get('[data-test-id="save-topic-btn"]').click(); + UserTopicForm + .getFormGroup('folder', '[data-test-id="dropdown-btn"]') + .contains('[data-test-id="dropdown-item--Folder 1"]', 'Folder 1').should('not.exist'); + }); + + describe('Create a new My Topic and save to folder', function () { + beforeEach(() => { + addResources([ + { + resource: 'topic_folders', + items: [ + { + "_id": "652d2535b7e10e09ec704d6d", + "name": "user folder", + "section": "wire", + "user": USERS.foobar.admin._id, + }, + { + "_id": "672d3d26f27b4d52d8d5a87s", + "section": "wire", + "name": "company folder", + "company": COMPANIES.foobar._id, + }, + ], + }, + ]); + NewshubLayout.login('foo@bar.com', 'admin'); + navigateToCreationNewTopicContent(); + }); + + it('Share with my company checkbox respect dropdown of folders', () => { + /** + check Share with my company checkbox + */ + cy.get('[data-test-id="field-is_global"] input').check(); + UserTopicForm + .getFormGroup('folder', '[data-test-id="dropdown-btn"]').click() + cy.get('[data-test-id="dropdown-item--user folder"]').should("not.exist"); + cy.get('[data-test-id="dropdown-item--company folder"]').should("exist"); + + /** + uncheck Share with my company checkbox + */ + cy.get('[data-test-id="field-is_global"] input').uncheck(); + UserTopicForm + .getFormGroup('folder', '[data-test-id="dropdown-btn"]').click() + cy.get('[data-test-id="dropdown-item--user folder"]').should("exist"); + cy.get('[data-test-id="dropdown-item--company folder"]').should("not.exist"); + }); + + it('Create a new My Topic and save to folder', () => { + /** + save to folder + */ + UserTopicForm + .getFormGroup('folder', '[data-test-id="dropdown-btn"]').click() + cy.get('[data-test-id="dropdown-item--user folder"]').should("exist"); + cy.get('[data-test-id="dropdown-item--company folder"]').should("not.exist"); + cy.get('[data-test-id="dropdown-item--user folder"]').click(); + cy.get('[data-test-id="user-topic-editor"] [data-test-id="save-topic-btn"]').click(); + + /** + check if topic exist in the Wire in appropriate folder on the left My Topics panel + */ + cy.get('[data-test-id="toggle-filter-panel"]').click(); + cy.get('[data-test-id="filter-panel-tab--topics"]').click(); + cy.get('[data-test-id="toggle-box-button"]').click(); + cy.get('[data-test-id="topic-list-item"][data-test-value="My Topic"]').should('exist'); + + /** + check if folder exist in appropriate folder in My Wire Topics + */ + cy.get('[data-test-id="edit-btn"]').click(); + profileTopics.getFolderCard("user folder").find('[data-test-id="expand"]').click(); + profileTopics.getTopicCard('My Topic').should('exist'); + }); + }); + + it('Move My Topic to another folder', () => { + addResources([ + { + resource: 'topic_folders', + items: [ + { + "_id": "652d2535b7e10e09ec704d6d", + "name": "Folder 1", + "section": "wire", + "user": USERS.none.admin._id + }, + { + "_id": "652d2535b7e10e09ec704d65", + "name": "Folder 2", + "section": "wire", + "user": USERS.none.admin._id + }, + ], + }, + { + resource: 'topics', + items: [ + { + "_id": "672d3d26f27b4d52d8d5a37b", + "query": "Topic 1", + "topic_type": "wire", + "label": "Topic 1", + "user": USERS.none.admin._id, + "folder": "652d2535b7e10e09ec704d6d" + }, + ], + }, + ]); + NewshubLayout.login('admin@admin.com', 'admin'); + navigateToMyWireTopic(); + + profileTopics.getFolderCard("Folder 1").find('[data-test-id="expand"]').click(); + + // move topic to another folder with drag & drop + profileTopics.dragTopicToFolder("Topic 1", "Folder 2"); + + /** + check if topic exist in the Wire in appropriate folder on the left My Topics panel + */ + cy.get('[data-test-id="profile-page-close"]').click(); + cy.get('[data-test-id="toggle-box-button"]').click(); + cy.get('[data-test-id="topic-list-item"][data-test-value="Topic 1"]').should('exist'); + + /** + check if folder exist in appropriate folder in My Wire Topics + */ + cy.get('[data-test-id="edit-btn"]').click(); + profileTopics.getFolderCard("Folder 2").find('[data-test-id="expand"]').click(); + profileTopics.getTopicCard('Topic 1').should('exist'); + }); + + it('Remove My Topic from folder ', () => { + addResources([ + { + resource: 'topic_folders', + items: [ + { + "_id": "652d2535b7e10e09ec704d6d", + "name": "Folder 1", + "section": "wire", + "user": USERS.none.admin._id + }, + ], + }, + { + resource: 'topics', + items: [ + { + "_id": "672d3d26f27b4d52d8d5a37b", + "query": "Topic 1", + "topic_type": "wire", + "label": "Topic 1", + "user": USERS.none.admin._id, + "folder": "652d2535b7e10e09ec704d6d" + }, + ], + }, + ]); + NewshubLayout.login('admin@admin.com', 'admin'); + navigateToMyWireTopic(); + + /** + remove topic from folder + */ + profileTopics.getFolderCard("Folder 1").find('[data-test-id="expand"]').click(); + cy.get('[data-test-id="topic-action--Remove from folder"]').click(); + + // check that the topic appeared in root of My Wire Topics - is not in any folder + cy.get('[data-test-id="topic-card--Topic 1"]').then(($el) => { + const el = $el[0]; + expect(el.closest('[data-test-id="folder-card"]')).to.be.null; + }); + + cy.get('[data-test-id="profile-page-close"]').click(); + + // check that the topic appeared in the Wire in root on the left My Topics panel - is not in any folder + cy.get('[data-test-id="topic-list-item"][data-test-value="Topic 1"]').then(($el) => { + const el = $el[0]; + expect(el.closest('[data-test-id="folder-card"]')).to.be.null; + }); + }); +}); diff --git a/e2e/cypress/support/pages/profile_topics.js b/e2e/cypress/support/pages/profile_topics.js index 08b7f8ba0..e0e32a80c 100644 --- a/e2e/cypress/support/pages/profile_topics.js +++ b/e2e/cypress/support/pages/profile_topics.js @@ -22,7 +22,7 @@ class ProfileTopicsWrapper { createNewFolder(name) { this.getCreateFolderButton().click(); this.getFolderNameInput().type(name + '{enter}'); - cy.get(`[data-test-id="folder-card--${name}"]`).should('be.visible'); + cy.get(`[data-test-id="folder-card"][data-test-value="${name}"]`).should('be.visible'); } getTopicCard(name, additionalSelector) { @@ -40,7 +40,12 @@ class ProfileTopicsWrapper { } getFolderCard(name) { - return this.getBaseComponent(`[data-test-id="folder-card--${name}"]`); + return this.getBaseComponent(`[data-test-id="folder-card"][data-test-value="${name}"]`); + } + + getFolderAction(name, actionName) { + cy.get(`[data-test-id="folder-card"][data-test-value="${name}"] [data-test-id="menu"]`).click(); + return cy.get(`[data-test-id="action-folder"][data-test-value="${actionName}"]`); } dragTopicToFolder(topicName, folderName) {