Skip to content

Commit 1cad2d1

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 1cad2d1

File tree

5 files changed

+229
-0
lines changed

5 files changed

+229
-0
lines changed

lib/zendesk_api/client.rb

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

34+
def ticket_fields_metadata
35+
@ticket_fields_metadata ||= []
36+
end
37+
3438
# Handles resources such as 'tickets'. Any options are passed to the underlying collection, except reload which disregards
3539
# memoization and creates a new Collection instance.
3640
# @return [Collection] Collection instance for resource
@@ -102,6 +106,17 @@ def initialize
102106
set_token_auth
103107
set_default_logger
104108
add_warning_callback
109+
load_ticket_fields_metadata if @config.load_ticket_fields_metadata
110+
end
111+
112+
def load_ticket_fields_metadata
113+
@ticket_fields_metadata = []
114+
ticket_fields.all do |f|
115+
if f
116+
@ticket_fields_metadata << f
117+
end
118+
end
119+
@ticket_fields_metadata
105120
end
106121

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

lib/zendesk_api/configuration.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ class Configuration
3737
# @return [String] OAuth2 access_token
3838
attr_accessor :access_token
3939

40+
# @return [String] url_based_access_token
4041
attr_accessor :url_based_access_token
4142

43+
# @return [Boolean] load_ticket_fields_metadata
44+
attr_accessor :load_ticket_fields_metadata
45+
4246
# Use this cache instead of default ZendeskAPI::LRUCache.new
4347
# - must respond to read/write/fetch e.g. ActiveSupport::Cache::MemoryStore.new)
4448
# - pass false to disable caching

lib/zendesk_api/resources.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,60 @@ 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+
raise "Cannot find custom field #{key}, configuration ticket_fields_metadata is OFF" unless
476+
@ticket.instance_variable_get("@client").ticket_fields_metadata
477+
# Trap read access
478+
fld = @ticket.instance_variable_get("@client").ticket_fields_metadata.find { |val| val[:title] == key }
479+
raise "Cannot find custom field #{key}" unless fld
480+
cf = @ticket.custom_fields.find { |h| h[:id] == fld[:id] }
481+
cf ? cf[:value] : nil
482+
end
483+
484+
def []=(key, value)
485+
raise "Cannot find custom field #{key}, configuration ticket_fields_metadata is OFF" unless
486+
@ticket.instance_variable_get("@client").ticket_fields_metadata
487+
# Trap write access
488+
fld = @ticket.instance_variable_get("@client").ticket_fields_metadata.find { |val| val[:title] == key }
489+
raise "Cannot find custom field #{key}" unless fld
490+
cf = @ticket.custom_fields.find { |h| h[:id] == fld[:id] } if @ticket.custom_fields
491+
if cf
492+
cf[:value] = value
493+
else
494+
@ticket.custom_fields << { id: fld[:id], value: value }
495+
end
496+
end
497+
498+
def to_a
499+
@field_array
500+
end
501+
502+
# Delegate other hash methods as needed
503+
def method_missing(method, ...)
504+
@field_array.send(method, ...)
505+
end
506+
507+
def respond_to_missing?(method, include_private = false)
508+
@field_array.respond_to?(method, include_private)
509+
end
510+
end
511+
512+
def custom_field_symbol
513+
@custom_field_symbol ||= CustomFieldSymbolProxy.new(self, @custom_field_symbol)
514+
end
515+
516+
def custom_field_symbol=(val)
517+
@custom_field_symbol = val
518+
@custom_field_symbol_proxy = CustomFieldSymbolProxy.new(self, @custom_field_symbol)
519+
end
520+
467521
def self.cbp_path_regexes
468522
[/^tickets$/, %r{organizations/\d+/tickets}, %r{users/\d+/tickets/requested}]
469523
end
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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(: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+
86+
describe "[] and []= with missing ticket_fields_metadata" do
87+
before do
88+
allow(client).to receive(:ticket_fields_metadata).and_return(nil)
89+
end
90+
91+
it "raises error for [] when ticket_fields_metadata is missing" do
92+
expect { proxy["foo"] }.to raise_error(/configuration ticket_fields_metadata is OFF/)
93+
end
94+
95+
it "raises error for []= when ticket_fields_metadata is missing" do
96+
expect { proxy["foo"] = "bar" }.to raise_error(/configuration ticket_fields_metadata is OFF/)
97+
end
98+
end
99+
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)