1
1
import * as React from 'react' ;
2
2
import { act } from 'react-dom/test-utils' ;
3
3
import { makeTestRouter , muteConsoleErrors } from '../../__tests__/util' ;
4
+ import { UIView } from '../../components' ;
5
+ import { ReactStateDeclaration } from '../../interface' ;
4
6
import { useSref } from '../useSref' ;
5
7
import { UISrefActive , UISrefActiveContext } from '../../components/UISrefActive' ;
6
8
7
9
const state = { name : 'state' , url : '/state' } ;
8
10
const state2 = { name : 'state2' , url : '/state2' } ;
9
11
const state3 = { name : 'state3' , url : '/state3/:param' } ;
10
12
13
+ const Link = ( { to, params = undefined , children = undefined } ) => {
14
+ const sref = useSref ( to , params ) ;
15
+ return < a { ...sref } > { children } </ a > ;
16
+ } ;
17
+
11
18
describe ( 'useUiSref' , ( ) => {
12
19
let { router, routerGo, mountInRouter } = makeTestRouter ( [ ] ) ;
13
20
beforeEach ( ( ) => ( { router, routerGo, mountInRouter } = makeTestRouter ( [ state , state2 , state3 ] ) ) ) ;
14
21
15
22
it ( 'throws if to is not a string' , ( ) => {
16
- const Component = ( ) => {
17
- const sref = useSref ( 5 as any , { } ) ;
18
- return < a { ...sref } /> ;
19
- } ;
20
-
21
23
muteConsoleErrors ( ) ;
22
- expect ( ( ) => mountInRouter ( < Component /> ) ) . toThrow ( / m u s t b e a s t r i n g / ) ;
24
+ expect ( ( ) => mountInRouter ( < Link to = { 5 } /> ) ) . toThrow ( / m u s t b e a s t r i n g / ) ;
23
25
} ) ;
24
26
25
27
it ( 'returns an href for the target state' , ( ) => {
26
- const Component = ( ) => {
27
- const uiSref = useSref ( 'state2' , { } ) ;
28
- return < a { ...uiSref } > state2</ a > ;
29
- } ;
30
- const wrapper = mountInRouter ( < Component /> ) ;
28
+ const wrapper = mountInRouter ( < Link to = "state2" > state2</ Link > ) ;
31
29
expect ( wrapper . html ( ) ) . toBe ( '<a href="/state2">state2</a>' ) ;
32
30
} ) ;
33
31
34
32
it ( 'returns an onClick function which activates the target state' , ( ) => {
35
33
const spy = jest . spyOn ( router . stateService , 'go' ) ;
36
- const Component = ( ) => {
37
- const uiSref = useSref ( 'state' ) ;
38
- return < a { ...uiSref } > state</ a > ;
39
- } ;
40
-
41
- const wrapper = mountInRouter ( < Component /> ) ;
34
+ const wrapper = mountInRouter ( < Link to = "state" /> ) ;
42
35
wrapper . simulate ( 'click' ) ;
43
36
44
37
expect ( spy ) . toBeCalledTimes ( 1 ) ;
@@ -47,50 +40,30 @@ describe('useUiSref', () => {
47
40
48
41
it ( 'returns an onClick function which respects defaultPrevented' , ( ) => {
49
42
const spy = jest . spyOn ( router . stateService , 'go' ) ;
50
- const Component = ( ) => {
51
- const uiSref = useSref ( 'state' ) ;
52
- return < a { ...uiSref } > state</ a > ;
53
- } ;
54
-
55
- const wrapper = mountInRouter ( < Component /> ) ;
43
+ const wrapper = mountInRouter ( < Link to = "state" /> ) ;
56
44
wrapper . simulate ( 'click' , { defaultPrevented : true } ) ;
57
45
58
46
expect ( spy ) . not . toHaveBeenCalled ( ) ;
59
47
} ) ;
60
48
61
49
it ( 'updates the href when the stateName changes' , ( ) => {
62
- const Component = props => {
63
- const uiSref = useSref ( props . state ) ;
64
- return < a { ...uiSref } /> ;
65
- } ;
66
-
67
- const wrapper = mountInRouter ( < Component state = "state" /> ) ;
50
+ const wrapper = mountInRouter ( < Link to = "state" /> ) ;
68
51
expect ( wrapper . html ( ) ) . toBe ( '<a href="/state"></a>' ) ;
69
52
70
- wrapper . setProps ( { state : 'state2' } ) ;
53
+ wrapper . setProps ( { to : 'state2' } ) ;
71
54
expect ( wrapper . html ( ) ) . toBe ( '<a href="/state2"></a>' ) ;
72
55
} ) ;
73
56
74
57
it ( 'updates the href when the params changes' , ( ) => {
75
- const State3Link = props => {
76
- const sref = useSref ( 'state3' , { param : props . param } ) ;
77
- return < a { ...sref } /> ;
78
- } ;
79
-
80
- const wrapper = mountInRouter ( < State3Link param = "123" /> ) ;
58
+ const wrapper = mountInRouter ( < Link to = "state3" params = { { param : '123' } } /> ) ;
81
59
expect ( wrapper . html ( ) ) . toBe ( '<a href="/state3/123"></a>' ) ;
82
60
83
- wrapper . setProps ( { param : '456' } ) ;
61
+ wrapper . setProps ( { params : { param : '456' } } ) ;
84
62
expect ( wrapper . html ( ) ) . toBe ( '<a href="/state3/456"></a>' ) ;
85
63
} ) ;
86
64
87
65
it ( 'updates href when the registered state is swapped out' , async ( ) => {
88
- const State2Link = ( ) => {
89
- const sref = useSref ( 'state2' ) ;
90
- return < a { ...sref } /> ;
91
- } ;
92
-
93
- const wrapper = mountInRouter ( < State2Link /> ) ;
66
+ const wrapper = mountInRouter ( < Link to = "state2" /> ) ;
94
67
expect ( wrapper . html ( ) ) . toBe ( '<a href="/state2"></a>' ) ;
95
68
act ( ( ) => {
96
69
router . stateRegistry . deregister ( 'state2' ) ;
@@ -113,16 +86,27 @@ describe('useUiSref', () => {
113
86
} ) ;
114
87
router . stateRegistry . register ( { name : 'future.**' , url : '/future' , lazyLoad : lazyLoadFutureStates } ) ;
115
88
89
+ const wrapper = mountInRouter ( < Link to = "future.child" /> ) ;
90
+ expect ( wrapper . html ( ) ) . toBe ( '<a href="/future"></a>' ) ;
91
+
92
+ await routerGo ( 'future.child' ) ;
93
+ expect ( wrapper . update ( ) . html ( ) ) . toBe ( '<a href="/future/child"></a>' ) ;
94
+ } ) ;
95
+
96
+ it ( 'calls go() with the actual string provided (not with the name of the matched future state)' , async ( ) => {
97
+ router . stateRegistry . register ( { name : 'future.**' , url : '/future' } ) ;
98
+
116
99
const Link = props => {
117
100
const sref = useSref ( 'future.child' , { param : props . param } ) ;
118
101
return < a { ...sref } /> ;
119
102
} ;
120
103
104
+ spyOn ( router . stateService , 'go' ) ;
121
105
const wrapper = mountInRouter ( < Link /> ) ;
122
- expect ( wrapper . html ( ) ) . toBe ( '<a href="/future"></a>' ) ;
123
106
124
- await routerGo ( 'future.child' ) ;
125
- expect ( wrapper . update ( ) . html ( ) ) . toBe ( '<a href="/future/child"></a>' ) ;
107
+ wrapper . find ( 'a' ) . simulate ( 'click' ) ;
108
+ expect ( router . stateService . go ) . toHaveBeenCalledTimes ( 1 ) ;
109
+ expect ( router . stateService . go ) . toHaveBeenCalledWith ( 'future.child' , expect . anything ( ) , expect . anything ( ) ) ;
126
110
} ) ;
127
111
128
112
it ( 'participates in parent UISrefActive component active state' , async ( ) => {
@@ -131,7 +115,7 @@ describe('useUiSref', () => {
131
115
const State2Link = props => {
132
116
const sref = useSref ( 'state2' ) ;
133
117
return (
134
- < a { ...sref } className = { props . className } >
118
+ < a { ...sref } { ... props } >
135
119
state2
136
120
</ a >
137
121
) ;
@@ -145,6 +129,24 @@ describe('useUiSref', () => {
145
129
expect ( wrapper . html ( ) ) . toBe ( '<a href="/state2" class="active">state2</a>' ) ;
146
130
} ) ;
147
131
132
+ it ( 'provides a fully qualified state name to the parent UISrefActive' , async ( ) => {
133
+ const spy = jest . fn ( ) ;
134
+ const State2Link = ( ) => {
135
+ return (
136
+ < UISrefActiveContext . Provider value = { spy } >
137
+ < Link to = { '.child' } />
138
+ </ UISrefActiveContext . Provider >
139
+ ) ;
140
+ } ;
141
+
142
+ router . stateRegistry . register ( { name : 'parent' , component : State2Link } as ReactStateDeclaration ) ;
143
+ router . stateRegistry . register ( { name : 'parent.child' , component : UIView } as ReactStateDeclaration ) ;
144
+
145
+ await routerGo ( 'parent' ) ;
146
+ mountInRouter ( < UIView /> ) ;
147
+ expect ( spy ) . toHaveBeenCalledWith ( 'parent.child' , expect . anything ( ) ) ;
148
+ } ) ;
149
+
148
150
it ( 'participates in grandparent UISrefActive component active state' , async ( ) => {
149
151
await routerGo ( 'state2' ) ;
150
152
0 commit comments