Ver código fonte

Add notifications unit tests

Includes unit tests for the new dropdown notifications feature.
Also includes a small fix for Cypress 'Invalid Login' test.
Sergiu Miclea 7 anos atrás
pai
commit
39e1e3176a

+ 1 - 1
package.json

@@ -104,4 +104,4 @@
     "webpack-blocks-happypack": "^0.1.3",
     "webpack-blocks-split-vendor": "^0.2.1"
   }
-}
+}

+ 4 - 0
private/cypress/integration/1 - login/Invalid Login.js

@@ -23,6 +23,10 @@ describe('Coriolis Login Failed', () => {
     cy.logout()
   })
 
+  beforeEach(() => {
+    Cypress.Cookies.preserveOnce('token', 'projectId')
+  })
+
   it('Displays incorrect password', () => {
     cy.server()
     cy.route({ url: '**/identity/**', method: 'POST' }).as('login')

+ 1 - 1
private/cypress/support/commands.js

@@ -95,7 +95,7 @@ Cypress.Commands.add('logout', () => {
   return cy.getCookies().then(cookies => {
     let tokenCookie = cookies.find(c => c.name === 'token')
     if (tokenCookie) {
-      token = tokenCookie
+      token = tokenCookie.value
     }
   }).then(() => {
     if (!token) {

+ 15 - 9
src/components/molecules/NotificationDropdown/NotificationDropdown.jsx

@@ -168,7 +168,7 @@ const Loading = styled.div`
   }
 `
 
-type Props = {
+export type Props = {
   white?: boolean,
   items: NotificationItemData[],
   onClose: () => void,
@@ -176,6 +176,7 @@ type Props = {
 type State = {
   showDropdownList: boolean,
 }
+const testId = 'notificationDropdown'
 @observer
 class NotificationDropdown extends React.Component<Props, State> {
   itemMouseDown: boolean
@@ -232,7 +233,7 @@ class NotificationDropdown extends React.Component<Props, State> {
           onMouseDown={() => { this.itemMouseDown = true }}
           onMouseUp={() => { this.itemMouseDown = false }}
         >
-          <NoItems data-test-id="notificationDropdown-noItems">There are no notifications</NoItems>
+          <NoItems data-test-id={`${testId}-noItems`}>There are no notifications</NoItems>
         </ListItem>
       </List>
     )
@@ -255,16 +256,20 @@ class NotificationDropdown extends React.Component<Props, State> {
               onMouseUp={() => { this.itemMouseDown = false }}
               onClick={() => { this.handleItemClick() }}
               href={`/#/${item.type}${executionsHref}/${item.id}`}
+              data-test-id={`${testId}-${item.id}-item`}
             >
               <InfoColumn>
                 <MainItemInfo>
-                  <StatusIcon status={item.status} hollow />
-                  <ItemReplicaBadge type={item.type}>{item.type === 'replica' ? 'RE' : 'MI'}</ItemReplicaBadge>
-                  <ItemTitle>{item.name}</ItemTitle>
+                  <StatusIcon data-test-id={`${testId}-${item.id}-status`} status={item.status} hollow />
+                  <ItemReplicaBadge
+                    type={item.type}
+                    data-test-id={`${testId}-${item.id}-type`}
+                  >{item.type === 'replica' ? 'RE' : 'MI'}</ItemReplicaBadge>
+                  <ItemTitle data-test-id={`${testId}-${item.id}-name`}>{item.name}</ItemTitle>
                 </MainItemInfo>
-                <ItemDescription>{item.description}</ItemDescription>
+                <ItemDescription data-test-id={`${testId}-${item.id}-description`}>{item.description}</ItemDescription>
               </InfoColumn>
-              {item.unseen ? <BadgeColumn><Badge /></BadgeColumn> : null}
+              {item.unseen ? <BadgeColumn data-test-id={`${testId}-${item.id}-badge`}><Badge /></BadgeColumn> : null}
             </ListItem>
           )
         })}
@@ -278,7 +283,7 @@ class NotificationDropdown extends React.Component<Props, State> {
 
     return (
       <Icon
-        data-test-id="notificationDropdown-button"
+        data-test-id={`${testId}-button`}
         onMouseDown={() => { this.itemMouseDown = true }}
         onMouseUp={() => { this.itemMouseDown = false }}
         onClick={() => this.handleButtonClick()}
@@ -286,8 +291,9 @@ class NotificationDropdown extends React.Component<Props, State> {
         <BellIcon
           dangerouslySetInnerHTML={{ __html: bellImage(this.props.white ? 'white' : Palette.grayscale[2]) }}
         />
-        {this.props.items.find(i => i.unseen) ? <Badge isBellBadge /> : null}
+        {this.props.items.find(i => i.unseen) ? <Badge data-test-id={`${testId}-bell-badge`} isBellBadge /> : null}
         {isLoading ? <Loading
+          data-test-id={`${testId}-bell-loading`}
           dangerouslySetInnerHTML={{ __html: loadingImage(this.props.white) }}
         /> : null}
       </Icon>

+ 43 - 22
src/components/molecules/NotificationDropdown/test.jsx

@@ -17,61 +17,82 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 import React from 'react'
 import { shallow } from 'enzyme'
 import sinon from 'sinon'
-import moment from 'moment'
+
+import type { NotificationItemData } from '../../../types/NotificationItem'
 import TW from '../../../utils/TestWrapper'
 import NotificationDropdown from '.'
+import type { Props } from '.'
 
-const wrap = props => new TW(shallow(
-  // $FlowIgnore
+const wrap = (props: Props) => new TW(shallow(
   <NotificationDropdown {...props} />
 ), 'notificationDropdown')
 
-let items = [
+let items: NotificationItemData[] = [
   {
-    id: new Date().getTime() + 1,
-    message: 'A full VM migration between two clouds',
-    level: 'success',
-    options: { persistInfo: { title: 'Migration' } },
+    id: '1',
+    name: 'notif-1',
+    description: 'desc-1',
+    type: 'replica',
+    status: 'COMPLETED',
+    unseen: false,
   },
   {
-    id: new Date().getTime() + 2,
-    message: 'Incrementally replicate virtual machines',
-    level: 'error',
-    options: { persistInfo: { title: 'Replica' } },
+    id: '2',
+    name: 'notif-2',
+    description: 'desc-2',
+    type: 'migration',
+    status: 'RUNNING',
+    unseen: true,
   },
   {
-    id: new Date().getTime() + 3,
-    message: 'A conection to a public or private cloud',
-    level: 'info',
-    options: { persistInfo: { title: 'Endpoint' } },
+    id: '3',
+    name: 'notif-3',
+    description: 'desc-3',
+    type: 'replica',
+    status: 'ERROR',
+    unseen: false,
   },
 ]
 
 describe('NotificationDropdown Component', () => {
   it('renders no items message on click', () => {
-    let wrapper = wrap({ onClose: () => { } })
+    let wrapper = wrap({ onClose: () => { }, items: [] })
     expect(wrapper.find('noItems').length).toBe(0)
     wrapper.find('button').simulate('click')
     expect(wrapper.find('noItems').length).toBe(1)
+    expect(wrapper.find('bell-badge').length).toBe(0)
+    expect(wrapper.find('bell-loading').length).toBe(0)
   })
 
   it('renders items correctly', () => {
     let wrapper = wrap({ items, onClose: () => { } })
     wrapper.find('button').simulate('click')
+    expect(wrapper.find('bell-badge').length).toBe(1)
+    expect(wrapper.find('bell-loading').length).toBe(1)
 
     items.forEach(item => {
-      expect(wrapper.find(`item-${item.id}`).find('itemLevel').prop('level')).toBe(item.level)
-      expect(wrapper.find(`item-${item.id}`).findText('itemTitle')).toBe(item.options.persistInfo.title)
-      expect(wrapper.find(`item-${item.id}`).findText('itemDescription')).toBe(item.message)
-      expect(wrapper.find(`item-${item.id}`).findText('itemTime')).toBe(moment(Number(item.id)).format('HH:mm'))
+      expect(wrapper.find(`${item.id}-status`).prop('status')).toBe(item.status)
+      expect(wrapper.findText(`${item.id}-type`)).toBe(item.type === 'replica' ? 'RE' : 'MI')
+      expect(wrapper.findText(`${item.id}-name`)).toBe(item.name)
+      expect(wrapper.findText(`${item.id}-description`)).toBe(item.description)
+      expect(wrapper.find(`${item.id}-badge`).length).toBe(item.unseen ? 1 : 0)
     })
   })
 
+  it('renders button bell badge', () => {
+    let wrapper = wrap({ items: items.map(i => { return { ...i, unseen: false } }), onClose: () => { } })
+    expect(wrapper.find('bell-badge').length).toBe(0)
+    expect(wrapper.find('bell-loading').length).toBe(1)
+    wrapper = wrap({ items: items.map(i => { return { ...i, status: 'COMPLETED' } }), onClose: () => { } })
+    expect(wrapper.find('bell-badge').length).toBe(1)
+    expect(wrapper.find('bell-loading').length).toBe(0)
+  })
+
   it('dispatches onClose', () => {
     let onClose = sinon.spy()
     let wrapper = wrap({ items, onClose })
     wrapper.find('button').simulate('click')
-    wrapper.find(`item-${items[0].id}`).simulate('click')
+    wrapper.find(`${items[0].id}-item`).simulate('click')
     expect(onClose.calledOnce).toBe(true)
   })
 })