UNPKG

react-notification

Version:
461 lines (379 loc) 12.3 kB
import React from 'react'; import { Notification, NotificationStack } from '../src/index'; import mockNotification from './mockNotification'; describe('<NotificationStack />', () => { let notifications; beforeEach(() => { notifications = [ mockNotification, Object.assign({}, mockNotification, { key: 2222 }) ]; }); it('notification prop isActive set to false after deactivate called in onClick', (done) => { const myNotification = Object.assign( {}, mockNotification, { onClick: (notification, deactivate) => deactivate() } ); const wrapper = mount( <NotificationStack notifications={[myNotification]} onDismiss={() => null} /> ); const notification = wrapper.find(Notification); const action = notification.find('.notification-bar-action'); setTimeout(() => { expect(notification.prop('isActive')).to.equal(true); action.simulate('click'); expect(notification.prop('isActive')).to.equal(false); done(); }, 10); }); it('notifications dismissed independently if `dismissInOrder` set to false', (done) => { const handleDismiss = spy(); const wrapper = mount( <NotificationStack dismissInOrder={false} notifications={notifications} onDismiss={handleDismiss} /> ); wrapper.update(); setTimeout(() => { try { expect(handleDismiss.calledTwice).to.equal(true); done(); } catch (error) { throw error; } // Add time due to each StackedNotification transition time ( > 300 ) }, mockNotification.dismissAfter + 340); }); it('should not dismiss when `dismissAfter` is `false`', (done) => { const handleDismiss = spy(); const wrapper = mount( <NotificationStack notifications={[{ ...mockNotification, dismissAfter: false }]} onDismiss={handleDismiss} /> ); wrapper.update(); setTimeout(() => { try { expect(handleDismiss.called).to.equal(false); done(); } catch (error) { throw error; } // Add time due to each StackedNotification transition time ( > 300 ) }, mockNotification.dismissAfter + 340); }); it('should fire onClick with argument `deactivate`', (done) => { const wrapper = mount( <NotificationStack notifications={[{ ...mockNotification, onClick: (notification, deactivate) => { expect(deactivate).to.be.a('function'); done(); } }]} onDismiss={() => null} /> ); const notification = wrapper.find('.notification-bar-action'); notification.simulate('click'); }); it('should dismiss when `dismissAfter` is updated to a number after it was `false`', (done) => { const handleDismiss = spy(); let dismissAfter = 0; const wrapper = mount( <NotificationStack dismissInOrder={false} notifications={[{ ...mockNotification, dismissAfter: false }]} onDismiss={handleDismiss} /> ); wrapper.update(); const isDismissed = (called, callback) => { setTimeout(() => { try { expect(handleDismiss.called).to.equal(called); callback(); } catch (err) { callback(err); } // Add time due to each StackedNotification transition time ( > 300 ) }, dismissAfter + 440); }; isDismissed(false, (err) => { if (err) return done(err); dismissAfter = 110; wrapper.setProps({ notifications: [{ ...mockNotification, dismissAfter }] }, () => { isDismissed(true, done); }); }); }); it('barStyleFactory should set correct style on notification', () => { const styleFactory = (index, style) => Object.assign( {}, style, { bottom: `${index}px` } ); const stack = mount( <NotificationStack notifications={[mockNotification]} barStyleFactory={styleFactory} onDismiss={() => {}} /> ); const notification = stack.find(Notification); expect(notification.prop('barStyle').bottom).to.equal('0px'); }); it('barStyleFactory should respect notification barStyle', () => { const styleFactory = (index, style) => Object.assign( {}, style, { bottom: `${index}px` } ); const stack = mount( <NotificationStack notifications={[mockNotification]} barStyleFactory={styleFactory} onDismiss={() => {}} /> ); const notification = stack.find(Notification); expect(notification.prop('barStyle').background).to.equal('rgb(2, 2, 2)'); }); it('barStyleFactory should have access to notification', () => { const styleFactory = (index, style, notification) => Object.assign( {}, style, { bottom: `${index}px`, color: notification.key === 1111111 ? 'green' : 'red' } ); const stack = mount( <NotificationStack notifications={[mockNotification]} barStyleFactory={styleFactory} onDismiss={() => {}} /> ); const notification = stack.find(Notification); expect(notification.prop('barStyle').color).to.equal('green'); }); it('activeBarStyleFactory should set correct style on notification', () => { const styleFactory = (index, style) => Object.assign( {}, style, { bottom: `${index + 2}px` } ); const stack = mount( <NotificationStack notifications={[mockNotification]} activeBarStyleFactory={styleFactory} onDismiss={() => {}} /> ); const notification = stack.find(Notification); expect(notification.prop('activeBarStyle').bottom).to.equal('2px'); }); it('activeBarStyleFactory should respect notification actionBarStyle', () => { const styleFactory = (index, style) => Object.assign( {}, style, { bottom: `${index}px` } ); const stack = mount( <NotificationStack notifications={[mockNotification]} activeBarStyleFactory={styleFactory} onDismiss={() => {}} /> ); const notification = stack.find(Notification); expect(notification.prop('activeBarStyle').left).to.equal('4rem'); }); it('activeBarStyleFactory should have access to notification', () => { const styleFactory = (index, style, notification) => Object.assign( {}, style, { bottom: `${index}px`, color: notification.key === 1111111 ? 'green' : 'red' } ); const stack = mount( <NotificationStack notifications={[mockNotification]} activeBarStyleFactory={styleFactory} onDismiss={() => {}} /> ); const notification = stack.find(Notification); expect(notification.prop('activeBarStyle').color).to.equal('green'); }); it('actionStyleFactory should set correct style on notification', () => { const styleFactory = (index, style) => Object.assign( {}, style, { color: 'blue' } ); const stack = mount( <NotificationStack notifications={[mockNotification]} actionStyleFactory={styleFactory} onDismiss={() => {}} /> ); const notification = stack.find(Notification); expect(notification.prop('actionStyle').color).to.equal('blue'); }); it('actionStyleFactory should respect notification actionBarStyle', () => { const styleFactory = (index, style) => Object.assign( {}, style, { color: 'blue' } ); const stack = mount( <NotificationStack notifications={[mockNotification]} actionStyleFactory={styleFactory} onDismiss={() => {}} /> ); const notification = stack.find(Notification); expect(notification.prop('actionStyle').letterSpacing).to.equal('.125ex'); }); it('actionStyleFactory should have access to notification', () => { const styleFactory = (index, style, notification) => Object.assign( {}, style, { color: notification.key === 1111111 ? 'green' : 'red' } ); const stack = mount( <NotificationStack notifications={[mockNotification]} actionStyleFactory={styleFactory} onDismiss={() => {}} /> ); const notification = stack.find(Notification); expect(notification.prop('actionStyle').color).to.equal('green'); }); /** * Test: Global handling of onClick: * * If a child notification in the stack does not have an onClick property, * then fire onClick at the parent (<NotificationStack />) level. * * Because the mockNotification we used for other tests includes an * onClick property, we need use a different mock notification. */ it('onClick fires globally when notification action is clicked', () => { const handleClickGlobal = spy(); // Render a notification stack with one notification child const wrapper = mount( <NotificationStack notifications={[{ key: '0', message: 'Foo', action: 'Dismiss', dismissAfter: 100, title: 'Title' // No onClick property on the notification child // onClick: () => {} }]} // Instead, it is handled globally onClick={handleClickGlobal} onDismiss={() => {}} /> ); // Simulate a click on the notification in the stack const notification = wrapper.find('.notification-bar-action'); notification.simulate('click'); // Expect handleClick to be caled once expect(handleClickGlobal).to.have.property('callCount', 1); }); /** * Test: Local handling of onClick: * * If a child notification in the stack has an onClick property, * then fire onClick on the child. */ it('onClick fires locally when notification action is clicked', () => { const handleClickLocal = spy(); const handleClickGlobal = spy(); // Render a notification stack with one notification child const wrapper = mount( <NotificationStack notifications={[{ key: mockNotification.key, message: mockNotification.message, action: mockNotification.action, dismissAfter: mockNotification.dismissAfter, title: mockNotification.title, onClick: handleClickLocal }]} // Instead, it is handled globally onClick={handleClickGlobal} onDismiss={() => {}} /> ); // Simulate a click on the notification in the stack const notification = wrapper.find('.notification-bar-action'); notification.simulate('click'); // Expect local to be called once and global to be called 0 expect(handleClickLocal).to.have.property('callCount', 1); expect(handleClickGlobal).to.have.property('callCount', 0); }); it('onDismiss fires for notification', (done) => { const handleDismiss = spy(); const wrapper = mount( <NotificationStack notifications={notifications} onDismiss={handleDismiss} /> ); wrapper.update(); setTimeout(() => { try { expect(handleDismiss.callCount).to.equal(notifications.length); done(); } catch (error) { throw error; } // Add transition time + 1000ms per each Notification }, mockNotification.dismissAfter + 1340); }); it('onDismiss does not fire until `dismissAfter` value times out', () => { const handleDismiss = spy(); // eslint-disable-next-line const wrapper = shallow( <NotificationStack notifications={[mockNotification]} onDismiss={handleDismiss} /> ); expect(handleDismiss.calledOnce).to.equal(false); }); it('onDismiss fires after `dismissAfter` value', (done) => { const handleDismiss = spy(); const wrapper = mount( <NotificationStack notifications={notifications} onDismiss={handleDismiss} /> ); wrapper.update(); setTimeout(() => { try { expect(handleDismiss.calledOnce).to.equal(true); done(); } catch (error) { throw error; } // Add time due to each StackedNotification transition time ( > 300 ) }, mockNotification.dismissAfter + 340); }); });