@@ -22,34 +22,41 @@ describe('LiveController parent -> child component tests', () => {
22
22
data-controller="live"
23
23
data-live-url-value="http://localhost/_components/parent"
24
24
>
25
- <span>Title: ${ data . title } </span>
26
- <span>Description in Parent: ${ data . description } </span>
25
+ <span>Title: ${ data . post . title } </span>
26
+ <span>Description in Parent: ${ data . post . content } </span>
27
+
28
+ <input
29
+ type="text"
30
+ name="post[title]"
31
+ value="${ data . post . title } "
32
+ >
33
+
34
+ ${ childTemplate ( { value : data . post . content } ) }
27
35
28
36
<button
29
37
data-action="live#$render"
30
38
>Parent Re-render</button>
31
-
32
- ${ childTemplate ( { description : data . description } ) }
33
39
</div>
34
40
`
35
41
}
36
42
37
43
const childTemplate = ( data ) => `
38
44
<div
39
45
data-controller="live"
40
- data-live-url-value="http://localhost/_components/my_component "
46
+ data-live-url-value="http://localhost/_components/child "
41
47
>
42
48
<!-- form field not mapped with data-model -->
43
49
<label>
44
- Description :
50
+ Content :
45
51
<input
46
- value="${ data . description } "
47
- data-model="description"
52
+ value="${ data . value } "
53
+ data-model="value"
54
+ name="post[content]"
48
55
data-action="live#update"
49
56
>
50
57
</label>
51
58
52
- <div>Description in child: ${ data . description } </div>
59
+ <div>Value in child: ${ data . value } </div>
53
60
54
61
<button
55
62
data-action="live#$render"
@@ -75,60 +82,61 @@ describe('LiveController parent -> child component tests', () => {
75
82
} ) ;
76
83
77
84
it ( 'renders parent component without affecting child component' , async ( ) => {
78
- const data = { title : 'Parent component' , description : 'i love components' } ;
85
+ const data = { post : { title : 'Parent component' , content : 'i love components' } } ;
79
86
const { element } = await startStimulusForParentChild (
80
87
parentTemplate ( data ) ,
81
88
data ,
82
- { description : data . description }
89
+ { value : data . post . content }
83
90
) ;
84
91
85
- // on child re-render, use a new description
86
- fetchMock . get ( 'http://localhost/_components/my_component?description =i+love+components' , {
87
- html : childTemplate ( { description : 'i love popcorn' } ) ,
88
- data : { description : 'i love popcorn' }
92
+ // on child re-render, use a new content
93
+ fetchMock . get ( 'http://localhost/_components/child?value =i+love+components' , {
94
+ html : childTemplate ( { value : 'i love popcorn' } ) ,
95
+ data : { value : 'i love popcorn' }
89
96
} ) ;
90
97
91
98
// reload the child template
92
99
getByText ( element , 'Child Re-render' ) . click ( ) ;
93
- await waitFor ( ( ) => expect ( element ) . toHaveTextContent ( 'Description in child: i love popcorn' ) ) ;
100
+ await waitFor ( ( ) => expect ( element ) . toHaveTextContent ( 'Value in child: i love popcorn' ) ) ;
94
101
95
102
// on parent re-render, render the child template differently
96
- fetchMock . get ( 'http://localhost/_components/parent?title=Parent+component&description=i+love+components ' , {
97
- html : parentTemplate ( { title : 'Changed parent ' , description : 'changed child description' } ) ,
98
- data : { title : 'Changed parent ' , description : 'changed child description' }
103
+ fetchMock . get ( 'begin: http://localhost/_components/parent' , {
104
+ html : parentTemplate ( { post : { title : 'Changed title ' , content : 'changed content' } } ) ,
105
+ data : { post : { title : 'Changed title ' , content : 'changed content' } }
99
106
} ) ;
100
107
getByText ( element , 'Parent Re-render' ) . click ( ) ;
101
- await waitFor ( ( ) => expect ( element ) . toHaveTextContent ( 'Title: Changed parent ' ) ) ;
108
+ await waitFor ( ( ) => expect ( element ) . toHaveTextContent ( 'Title: Changed title ' ) ) ;
102
109
103
110
// the child component should *not* have updated
104
- expect ( element ) . toHaveTextContent ( 'Description in child: i love popcorn' ) ;
111
+ expect ( element ) . toHaveTextContent ( 'Value in child: i love popcorn' ) ;
105
112
} ) ;
106
113
107
114
it ( 'updates child model and parent model in a deferred way' , async ( ) => {
108
- const data = { title : 'Parent component' , description : 'i love' } ;
115
+ const data = { post : { title : 'Parent component' , content : 'i love' } } ;
109
116
const { element, controller } = await startStimulusForParentChild (
110
117
parentTemplate ( data ) ,
111
118
data ,
112
- { description : data . description }
119
+ { value : data . post . content }
113
120
) ;
114
121
115
122
// verify the child request contains the correct description & re-render
116
- fetchMock . get ( 'http://localhost/_components/my_component?description =i+love+turtles' , {
117
- html : childTemplate ( { description : 'i love turtles' } ) ,
118
- data : { description : 'i love turtles' }
123
+ fetchMock . get ( 'http://localhost/_components/child?value =i+love+turtles' , {
124
+ html : childTemplate ( { value : 'i love turtles' } ) ,
125
+ data : { value : 'i love turtles' }
119
126
} ) ;
120
127
121
128
// change the description in the child
122
- const inputElement = getByLabelText ( element , 'Description :' ) ;
129
+ const inputElement = getByLabelText ( element , 'Content :' ) ;
123
130
await userEvent . type ( inputElement , ' turtles' ) ;
124
131
125
132
// wait for the render to complete
126
- await waitFor ( ( ) => expect ( element ) . toHaveTextContent ( 'Description in child: i love turtles' ) ) ;
133
+ await waitFor ( ( ) => expect ( element ) . toHaveTextContent ( 'Value in child: i love turtles' ) ) ;
127
134
128
135
// the parent should not re-render
129
- expect ( element ) . not . toHaveTextContent ( 'Description in parent: i love turtles' ) ;
130
- // but the value DID update
131
- expect ( controller . dataValue . description ) . toEqual ( 'i love turtles' ) ;
136
+ expect ( element ) . not . toHaveTextContent ( 'Content in parent: i love turtles' ) ;
137
+ // but the value DID update on the parent component
138
+ // this is because the name="post[content]" in the child matches the parent model
139
+ expect ( controller . dataValue . post . content ) . toEqual ( 'i love turtles' ) ;
132
140
} ) ;
133
141
134
142
// TODO - what if a child component re-renders and comes down with
0 commit comments