1515 */
1616var audienceEvaluator = require ( './' ) ;
1717var chai = require ( 'chai' ) ;
18+ var conditionTreeEvaluator = require ( '../condition_tree_evaluator' ) ;
19+ var customAttributeConditionEvaluator = require ( '../custom_attribute_condition_evaluator' ) ;
20+ var sinon = require ( 'sinon' ) ;
21+
1822var assert = chai . assert ;
1923
2024var chromeUserAudience = {
@@ -31,16 +35,29 @@ var iphoneUserAudience = {
3135 type : 'custom_attribute' ,
3236 } ] ,
3337} ;
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+ } ;
3451
3552describe ( 'lib/core/audience_evaluator' , function ( ) {
3653 describe ( 'APIs' , function ( ) {
3754 describe ( 'evaluate' , function ( ) {
3855 it ( 'should return true if there are no audiences' , function ( ) {
39- assert . isTrue ( audienceEvaluator . evaluate ( [ ] , { } ) ) ;
56+ assert . isTrue ( audienceEvaluator . evaluate ( [ ] , audiencesById , { } ) ) ;
4057 } ) ;
4158
4259 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 , { } ) ) ;
4461 } ) ;
4562
4663 it ( 'should return true if any of the audience conditions are met' , function ( ) {
@@ -57,9 +74,9 @@ describe('lib/core/audience_evaluator', function() {
5774 'device_model' : 'iphone' ,
5875 } ;
5976
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 ) ) ;
6380 } ) ;
6481
6582 it ( 'should return false if none of the audience conditions are met' , function ( ) {
@@ -76,21 +93,98 @@ describe('lib/core/audience_evaluator', function() {
7693 'device_model' : 'nexus5' ,
7794 } ;
7895
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 ) ) ;
8299 } ) ;
83100
84101 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+ } ) ;
94188 } ) ;
95189 } ) ;
96190 } ) ;
0 commit comments