15
15
*/
16
16
var audienceEvaluator = require ( './' ) ;
17
17
var chai = require ( 'chai' ) ;
18
+ var conditionTreeEvaluator = require ( '../condition_tree_evaluator' ) ;
19
+ var customAttributeConditionEvaluator = require ( '../custom_attribute_condition_evaluator' ) ;
20
+ var sinon = require ( 'sinon' ) ;
21
+
18
22
var assert = chai . assert ;
19
23
20
24
var chromeUserAudience = {
@@ -31,16 +35,29 @@ var iphoneUserAudience = {
31
35
type : 'custom_attribute' ,
32
36
} ] ,
33
37
} ;
38
+ var conditionsPassingWithNoAttrs = [ 'not' , {
39
+ match : 'exists' ,
40
+ name : 'input_value' ,
41
+ type : 'custom_attribute' ,
42
+ } ] ;
43
+ var conditionsPassingWithNoAttrsAudience = {
44
+ conditions : conditionsPassingWithNoAttrs ,
45
+ } ;
46
+ var audiencesById = {
47
+ 0 : chromeUserAudience ,
48
+ 1 : iphoneUserAudience ,
49
+ 2 : conditionsPassingWithNoAttrsAudience ,
50
+ } ;
34
51
35
52
describe ( 'lib/core/audience_evaluator' , function ( ) {
36
53
describe ( 'APIs' , function ( ) {
37
54
describe ( 'evaluate' , function ( ) {
38
55
it ( 'should return true if there are no audiences' , function ( ) {
39
- assert . isTrue ( audienceEvaluator . evaluate ( [ ] , { } ) ) ;
56
+ assert . isTrue ( audienceEvaluator . evaluate ( [ ] , audiencesById , { } ) ) ;
40
57
} ) ;
41
58
42
59
it ( 'should return false if there are audiences but no attributes' , function ( ) {
43
- assert . isFalse ( audienceEvaluator . evaluate ( [ chromeUserAudience ] , { } ) ) ;
60
+ assert . isFalse ( audienceEvaluator . evaluate ( [ '0' ] , audiencesById , { } ) ) ;
44
61
} ) ;
45
62
46
63
it ( 'should return true if any of the audience conditions are met' , function ( ) {
@@ -57,9 +74,9 @@ describe('lib/core/audience_evaluator', function() {
57
74
'device_model' : 'iphone' ,
58
75
} ;
59
76
60
- assert . isTrue ( audienceEvaluator . evaluate ( [ chromeUserAudience , iphoneUserAudience ] , iphoneUsers ) ) ;
61
- assert . isTrue ( audienceEvaluator . evaluate ( [ chromeUserAudience , iphoneUserAudience ] , chromeUsers ) ) ;
62
- assert . isTrue ( audienceEvaluator . evaluate ( [ chromeUserAudience , iphoneUserAudience ] , iphoneChromeUsers ) ) ;
77
+ assert . isTrue ( audienceEvaluator . evaluate ( [ '0' , '1' ] , audiencesById , iphoneUsers ) ) ;
78
+ assert . isTrue ( audienceEvaluator . evaluate ( [ '0' , '1' ] , audiencesById , chromeUsers ) ) ;
79
+ assert . isTrue ( audienceEvaluator . evaluate ( [ '0' , '1' ] , audiencesById , iphoneChromeUsers ) ) ;
63
80
} ) ;
64
81
65
82
it ( 'should return false if none of the audience conditions are met' , function ( ) {
@@ -76,21 +93,98 @@ describe('lib/core/audience_evaluator', function() {
76
93
'device_model' : 'nexus5' ,
77
94
} ;
78
95
79
- assert . isFalse ( audienceEvaluator . evaluate ( [ chromeUserAudience , iphoneUserAudience ] , nexusUsers ) ) ;
80
- assert . isFalse ( audienceEvaluator . evaluate ( [ chromeUserAudience , iphoneUserAudience ] , safariUsers ) ) ;
81
- assert . isFalse ( audienceEvaluator . evaluate ( [ chromeUserAudience , iphoneUserAudience ] , nexusSafariUsers ) ) ;
96
+ assert . isFalse ( audienceEvaluator . evaluate ( [ '0' , '1' ] , audiencesById , nexusUsers ) ) ;
97
+ assert . isFalse ( audienceEvaluator . evaluate ( [ '0' , '1' ] , audiencesById , safariUsers ) ) ;
98
+ assert . isFalse ( audienceEvaluator . evaluate ( [ '0' , '1' ] , audiencesById , nexusSafariUsers ) ) ;
82
99
} ) ;
83
100
84
101
it ( 'should return true if no attributes are passed and the audience conditions evaluate to true in the absence of attributes' , function ( ) {
85
- var conditionsPassingWithNoAttrs = [ 'not' , {
86
- match : 'exists' ,
87
- name : 'input_value' ,
88
- type : 'custom_attribute' ,
89
- } ] ;
90
- var audience = {
91
- conditions : conditionsPassingWithNoAttrs ,
92
- } ;
93
- assert . isTrue ( audienceEvaluator . evaluate ( [ audience ] ) ) ;
102
+ assert . isTrue ( audienceEvaluator . evaluate ( [ '2' ] , audiencesById ) ) ;
103
+ } ) ;
104
+
105
+ describe ( 'complex audience conditions' , function ( ) {
106
+ it ( 'should return true if any of the audiences in an "OR" condition pass' , function ( ) {
107
+ var result = audienceEvaluator . evaluate (
108
+ [ 'or' , '0' , '1' ] ,
109
+ audiencesById ,
110
+ { browser_type : 'chrome' }
111
+ ) ;
112
+ assert . isTrue ( result ) ;
113
+ } ) ;
114
+
115
+ it ( 'should return true if all of the audiences in an "AND" condition pass' , function ( ) {
116
+ var result = audienceEvaluator . evaluate (
117
+ [ 'and' , '0' , '1' ] ,
118
+ audiencesById ,
119
+ { browser_type : 'chrome' , device_model : 'iphone' }
120
+ ) ;
121
+ assert . isTrue ( result ) ;
122
+ } ) ;
123
+
124
+ it ( 'should return true if the audience in a "NOT" condition does not pass' , function ( ) {
125
+ var result = audienceEvaluator . evaluate (
126
+ [ 'not' , '1' ] ,
127
+ audiencesById ,
128
+ { device_model : 'android' }
129
+ ) ;
130
+ assert . isTrue ( result ) ;
131
+ } ) ;
132
+
133
+ } ) ;
134
+
135
+ describe ( 'integration with dependencies' , function ( ) {
136
+ var sandbox = sinon . sandbox . create ( ) ;
137
+
138
+ beforeEach ( function ( ) {
139
+ sandbox . stub ( conditionTreeEvaluator , 'evaluate' ) ;
140
+ sandbox . stub ( customAttributeConditionEvaluator , 'evaluate' ) ;
141
+ } ) ;
142
+
143
+ afterEach ( function ( ) {
144
+ sandbox . restore ( ) ;
145
+ } ) ;
146
+
147
+ it ( 'returns true if conditionTreeEvaluator.evaluate returns true' , function ( ) {
148
+ conditionTreeEvaluator . evaluate . returns ( true ) ;
149
+ var result = audienceEvaluator . evaluate (
150
+ [ 'or' , '0' , '1' ] ,
151
+ audiencesById ,
152
+ { browser_type : 'chrome' }
153
+ ) ;
154
+ assert . isTrue ( result ) ;
155
+ } ) ;
156
+
157
+ it ( 'returns false if conditionTreeEvaluator.evaluate returns false' , function ( ) {
158
+ conditionTreeEvaluator . evaluate . returns ( false ) ;
159
+ var result = audienceEvaluator . evaluate (
160
+ [ 'or' , '0' , '1' ] ,
161
+ audiencesById ,
162
+ { browser_type : 'safari' }
163
+ ) ;
164
+ assert . isFalse ( result ) ;
165
+ } ) ;
166
+
167
+ it ( 'returns false if conditionTreeEvaluator.evaluate returns null' , function ( ) {
168
+ conditionTreeEvaluator . evaluate . returns ( null ) ;
169
+ var result = audienceEvaluator . evaluate (
170
+ [ 'or' , '0' , '1' ] ,
171
+ audiencesById ,
172
+ { state : 'California' }
173
+ ) ;
174
+ assert . isFalse ( result ) ;
175
+ } ) ;
176
+
177
+ it ( 'calls customAttributeConditionEvaluator.evaluate in the leaf evaluator for audience conditions' , function ( ) {
178
+ conditionTreeEvaluator . evaluate . callsFake ( function ( conditions , leafEvaluator ) {
179
+ return leafEvaluator ( conditions [ 1 ] ) ;
180
+ } ) ;
181
+ customAttributeConditionEvaluator . evaluate . returns ( false ) ;
182
+ var userAttributes = { device_model : 'android' } ;
183
+ var result = audienceEvaluator . evaluate ( [ 'or' , '1' ] , audiencesById , userAttributes ) ;
184
+ sinon . assert . calledOnce ( customAttributeConditionEvaluator . evaluate ) ;
185
+ sinon . assert . calledWithExactly ( customAttributeConditionEvaluator . evaluate , iphoneUserAudience . conditions [ 1 ] , userAttributes ) ;
186
+ assert . isFalse ( result ) ;
187
+ } ) ;
94
188
} ) ;
95
189
} ) ;
96
190
} ) ;
0 commit comments