Skip to content

Commit 6df1c09

Browse files
committed
adding new field mapping custom_field_symbol associative array, initialized from global meta data garnered from account context
1 parent ab34ca8 commit 6df1c09

File tree

5 files changed

+206
-1
lines changed

5 files changed

+206
-1
lines changed

lib/zendesk_api/client.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class Client
3131
# @return [Array] Custom response callbacks
3232
attr_reader :callbacks
3333

34+
attr_reader :ticket_fields_metadata
35+
3436
# Handles resources such as 'tickets'. Any options are passed to the underlying collection, except reload which disregards
3537
# memoization and creates a new Collection instance.
3638
# @return [Collection] Collection instance for resource
@@ -102,6 +104,17 @@ def initialize
102104
set_token_auth
103105
set_default_logger
104106
add_warning_callback
107+
load_ticket_fields_metadata if @config.load_ticket_fields_metadata
108+
end
109+
110+
def load_ticket_fields_metadata
111+
@ticket_fields_metadata = []
112+
ticket_fields.all do |f|
113+
if f
114+
@ticket_fields_metadata << f
115+
end
116+
end
117+
@ticket_fields_metadata
105118
end
106119

107120
# Creates a connection if there is none, otherwise returns the existing connection.

lib/zendesk_api/configuration.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class Configuration
3737
# @return [String] OAuth2 access_token
3838
attr_accessor :access_token
3939

40-
attr_accessor :url_based_access_token
40+
attr_accessor :url_based_access_token, :load_ticket_fields_metadata
4141

4242
# Use this cache instead of default ZendeskAPI::LRUCache.new
4343
# - must respond to read/write/fetch e.g. ActiveSupport::Cache::MemoryStore.new)

lib/zendesk_api/resources.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,56 @@ class Ticket < Resource
464464
extend UpdateMany
465465
extend DestroyMany
466466

467+
# Proxy to trap array operator usage on custom_field_symbol
468+
class CustomFieldSymbolProxy
469+
def initialize(ticket, _arr)
470+
@ticket = ticket
471+
@field_array = @ticket.custom_fields || []
472+
end
473+
474+
def [](key)
475+
# Trap read access
476+
fld = @ticket.instance_variable_get("@client").instance_variable_get("@ticket_fields_metadata").find { |val| val[:title] == key }
477+
raise "Cannot find custom field #{key}" unless fld
478+
cf = @ticket.custom_fields.find { |h| h[:id] == fld[:id] }
479+
cf ? cf[:value] : nil
480+
end
481+
482+
def []=(key, value)
483+
# Trap write access
484+
fld = @ticket.instance_variable_get("@client").instance_variable_get("@ticket_fields_metadata").find { |val| val[:title] == key }
485+
raise "Cannot find custom field #{key}" unless fld
486+
cf = @ticket.custom_fields.find { |h| h[:id] == fld[:id] } if @ticket.custom_fields
487+
if cf
488+
cf[:value] = value
489+
else
490+
@ticket.custom_fields << { id: fld[:id], value: value }
491+
end
492+
end
493+
494+
def to_a
495+
@field_array
496+
end
497+
498+
# Delegate other hash methods as needed
499+
def method_missing(method, ...)
500+
@field_array.send(method, ...)
501+
end
502+
503+
def respond_to_missing?(method, include_private = false)
504+
@field_array.respond_to?(method, include_private)
505+
end
506+
end
507+
508+
def custom_field_symbol
509+
@custom_field_symbol ||= CustomFieldSymbolProxy.new(self, @custom_field_symbol)
510+
end
511+
512+
def custom_field_symbol=(val)
513+
@custom_field_symbol = val
514+
@custom_field_symbol_proxy = CustomFieldSymbolProxy.new(self, @custom_field_symbol)
515+
end
516+
467517
def self.cbp_path_regexes
468518
[/^tickets$/, %r{organizations/\d+/tickets}, %r{users/\d+/tickets/requested}]
469519
end
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
require 'core/spec_helper'
2+
require_relative '../../../lib/zendesk_api/resources'
3+
4+
RSpec.describe ZendeskAPI::Ticket::CustomFieldSymbolProxy do
5+
let(:field_metadata) do
6+
[
7+
{ id: 1, title: "foo" },
8+
{ id: 2, title: "bar" }
9+
]
10+
end
11+
let(:client) do
12+
double("Client").tap do |c|
13+
allow(c).to receive(:instance_variable_get).with("@ticket_fields_metadata").and_return(field_metadata)
14+
end
15+
end
16+
let(:ticket) do
17+
t = ZendeskAPI::Ticket.new({})
18+
t.instance_variable_set(:@client, client)
19+
t.instance_variable_set(:@custom_fields, [{ id: 1, value: "abc" }])
20+
def t.custom_fields
21+
_foo = 1
22+
@custom_fields
23+
end
24+
t
25+
end
26+
let(:proxy) { described_class.new(ticket, nil) }
27+
28+
describe "[] and []=" do
29+
it "reads a custom field by symbol (existing)" do
30+
expect(proxy["foo"]).to eq("abc")
31+
end
32+
33+
it "returns nil for existing field with no value" do
34+
ticket.instance_variable_set(:@custom_fields, [{ id: 1 }])
35+
expect(proxy["foo"]).to be_nil
36+
end
37+
38+
it "raises error for missing field title" do
39+
expect { proxy["baz"] }.to raise_error(/Cannot find custom field/)
40+
end
41+
42+
it "writes a custom field by symbol (existing)" do
43+
proxy["foo"] = "updated"
44+
expect(ticket.custom_fields.find { |h| h[:id] == 1 }[:value]).to eq("updated")
45+
end
46+
47+
it "writes a custom field by symbol (new)" do
48+
proxy["bar"] = "def"
49+
expect(ticket.custom_fields.find { |h| h[:id] == 2 }[:value]).to eq("def")
50+
end
51+
end
52+
53+
describe "delegation and integration" do
54+
it "delegates to_a" do
55+
expect(proxy.to_a).to eq(ticket.custom_fields)
56+
end
57+
58+
it "delegates method_missing and respond_to_missing?" do
59+
expect(proxy.respond_to?(:each)).to be true
60+
expect(proxy.map { |h| h[:id] }).to include(1)
61+
end
62+
63+
it "returns proxy from custom_field_symbol accessor" do
64+
t = ZendeskAPI::Ticket.new({})
65+
t.instance_variable_set(:@client, client)
66+
t.instance_variable_set(:@custom_fields, [{ id: 1, value: "abc" }])
67+
def t.custom_fields
68+
_foo = 1
69+
@custom_fields
70+
end
71+
expect(t.custom_field_symbol["foo"]).to eq("abc")
72+
end
73+
74+
it "updates proxy on custom_field_symbol= assignment" do
75+
t = ZendeskAPI::Ticket.new({})
76+
t.instance_variable_set(:@client, client)
77+
def t.custom_fields
78+
_foo = 1
79+
@custom_fields
80+
end
81+
t.custom_field_symbol = [{ id: 1, value: "xyz" }]
82+
expect(t.custom_field_symbol.to_a).to eq([{ id: 1, value: "xyz" }])
83+
end
84+
end
85+
end

spec/live/ticket_spec.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,61 @@ def valid_attributes
211211
end
212212
end
213213
end
214+
215+
describe "CustomFieldSymbolProxy" do
216+
let(:field_metadata) do
217+
[
218+
{ id: 1, title: "foo" },
219+
{ id: 2, title: "bar" }
220+
]
221+
end
222+
let(:client) do
223+
double("Client", :instance_variable_get => field_metadata)
224+
end
225+
let(:ticket) do
226+
t = ZendeskAPI::Ticket.allocate
227+
t.instance_variable_set(:@client, client)
228+
t.instance_variable_set(:@custom_fields, [{ id: 1, value: "abc" }])
229+
t
230+
end
231+
let(:proxy) { ZendeskAPI::Ticket::CustomFieldSymbolProxy.new(ticket, nil) }
232+
233+
it "reads a custom field by symbol" do
234+
expect(proxy["foo"]).to eq("abc")
235+
end
236+
237+
it "raises error for missing field" do
238+
expect { proxy["baz"] }.to raise_error(/Cannot find custom field/)
239+
end
240+
241+
it "writes a custom field by symbol" do
242+
proxy["bar"] = "def"
243+
expect(ticket.custom_fields.find { |h| h[:id] == 2 }[:value]).to eq("def")
244+
end
245+
246+
it "delegates to_a" do
247+
expect(proxy.to_a).to eq(ticket.custom_fields)
248+
end
249+
250+
it "delegates method_missing and respond_to_missing?" do
251+
expect(proxy.respond_to?(:each)).to be true
252+
expect(proxy.map { |h| h[:id] }).to eq([1])
253+
end
254+
255+
describe "integration with Ticket methods" do
256+
it "returns proxy from custom_field_symbol accessor" do
257+
t = ZendeskAPI::Ticket.allocate
258+
t.instance_variable_set(:@client, client)
259+
t.instance_variable_set(:@custom_fields, [{ id: 1, value: "abc" }])
260+
expect(t.custom_field_symbol["foo"]).to eq("abc")
261+
end
262+
263+
it "updates proxy on custom_field_symbol= assignment" do
264+
t = ZendeskAPI::Ticket.allocate
265+
t.instance_variable_set(:@client, client)
266+
t.custom_field_symbol = [{ id: 1, value: "xyz" }]
267+
expect(t.custom_field_symbol.to_a).to eq([{ id: 1, value: "xyz" }])
268+
end
269+
end
270+
end
214271
end

0 commit comments

Comments
 (0)