1 package growthbook
2
3 import (
4 "reflect"
5 "testing"
6 )
7
8 const issue1FeaturesJson = `{
9 "banner_text": {
10 "defaultValue": "Welcome to Acme Donuts!",
11 "rules": [
12 {
13 "condition": { "country": "france" },
14 "force": "Bienvenue au Beignets Acme !"
15 },
16 {
17 "condition": { "country": "spain" },
18 "force": "¡Bienvenidos y bienvenidas a Donas Acme!"
19 }
20 ]
21 },
22 "dark_mode": {
23 "defaultValue": false,
24 "rules": [
25 {
26 "condition": { "loggedIn": true },
27 "force": true,
28 "coverage": 0.5,
29 "hashAttribute": "id"
30 }
31 ]
32 },
33 "donut_price": {
34 "defaultValue": 2.5,
35 "rules": [{ "condition": { "employee": true }, "force": 0 }]
36 },
37 "meal_overrides_gluten_free": {
38 "defaultValue": {
39 "meal_type": "standard",
40 "dessert": "Strawberry Cheesecake"
41 },
42 "rules": [
43 {
44 "condition": {
45 "dietaryRestrictions": { "$elemMatch": { "$eq": "gluten_free" } }
46 },
47 "force": { "meal_type": "gf", "dessert": "French Vanilla Ice Cream" }
48 }
49 ]
50 }
51 }`
52
53 const issue1AttributesJson = `{"employee":false,"loggedIn":true,"dietaryRestrictions":["gluten_free"]}`
54
55 const issue1ContextJson = `{
56 "attributes": {"employee":false,"loggedIn":true,"dietaryRestrictions":["gluten_free"]},
57 "features": {
58 "banner_text": {
59 "defaultValue": "Welcome to Acme Donuts!",
60 "rules": [
61 {
62 "condition": { "country": "france" },
63 "force": "Bienvenue au Beignets Acme !"
64 },
65 {
66 "condition": { "country": "spain" },
67 "force": "¡Bienvenidos y bienvenidas a Donas Acme!"
68 }
69 ]
70 },
71 "dark_mode": {
72 "defaultValue": false,
73 "rules": [
74 {
75 "condition": { "loggedIn": true },
76 "force": true,
77 "coverage": 0.5,
78 "hashAttribute": "id"
79 }
80 ]
81 },
82 "donut_price": {
83 "defaultValue": 2.5,
84 "rules": [{ "condition": { "employee": true }, "force": 0 }]
85 },
86 "meal_overrides_gluten_free": {
87 "defaultValue": {
88 "meal_type": "standard",
89 "dessert": "Strawberry Cheesecake"
90 },
91 "rules": [
92 {
93 "condition": {
94 "dietaryRestrictions": { "$elemMatch": { "$eq": "gluten_free" } }
95 },
96 "force": { "meal_type": "gf", "dessert": "French Vanilla Ice Cream" }
97 }
98 ]
99 }
100 }
101 }`
102
103 const issue1ExpectedJson = `{ "meal_type": "gf", "dessert": "French Vanilla Ice Cream" }`
104
105 func TestIssue1(t *testing.T) {
106
107 attrs := Attributes{
108 "id": "user-employee-123456789",
109 "loggedIn": true,
110 "employee": true,
111 "country": "france",
112 "dietaryRestrictions": []string{"gluten_free"},
113 }
114
115 features := ParseFeatureMap([]byte(issue1FeaturesJson))
116
117 context := NewContext().
118 WithFeatures(features).
119 WithAttributes(attrs)
120
121 gb := New(context)
122
123 value := gb.Feature("meal_overrides_gluten_free").Value
124
125 expectedValue := map[string]interface{}{
126 "meal_type": "gf",
127 "dessert": "French Vanilla Ice Cream",
128 }
129
130 if !reflect.DeepEqual(value, expectedValue) {
131 t.Errorf("unexpected value: %v", value)
132 }
133 }
134
135 func TestIssue5(t *testing.T) {
136
137 attrs := Attributes{
138 "id": "user-employee-123456789",
139 "loggedIn": true,
140 "employee": true,
141 "country": "france",
142 "dietaryRestrictions": [1]string{"gluten_free"},
143 }
144
145 features := ParseFeatureMap([]byte(issue1FeaturesJson))
146
147 context := NewContext().
148 WithFeatures(features).
149 WithAttributes(attrs)
150
151 gb := New(context)
152
153 value := gb.Feature("meal_overrides_gluten_free").Value
154
155 expectedValue := map[string]interface{}{
156 "meal_type": "gf",
157 "dessert": "French Vanilla Ice Cream",
158 }
159
160 if !reflect.DeepEqual(value, expectedValue) {
161 t.Errorf("unexpected value: %v", value)
162 }
163 }
164
165 func TestNilContext(t *testing.T) {
166
167 var nilContext *Context
168 gbTest := New(nilContext)
169
170 if !gbTest.inner.context.Enabled {
171 t.Errorf("expected gbTest.enabled to be true")
172 }
173 }
174
175 const numericComparisonsJson = `{
176 "donut_price": {
177 "defaultValue": 2.5,
178 "rules": [
179 {
180 "condition": {
181 "bonus_scheme": 2
182 },
183 "force": 1.0
184 }
185 ]
186 },
187 "donut_rating": {
188 "defaultValue": 4,
189 "rules": [
190 {
191 "condition": {
192 "bonus_scheme": 1
193 },
194 "force": 1
195 }
196 ]
197 }
198
199 }
200 `
201
202 func TestNumericComparisons(t *testing.T) {
203 features := ParseFeatureMap([]byte(numericComparisonsJson))
204
205 attrs := Attributes{"bonus_scheme": 2}
206
207 context := NewContext().
208 WithFeatures(features).
209 WithAttributes(attrs)
210
211 gb := New(context)
212
213 value1 := gb.Feature("donut_price").Value
214 if value1 != 1.0 {
215 t.Errorf("unexpected value: %v", value1)
216 }
217 value2 := gb.Feature("donut_rating").Value
218 if value2 != 4.0 {
219 t.Errorf("unexpected value: %v", value2)
220 }
221 }
222
View as plain text