Skip to content

Commit c3914df

Browse files
committed
adding new field mapping custom_field_symbol associative array, initialized from global meta data garnered from account context
1 parent 481f999 commit c3914df

File tree

4 files changed

+156
-0
lines changed

4 files changed

+156
-0
lines changed

lib/zendesk_api/client.rb

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

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

108123
# token impersonation for the scope of the block

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: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,55 @@ 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)
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_proxy ||= CustomFieldSymbolProxy.new(self)
514+
end
515+
467516
def self.cbp_path_regexes
468517
[/^tickets$/, %r{organizations/\d+/tickets}, %r{users/\d+/tickets/requested}]
469518
end
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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) }
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+
end
74+
75+
describe "[] and []= with missing ticket_fields_metadata" do
76+
before do
77+
allow(client).to receive(:ticket_fields_metadata).and_return(nil)
78+
end
79+
80+
it "raises error for [] when ticket_fields_metadata is missing" do
81+
expect { proxy["foo"] }.to raise_error(/configuration ticket_fields_metadata is OFF/)
82+
end
83+
84+
it "raises error for []= when ticket_fields_metadata is missing" do
85+
expect { proxy["foo"] = "bar" }.to raise_error(/configuration ticket_fields_metadata is OFF/)
86+
end
87+
end
88+
end

0 commit comments

Comments
 (0)