1
+ import {
2
+ render
3
+ } from '@testing-library/preact/pure' ;
4
+
5
+ import { JSFunctionField } from '../../../../../src/render/components/form-fields/JSFunctionField' ;
6
+
7
+ import { MockFormContext } from '../helper' ;
8
+
9
+ import { act } from 'preact/test-utils' ;
10
+
11
+ import {
12
+ createFormContainer
13
+ } from '../../../../TestHelper' ;
14
+
15
+ let container ;
16
+
17
+ describe ( 'JSFunctionField' , function ( ) {
18
+
19
+ beforeEach ( function ( ) {
20
+ container = createFormContainer ( ) ;
21
+ } ) ;
22
+
23
+
24
+ afterEach ( function ( ) {
25
+ container . remove ( ) ;
26
+ } ) ;
27
+
28
+
29
+ it ( 'should evaluate with setValue' , async function ( ) {
30
+
31
+ // given
32
+ const onChangeSpy = sinon . spy ( ) ;
33
+ const field = defaultField ;
34
+ const passedData = { value : 42 } ;
35
+
36
+ const services = {
37
+ expressionLanguage : {
38
+ isExpression : ( ) => true ,
39
+ evaluate : ( ) => {
40
+ return passedData ;
41
+ }
42
+ }
43
+ } ;
44
+
45
+ // when
46
+ act ( ( ) => {
47
+ createJSFunctionField ( { field, onChange : onChangeSpy , services } ) ;
48
+ } ) ;
49
+
50
+ // wait for the iframe to compute the expression and pass it back
51
+ await new Promise ( r => setTimeout ( r , 100 ) ) . then ( ( ) => {
52
+
53
+ // then
54
+ expect ( onChangeSpy ) . to . be . calledOnce ;
55
+ expect ( onChangeSpy ) . to . be . calledWith ( { field, value : 42 } ) ;
56
+ } ) ;
57
+
58
+ } ) ;
59
+
60
+
61
+ it ( 'should evaluate with return' , async function ( ) {
62
+
63
+ // given
64
+ const onChangeSpy = sinon . spy ( ) ;
65
+ const field = {
66
+ ...defaultField ,
67
+ jsFunction : 'return data.value'
68
+ } ;
69
+ const passedData = { value : 42 } ;
70
+
71
+ const services = {
72
+ expressionLanguage : {
73
+ isExpression : ( ) => true ,
74
+ evaluate : ( ) => {
75
+ return passedData ;
76
+ }
77
+ }
78
+ } ;
79
+
80
+ // when
81
+ act ( ( ) => {
82
+ createJSFunctionField ( { field, onChange : onChangeSpy , services } ) ;
83
+ } ) ;
84
+
85
+ // wait for the iframe to compute the expression and pass it back
86
+ await new Promise ( r => setTimeout ( r , 100 ) ) . then ( ( ) => {
87
+
88
+ // then
89
+ expect ( onChangeSpy ) . to . be . calledOnce ;
90
+ expect ( onChangeSpy ) . to . be . calledWith ( { field, value : 42 } ) ;
91
+ } ) ;
92
+
93
+ } ) ;
94
+
95
+
96
+ it ( 'should evaluate multiple times when using interval' , async function ( ) {
97
+
98
+ // given
99
+ const onChangeSpy = sinon . spy ( ) ;
100
+ const field = {
101
+ ...defaultField ,
102
+ computeOn : 'interval' ,
103
+ interval : 100
104
+ } ;
105
+ const passedData = { value : 42 } ;
106
+
107
+ const services = {
108
+ expressionLanguage : {
109
+ isExpression : ( ) => true ,
110
+ evaluate : ( ) => {
111
+ return passedData ;
112
+ }
113
+ }
114
+ } ;
115
+
116
+ // when
117
+ act ( ( ) => {
118
+ createJSFunctionField ( { field, onChange : onChangeSpy , services } ) ;
119
+ } ) ;
120
+
121
+ // wait for the iframe to compute the expression and pass it back
122
+ await new Promise ( r => setTimeout ( r , 500 ) ) . then ( ( ) => {
123
+
124
+ // then
125
+
126
+ // deliberately underestimating the number of calls to account for potential timing issues
127
+ expect ( onChangeSpy . callCount > 3 ) . to . be . true ;
128
+ expect ( onChangeSpy ) . to . be . calledWith ( { field, value : 42 } ) ;
129
+ } ) ;
130
+
131
+
132
+ } ) ;
133
+
134
+ } ) ;
135
+
136
+ // helpers //////////
137
+
138
+ const defaultField = {
139
+ type : 'script' ,
140
+ key : 'jsfunction' ,
141
+ jsFunction : 'setValue(data.value)' ,
142
+ computeOn : 'load'
143
+ } ;
144
+
145
+ function createJSFunctionField ( { services, ...restOptions } = { } ) {
146
+ const options = {
147
+ field : defaultField ,
148
+ onChange : ( ) => { } ,
149
+ ...restOptions
150
+ } ;
151
+
152
+ return render (
153
+ < MockFormContext
154
+ services = { services }
155
+ options = { options } >
156
+ < JSFunctionField
157
+ field = { options . field }
158
+ onChange = { options . onChange } />
159
+ </ MockFormContext > , {
160
+ container : options . container || container . querySelector ( '.fjs-form' )
161
+ }
162
+ ) ;
163
+ }
0 commit comments