@samitouri / QOS-React-2 / commits / 6c785ed524

Add unit tests for event bubbling in portals (#8509)

These bubble through the portal and up to the parent that rendered the portal.

Sebastian Markbåge committed Dec 8, 2016 at 13:51 UTC 6c785ed5246997c6d2b6bc1a84177e94f413cb27
2 files changed +110
scripts/fiber/tests-passing.txt
+2
@@ -524,6 +524,8 @@ src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
524 * should update portal context if it changes due to setState
525 * should update portal context if it changes due to re-render
526 * findDOMNode should find dom element after expanding a fragment
527 +* should bubble events from the portal to the parent
528 +* should not onMouseLeave when staying in the portal
529
530 src/renderers/dom/shared/__tests__/CSSProperty-test.js
531 * should generate browser prefixes for its `isUnitlessNumber`
src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
+108
@@ -14,6 +14,7 @@
14 var React = require('React');
15 var ReactDOM = require('ReactDOM');
16 var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
17 +var ReactTestUtils = require('ReactTestUtils');
18
19 describe('ReactDOMFiber', () => {
20 var container;
@@ -773,5 +774,112 @@ describe('ReactDOMFiber', () => {
774 var b = ReactDOM.findDOMNode(myNodeB);
775 expect(b.tagName).toBe('SPAN');
776 });
777 +
778 + it('should bubble events from the portal to the parent', () => {
779 + var portalContainer = document.createElement('div');
780 +
781 + var ops = [];
782 + var portal = null;
783 +
784 + ReactDOM.render(
785 + <div onClick={() => ops.push('parent clicked')}>
786 + {ReactDOM.unstable_createPortal(
787 + <div onClick={() => ops.push('portal clicked')} ref={n => portal = n}>
788 + portal
789 + </div>,
790 + portalContainer
791 + )}
792 + </div>,
793 + container
794 + );
795 +
796 + expect(portal.tagName).toBe('DIV');
797 +
798 + var fakeNativeEvent = {};
799 + ReactTestUtils.simulateNativeEventOnNode(
800 + 'topClick',
801 + portal,
802 + fakeNativeEvent
803 + );
804 +
805 + expect(ops).toEqual([
806 + 'portal clicked',
807 + 'parent clicked',
808 + ]);
809 + });
810 +
811 + it('should not onMouseLeave when staying in the portal', () => {
812 + var portalContainer = document.createElement('div');
813 +
814 + var ops = [];
815 + var firstTarget = null;
816 + var secondTarget = null;
817 + var thirdTarget = null;
818 +
819 + function simulateMouseMove(from, to) {
820 + if (from) {
821 + ReactTestUtils.simulateNativeEventOnNode(
822 + 'topMouseOut',
823 + from,
824 + {
825 + target: from,
826 + relatedTarget: to,
827 + }
828 + );
829 + }
830 + if (to) {
831 + ReactTestUtils.simulateNativeEventOnNode(
832 + 'topMouseOver',
833 + to,
834 + {
835 + target: to,
836 + relatedTarget: from,
837 + }
838 + );
839 + }
840 + }
841 +
842 + ReactDOM.render(
843 + <div>
844 + <div
845 + onMouseEnter={() => ops.push('enter parent')}
846 + onMouseLeave={() => ops.push('leave parent')}>
847 + <div ref={n => firstTarget = n} />
848 + {ReactDOM.unstable_createPortal(
849 + <div
850 + onMouseEnter={() => ops.push('enter portal')}
851 + onMouseLeave={() => ops.push('leave portal')}
852 + ref={n => secondTarget = n}>
853 + portal
854 + </div>,
855 + portalContainer
856 + )}
857 + </div>
858 + <div ref={n => thirdTarget = n} />
859 + </div>,
860 + container
861 + );
862 +
863 + simulateMouseMove(null, firstTarget);
864 + expect(ops).toEqual([
865 + 'enter parent',
866 + ]);
867 +
868 + ops = [];
869 +
870 + simulateMouseMove(firstTarget, secondTarget);
871 + expect(ops).toEqual([
872 + // Parent did not invoke leave because we're still inside the portal.
873 + 'enter portal',
874 + ]);
875 +
876 + ops = [];
877 +
878 + simulateMouseMove(secondTarget, thirdTarget);
879 + expect(ops).toEqual([
880 + 'leave portal',
881 + 'leave parent', // Only when we leave the portal does onMouseLeave fire.
882 + ]);
883 + });
884 }
885 });