Skip to content

Commit d3c8d40

Browse files
authored
feat: Support to_h and to_json methods for LDContext (#284)
1 parent adb1d23 commit d3c8d40

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

lib/ldclient-rb/context.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,49 @@ def [](key)
334334
multi_kind? ? individual_context(key.to_s) : get_value(key)
335335
end
336336

337+
#
338+
# Convert the LDContext to a JSON string.
339+
#
340+
# @param args [Array]
341+
# @return [String]
342+
#
343+
def to_json(*args)
344+
JSON.generate(to_h, *args)
345+
end
346+
347+
#
348+
# Convert the LDContext to a hash. If the LDContext is invalid, the hash will contain an error key with the error
349+
# message.
350+
#
351+
# @return [Hash]
352+
#
353+
def to_h
354+
return {error: error} unless valid?
355+
return hash_single_kind unless multi_kind?
356+
357+
hash = {kind: 'multi'}
358+
@contexts.each do |context|
359+
single_kind_hash = context.to_h
360+
kind = single_kind_hash.delete(:kind)
361+
hash[kind] = single_kind_hash
362+
end
363+
364+
hash
365+
end
366+
367+
protected def hash_single_kind
368+
hash = attributes.nil? ? {} : attributes.clone
369+
370+
hash[:kind] = kind
371+
hash[:key] = key
372+
373+
hash[:name] = name unless name.nil?
374+
hash[:anonymous] = anonymous if anonymous
375+
hash[:_meta] = {privateAttributes: private_attributes} unless private_attributes.empty?
376+
377+
hash
378+
end
379+
337380
#
338381
# Retrieve the value of any top level, addressable attribute.
339382
#

lib/ldclient-rb/reference.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,16 @@ def hash
238238
([error] + components).hash
239239
end
240240

241+
#
242+
# Convert the Reference to a JSON string.
243+
#
244+
# @param args [Array]
245+
# @return [String]
246+
#
247+
def to_json(*args)
248+
JSON.generate(@raw_path, *args)
249+
end
250+
241251
#
242252
# Performs unescaping of attribute reference path components:
243253
#

spec/context_spec.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require "ldclient-rb/context"
2+
require "json"
23

34
module LaunchDarkly
45
describe LDContext do
@@ -148,6 +149,64 @@ module LaunchDarkly
148149
expect(org_first.fully_qualified_key).to eq("org:b-org-key:user:a-user-key")
149150
end
150151
end
152+
153+
describe "converts back to JSON format" do
154+
it "single kind contexts" do
155+
contextHash = {
156+
key: "launchdarkly",
157+
kind: "org",
158+
address: {
159+
street: "1999 Harrison St Suite 1100",
160+
city: "Oakland",
161+
state: "CA",
162+
zip: "94612",
163+
_meta: {
164+
privateAttributes: ["city"],
165+
},
166+
},
167+
}
168+
context = subject.create(contextHash)
169+
contextJson = context.to_json
170+
backToHash = JSON.parse(contextJson, symbolize_names: true)
171+
172+
expect(backToHash).to eq(contextHash)
173+
end
174+
175+
it "multi kind contexts" do
176+
contextHash = {
177+
kind: "multi",
178+
"org": {
179+
key: "launchdarkly",
180+
address: {
181+
street: "1999 Harrison St Suite 1100",
182+
city: "Oakland",
183+
state: "CA",
184+
zip: "94612",
185+
},
186+
_meta: {
187+
privateAttributes: ["address/city"],
188+
},
189+
},
190+
"user": {
191+
key: "user-key",
192+
name: "Ruby",
193+
anonymous: true,
194+
},
195+
}
196+
context = subject.create(contextHash)
197+
contextJson = context.to_json
198+
backToHash = JSON.parse(contextJson, symbolize_names: true)
199+
200+
expect(backToHash).to eq(contextHash)
201+
end
202+
203+
it "invalid context returns error" do
204+
context = subject.create({ key: "", kind: "user", name: "testing" })
205+
expect(context.valid?).to be false
206+
expect(context.to_h).to eq({ error: "context key must not be empty" })
207+
expect(context.to_json).to eq({ error: "context key must not be empty" }.to_json)
208+
end
209+
end
151210
end
152211

153212
describe "context counts" do

0 commit comments

Comments
 (0)