1 package lduser
2
3 import (
4 "testing"
5
6 "github.com/launchdarkly/go-sdk-common/v3/ldcontext"
7 "github.com/launchdarkly/go-sdk-common/v3/ldvalue"
8
9 "github.com/stretchr/testify/assert"
10 )
11
12 func TestConstructors(t *testing.T) {
13 assert.Equal(t, ldcontext.New("some-key"), NewUser("some-key"))
14 assert.Equal(t, ldcontext.NewBuilder("some-key").Anonymous(true).Build(), NewAnonymousUser("some-key"))
15 }
16
17 func TestUserBuilderSetsOnlyKeyByDefault(t *testing.T) {
18 c := NewUserBuilder("some-key").Build()
19
20 assert.Equal(t, ldcontext.Kind("user"), c.Kind())
21 assert.Equal(t, "some-key", c.Key())
22 assert.False(t, c.Secondary().IsDefined())
23 assert.False(t, c.Anonymous())
24 assert.Len(t, c.GetOptionalAttributeNames(nil), 0)
25 assert.Equal(t, 0, c.PrivateAttributeCount())
26 }
27
28 func TestUserBuilderCanSetStringAttributes(t *testing.T) {
29 for a, setter := range optionalStringSetters {
30 t.Run(string(a), func(t *testing.T) {
31 builder := NewUserBuilder("some-key")
32 setter(builder, "value")
33 c := builder.Build()
34
35 assert.Equal(t, ldcontext.Kind("user"), c.Kind())
36 assert.Equal(t, "some-key", c.Key())
37
38 assert.Equal(t, ldvalue.NewOptionalString("value"), optionalStringGetters[a](c), a)
39
40 for a1 := range optionalStringSetters {
41 if a1 != a {
42 assertStringAttrNotSet(t, a1, c)
43 }
44 }
45 })
46 }
47 }
48
49 func TestUserBuilderCanSetAnonymous(t *testing.T) {
50 user0 := NewUserBuilder("some-key").Build()
51 assert.False(t, user0.Anonymous())
52
53 user1 := NewUserBuilder("some-key").Anonymous(true).Build()
54 assert.True(t, user1.Anonymous())
55
56 user2 := NewUserBuilder("some-key").Anonymous(false).Build()
57 assert.False(t, user2.Anonymous())
58 }
59
60 func TestUserBuilderCanSetPrivateAttributes(t *testing.T) {
61 for a, setter := range optionalStringSetters {
62 t.Run(string(a), func(t *testing.T) {
63 builder := NewUserBuilder("some-key")
64 setter(builder, "value").AsPrivateAttribute()
65 c := builder.Build()
66
67 assert.Equal(t, "some-key", c.Key())
68
69 assert.Equal(t, ldvalue.NewOptionalString("value"), optionalStringGetters[a](c))
70 value := c.GetValue(string(a))
71 if a == "secondary" {
72
73 assert.False(t, value.IsDefined())
74 } else {
75 assert.Equal(t, ldvalue.String("value"), value)
76 }
77
78 for a1 := range optionalStringSetters {
79 if a1 != a {
80 assertStringAttrNotSet(t, a1, c)
81 }
82 }
83
84 if string(a) == "secondary" {
85 assert.Len(t, sortedOptionalAttributes(c), 0)
86 } else {
87 assert.Equal(t, []string{string(a)}, sortedOptionalAttributes(c))
88 }
89 assert.Equal(t, []string{string(a)}, sortedPrivateAttributes(c))
90 })
91 }
92
93 t.Run("custom", func(t *testing.T) {
94 builder := NewUserBuilder("some-key")
95 builder.Custom("my-attr", ldvalue.String("value")).AsPrivateAttribute()
96 c := builder.Build()
97
98 value := c.GetValue("my-attr")
99 assert.Equal(t, ldvalue.String("value"), value)
100
101 assert.Equal(t, []string{"my-attr"}, sortedPrivateAttributes(c))
102 })
103
104 t.Run("custom with leading slash", func(t *testing.T) {
105 builder := NewUserBuilder("some-key")
106 builder.Custom("/my-attr", ldvalue.String("value")).AsPrivateAttribute()
107 c := builder.Build()
108
109 value := c.GetValue("/my-attr")
110 assert.Equal(t, ldvalue.String("value"), value)
111
112 assert.Equal(t, []string{"/~1my-attr"}, sortedPrivateAttributes(c))
113 })
114 }
115
116 func TestUserBuilderCanMakeAttributeNonPrivate(t *testing.T) {
117 builder := NewUserBuilder("some-key")
118 builder.Country("us").AsNonPrivateAttribute()
119 builder.Email("e").AsPrivateAttribute()
120 builder.Name("n").AsPrivateAttribute()
121 builder.Email("f").AsNonPrivateAttribute()
122
123 c := builder.Build()
124
125 value := c.GetValue("email")
126 assert.Equal(t, ldvalue.String("f"), value)
127
128 assert.Equal(t, []string{"name"}, sortedPrivateAttributes(c))
129 }
130
131 func TestUserBuilderCanSetCustomAttributes(t *testing.T) {
132 c := NewUserBuilder("some-key").Custom("first", ldvalue.Int(1)).Custom("second", ldvalue.String("two")).Build()
133
134 value := c.GetValue("first")
135 assert.Equal(t, 1, value.IntValue())
136
137 value = c.GetValue("second")
138 assert.Equal(t, "two", value.StringValue())
139
140 value = c.GetValue("no")
141 assert.Equal(t, ldvalue.Null(), value)
142
143 assert.Equal(t, []string{"first", "second"}, sortedOptionalAttributes(c))
144 assert.Len(t, sortedPrivateAttributes(c), 0)
145 }
146
147 func TestUserBuilderCanSetCustomAttributesAsMap(t *testing.T) {
148 valueMap := ldvalue.ValueMapBuild().Set("first", ldvalue.Int(1)).Set("second", ldvalue.String("two")).Build()
149 c := NewUserBuilder("some-key").CustomAll(valueMap).Build()
150
151 value := c.GetValue("first")
152 assert.Equal(t, ldvalue.Int(1), value)
153
154 value = c.GetValue("second")
155 assert.Equal(t, ldvalue.String("two"), value)
156
157 assert.Equal(t, []string{"first", "second"}, sortedOptionalAttributes(c))
158 }
159
160 func TestUserBuilderCustomAllReplacesAllCustomAttributes(t *testing.T) {
161 valueMap := ldvalue.ValueMapBuild().Set("second", ldvalue.String("two")).Build()
162 c1 := NewUserBuilder("some-key").Email("my-email").Custom("first", ldvalue.Int(1)).
163 CustomAll(valueMap).Build()
164
165 assert.Equal(t, []string{"email", "second"}, sortedOptionalAttributes(c1))
166
167 c2 := NewUserBuilder("some-key").Email("my-email").Custom("first", ldvalue.Int(1)).
168 CustomAll(ldvalue.ValueMap{}).Build()
169
170 assert.Equal(t, []string{"email"}, sortedOptionalAttributes(c2))
171 }
172
173 func TestUserBuilderCanSetAttributesAfterSettingAttributeThatCanBePrivate(t *testing.T) {
174
175 builder := NewUserBuilder("some-key").Name("original-name").Key("new-key")
176 c := builder.Build()
177
178 assert.Equal(t, "new-key", c.Key())
179 }
180
181 func TestUserBuilderGenericSetAttribute(t *testing.T) {
182 t.Run("key", func(t *testing.T) {
183 builder := NewUserBuilder("some-key")
184 value := "value"
185
186 builder.SetAttribute(KeyAttribute, ldvalue.String(value))
187 assert.Equal(t, value, builder.Build().Key())
188
189
190 builder.SetAttribute(KeyAttribute, ldvalue.Null())
191 assert.Equal(t, value, builder.Build().Key())
192 builder.SetAttribute(KeyAttribute, ldvalue.Bool(true))
193 assert.Equal(t, value, builder.Build().Key())
194
195 builder.SetAttribute(KeyAttribute, ldvalue.String(value)).AsPrivateAttribute()
196 assert.Len(t, sortedPrivateAttributes(builder.Build()), 0)
197 })
198
199 for a, getter := range optionalStringGetters {
200 t.Run(string(a), func(t *testing.T) {
201 builder := NewUserBuilder("some-key")
202 valueStr := ldvalue.NewOptionalString("value")
203 value := valueStr.AsValue()
204
205 builder.SetAttribute(a, value)
206 assert.Equal(t, valueStr, getter(builder.Build()))
207
208
209 builder.SetAttribute(a, ldvalue.Bool(true))
210 assert.Equal(t, valueStr, getter(builder.Build()))
211
212 for a1 := range optionalStringGetters {
213 if a1 != a {
214 assertStringAttrNotSet(t, a1, builder.Build())
215 }
216 }
217
218 assert.Len(t, sortedPrivateAttributes(builder.Build()), 0)
219
220 builder.SetAttribute(a, ldvalue.Null())
221 assert.Equal(t, ldvalue.OptionalString{}, getter(builder.Build()))
222
223 builder.SetAttribute(a, value).AsPrivateAttribute()
224 assert.Equal(t, []string{string(a)}, sortedPrivateAttributes(builder.Build()))
225 })
226 }
227
228 t.Run("anonymous", func(t *testing.T) {
229 builder := NewUserBuilder("some-key")
230
231 builder.SetAttribute(AnonymousAttribute, ldvalue.Bool(false))
232 assert.False(t, builder.Build().Anonymous())
233
234 builder.SetAttribute(AnonymousAttribute, ldvalue.Bool(true))
235 assert.True(t, builder.Build().Anonymous())
236
237
238 builder.SetAttribute(AnonymousAttribute, ldvalue.String("x"))
239 assert.True(t, builder.Build().Anonymous())
240
241 builder.SetAttribute(AnonymousAttribute, ldvalue.Null())
242 assert.False(t, builder.Build().Anonymous())
243 })
244
245 t.Run("custom", func(t *testing.T) {
246 builder := NewUserBuilder("some-key")
247 name := "thing"
248 value := ldvalue.Int(2)
249
250 builder.SetAttribute(UserAttribute(name), value)
251 c0 := builder.Build()
252 v := c0.GetValue(name)
253 assert.Equal(t, value, v)
254 assert.Equal(t, []string{name}, sortedOptionalAttributes(c0))
255 assert.Len(t, sortedPrivateAttributes(c0), 0)
256
257 builder.SetAttribute(UserAttribute(name), ldvalue.Null())
258 c1 := builder.Build()
259 v = c1.GetValue(name)
260 assert.Equal(t, ldvalue.Null(), v)
261 assert.Len(t, sortedOptionalAttributes(c1), 0)
262 assert.Len(t, sortedPrivateAttributes(c1), 0)
263
264 builder.SetAttribute(UserAttribute(name), value).AsPrivateAttribute()
265 c2 := builder.Build()
266 assert.Equal(t, []string{name}, sortedPrivateAttributes(c2))
267 })
268 }
269
270 func TestUserBuilderCanCopyFromExistingUserWithOnlyKey(t *testing.T) {
271 user0 := NewUser("some-key")
272 user1 := NewUserBuilderFromUser(user0).Build()
273
274 assert.Equal(t, user0, user1)
275 }
276
277 func TestUserBuilderCanCopyFromExistingUserWithAllAttributes(t *testing.T) {
278 user0 := NewUserBuilder("some-key").
279 Name("name").
280 FirstName("firstName").
281 LastName("lastName").
282 Email("email").AsPrivateAttribute().
283 Country("country").
284 Avatar("avatar").
285 IP("ip").
286 Custom("attr", ldvalue.String("value")).
287 Anonymous(true).
288 Build()
289 user1 := NewUserBuilderFromUser(user0).Build()
290 assert.Equal(t, user0, user1)
291 }
292
View as plain text