zendesk_api 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1d55a2716fcbc1751d58a23796282e5b5689ac4fe193bdf0e5abc800605c200
4
- data.tar.gz: fae9a5e9c62eb4ef7cfd61e01af12b5fd3fbcca709271f2bf00552863a22972c
3
+ metadata.gz: bb7a7899050cd837be40995be562bb7c95a04e7d631a34cdddaa671c1eeca9b3
4
+ data.tar.gz: c042f01365e91e868c54e7aa5fc1318fc490efa2440093e24df86df6800feaba
5
5
  SHA512:
6
- metadata.gz: d70b174c454944498d191d962036890c654ae25ed8c6e5a310aaecbc7364b21b203246052b311702fc564ee3be4c00b92f3f6b57ca29367bcb79039bef16cac2
7
- data.tar.gz: 702de99c18e0f256f4871a8fa31a588de67d7da46402c8a14f77d97cd1c1f90fdbead7481bdcb26d2e5c6e0176c5e2c739c954b6162808b1b6ff38edc6028864
6
+ metadata.gz: efafbaa0881befe0fd827e9fa465a3f7be19ec566199dd1640f5bba68ec101a6a0eb8b30efe850a08ca5f2adc2004ab809e74ba96eb52b3f8ac2e63f75c07e72
7
+ data.tar.gz: 6c81354976ef9ce6adf2f6ae084d7a60ae04fd49e10033e5025e5697a1f7adaac9385834f1c22a671e08cb94c3132d5c365a2e2a969b42f3035e301e94ed0a68
@@ -37,24 +37,25 @@ module ZendeskAPI
37
37
  def method_missing(method, *args, &block)
38
38
  method = method.to_s
39
39
  options = args.last.is_a?(Hash) ? args.pop : {}
40
-
41
40
  unless config.use_resource_cache
42
- raise "Resource for #{method} does not exist" unless method_as_class(method)
43
- return ZendeskAPI::Collection.new(self, method_as_class(method), options)
41
+ resource_class = resource_class_for(method)
42
+ raise "Resource for #{method} does not exist" unless resource_class
43
+ return ZendeskAPI::Collection.new(self, resource_class, options)
44
44
  end
45
45
 
46
46
  @resource_cache[method] ||= { :class => nil, :cache => ZendeskAPI::LRUCache.new }
47
47
  if !options.delete(:reload) && (cached = @resource_cache[method][:cache].read(options.hash))
48
48
  cached
49
49
  else
50
- @resource_cache[method][:class] ||= method_as_class(method)
50
+ @resource_cache[method][:class] ||= resource_class_for(method)
51
51
  raise "Resource for #{method} does not exist" unless @resource_cache[method][:class]
52
52
  @resource_cache[method][:cache].write(options.hash, ZendeskAPI::Collection.new(self, @resource_cache[method][:class], options))
53
53
  end
54
54
  end
55
55
 
56
56
  def respond_to?(method, *args)
57
- ((cache = @resource_cache[method]) && cache[:class]) || !method_as_class(method).nil? || super
57
+ cache = @resource_cache[method]
58
+ !!(cache.to_h[:class] || resource_class_for(method) || super)
58
59
  end
59
60
 
60
61
  # Returns the current user (aka me)
@@ -184,9 +185,9 @@ module ZendeskAPI
184
185
 
185
186
  private
186
187
 
187
- def method_as_class(method)
188
- klass_as_string = ZendeskAPI::Helpers.modulize_string(Inflection.singular(method.to_s.gsub(/\W/, '')))
189
- ZendeskAPI::Association.class_from_namespace(klass_as_string)
188
+ def resource_class_for(method)
189
+ resource_name = ZendeskAPI::Helpers.modulize_string(Inflection.singular(method.to_s.gsub(/\W/, '')))
190
+ ZendeskAPI::Association.class_from_namespace(resource_name)
190
191
  end
191
192
 
192
193
  def check_url
@@ -1,14 +1,14 @@
1
1
  require 'zendesk_api/resource'
2
2
  require 'zendesk_api/resources'
3
3
  require 'zendesk_api/search'
4
+ require 'zendesk_api/pagination'
4
5
 
5
6
  module ZendeskAPI
6
7
  # Represents a collection of resources. Lazily loaded, resources aren't
7
8
  # actually fetched until explicitly needed (e.g. #each, {#fetch}).
8
9
  class Collection
9
- DEFAULT_PAGE_SIZE = 100
10
-
11
10
  include ZendeskAPI::Sideloading
11
+ include Pagination
12
12
 
13
13
  # Options passed in that are automatically converted from an array to a comma-separated list.
14
14
  SPECIALLY_JOINED_PARAMS = [:ids, :only]
@@ -116,30 +116,6 @@ module ZendeskAPI
116
116
  @count || -1
117
117
  end
118
118
 
119
- # Changes the per_page option. Returns self, so it can be chained. No execution.
120
- # @return [Collection] self
121
- def per_page(count)
122
- clear_cache if count
123
- @options["per_page"] = count
124
- self
125
- end
126
-
127
- # Changes the page option. Returns self, so it can be chained. No execution.
128
- # @return [Collection] self
129
- def page(number)
130
- clear_cache if number
131
- @options["page"] = number
132
- self
133
- end
134
-
135
- def first_page?
136
- !@prev_page
137
- end
138
-
139
- def last_page?
140
- !@next_page || @next_page == @query
141
- end
142
-
143
119
  # Saves all newly created resources stored in this collection.
144
120
  # @return [Collection] self
145
121
  def save
@@ -323,11 +299,6 @@ module ZendeskAPI
323
299
  map(&:to_param)
324
300
  end
325
301
 
326
- def more_results?(response)
327
- Helpers.present?(response["meta"]) && response["meta"]["has_more"]
328
- end
329
- alias_method :has_more_results?, :more_results? # For backward compatibility with 1.33.0 and 1.34.0
330
-
331
302
  def get_next_page_data(original_response_body)
332
303
  link = original_response_body["links"]["next"]
333
304
  result_key = @resource_class.model_key || "results"
@@ -344,42 +315,14 @@ module ZendeskAPI
344
315
 
345
316
  private
346
317
 
347
- def cbp_response?(body)
348
- !!(body["meta"] && body["links"])
349
- end
350
-
351
- def cbp_request?
352
- @options["page"].is_a?(Hash)
353
- end
354
-
355
- def intentional_obp_request?
356
- Helpers.present?(@options["page"]) && !cbp_request?
357
- end
358
-
359
- def should_try_cbp?(path_query_link)
360
- not_supported_endpoints = %w[show_many]
361
- not_supported_endpoints.none? { |endpoint| path_query_link.end_with?(endpoint) }
362
- end
363
-
364
318
  def get_resources(path_query_link)
365
319
  if intentional_obp_request?
366
320
  warn "Offset Based Pagination will be deprecated soon"
367
- elsif @next_page.nil? && should_try_cbp?(path_query_link)
368
- @options_per_page_was = @options.delete("per_page")
369
- # Default to CBP by using the page param as a map
370
- @options.page = { size: (@options_per_page_was || DEFAULT_PAGE_SIZE) }
371
- end
372
-
373
- begin
374
- # Try CBP first, unless the user explicitly asked for OBP
375
- @response = get_response(path_query_link)
376
- rescue ZendeskAPI::Error::NetworkError => e
377
- raise e if intentional_obp_request?
378
- # Fallback to OBP if CBP didn't work, using per_page param
379
- @options.per_page = @options_per_page_was
380
- @options.page = nil
381
- @response = get_response(path_query_link)
321
+ elsif supports_cbp? && first_cbp_request?
322
+ # only set cbp options if it's the first request, otherwise the options would be already in place
323
+ set_cbp_options
382
324
  end
325
+ @response = get_response(path_query_link)
383
326
 
384
327
  # Keep pre-existing behaviour for search/export
385
328
  if path_query_link == "search/export"
@@ -389,29 +332,6 @@ module ZendeskAPI
389
332
  end
390
333
  end
391
334
 
392
- def set_page_and_count(body)
393
- @count = (body["count"] || @resources.size).to_i
394
- @next_page, @prev_page = page_links(body)
395
-
396
- if cbp_response?(body)
397
- # We'll delete the one we don't need in #next or #prev
398
- @options["page"]["after"] = body["meta"]["after_cursor"]
399
- @options["page"]["before"] = body["meta"]["before_cursor"]
400
- elsif @next_page =~ /page=(\d+)/
401
- @options["page"] = $1.to_i - 1
402
- elsif @prev_page =~ /page=(\d+)/
403
- @options["page"] = $1.to_i + 1
404
- end
405
- end
406
-
407
- def page_links(body)
408
- if body["meta"] && body["links"]
409
- [body["links"]["next"], body["links"]["prev"]]
410
- else
411
- [body["next_page"], body["previous_page"]]
412
- end
413
- end
414
-
415
335
  def _all(start_page = @options["page"], bang = false, &block)
416
336
  raise(ArgumentError, "must pass a block") unless block
417
337
 
@@ -541,9 +461,13 @@ module ZendeskAPI
541
461
  to_a.public_send(name, *args, &block)
542
462
  end
543
463
 
464
+ # If you call client.tickets.foo - and foo is not an attribute nor an association, it ends up here, as a new collection
544
465
  def next_collection(name, *args, &block)
545
466
  opts = args.last.is_a?(Hash) ? args.last : {}
546
- opts.merge!(:collection_path => @collection_path.dup.push(name))
467
+ opts.merge!(collection_path: [*@collection_path, name], page: nil)
468
+ # why page: nil ?
469
+ # when you do client.tickets.fetch followed by client.tickets.foos => the request to /tickets/foos will
470
+ # have the options page set to whatever the last options were for the tickets collection
547
471
  self.class.new(@client, @resource_class, @options.merge(opts))
548
472
  end
549
473
 
@@ -0,0 +1,99 @@
1
+ module ZendeskAPI
2
+ class Collection
3
+ # Contains all methods related to pagination in an attempt to slim down collection.rb
4
+ module Pagination
5
+ DEFAULT_PAGE_SIZE = 100
6
+ def more_results?(response)
7
+ Helpers.present?(response["meta"]) && response["meta"]["has_more"]
8
+ end
9
+ alias has_more_results? more_results? # For backward compatibility with 1.33.0 and 1.34.0
10
+
11
+ # Changes the per_page option. Returns self, so it can be chained. No execution.
12
+ # @return [Collection] self
13
+ def per_page(count)
14
+ clear_cache if count
15
+ @options["per_page"] = count
16
+ self
17
+ end
18
+
19
+ # Changes the page option. Returns self, so it can be chained. No execution.
20
+ # @return [Collection] self
21
+ def page(number)
22
+ clear_cache if number
23
+ @options["page"] = number
24
+ self
25
+ end
26
+
27
+ def first_page?
28
+ !@prev_page
29
+ end
30
+
31
+ def last_page?
32
+ !@next_page || @next_page == @query
33
+ end
34
+
35
+ private
36
+
37
+ def page_links(body)
38
+ if body["meta"] && body["links"]
39
+ [body["links"]["next"], body["links"]["prev"]]
40
+ else
41
+ [body["next_page"], body["previous_page"]]
42
+ end
43
+ end
44
+
45
+ def cbp_response?(body)
46
+ !!(body["meta"] && body["links"])
47
+ end
48
+
49
+ def set_cbp_options
50
+ @options_per_page_was = @options.delete("per_page")
51
+ # Default to CBP by using the page param as a map
52
+ @options.page = { size: (@options_per_page_was || DEFAULT_PAGE_SIZE) }
53
+ end
54
+
55
+ # CBP requests look like: `/resources?page[size]=100`
56
+ # OBP requests look like: `/resources?page=2`
57
+ def cbp_request?
58
+ @options["page"].is_a?(Hash)
59
+ end
60
+
61
+ def intentional_obp_request?
62
+ Helpers.present?(@options["page"]) && !cbp_request?
63
+ end
64
+
65
+ def supports_cbp?
66
+ @resource_class.cbp_path_regexes.any? { |supported_path_regex| path.match?(supported_path_regex) }
67
+ end
68
+
69
+ def first_cbp_request?
70
+ # @next_page will be nil when making the first cbp request
71
+ @next_page.nil?
72
+ end
73
+
74
+ def set_page_and_count(body)
75
+ @count = (body["count"] || @resources.size).to_i
76
+ @next_page, @prev_page = page_links(body)
77
+
78
+ if cbp_response?(body)
79
+ set_cbp_response_options(body)
80
+ elsif @next_page =~ /page=(\d+)/
81
+ @options["page"] = Regexp.last_match(1).to_i - 1
82
+ elsif @prev_page =~ /page=(\d+)/
83
+ @options["page"] = Regexp.last_match(1).to_i + 1
84
+ end
85
+ end
86
+
87
+ def set_cbp_response_options(body)
88
+ @options.page = {} unless cbp_request?
89
+ # the line above means an intentional CBP request where page[size] is passed on the query
90
+ # this is to cater for CBP responses where we don't specify page[size] but the endpoint
91
+ # responds CBP by default. i.e `client.trigger_categories.fetch`
92
+ @options.page.merge!(
93
+ before: body["meta"]["before_cursor"],
94
+ after: body["meta"]["after_cursor"]
95
+ )
96
+ end
97
+ end
98
+ end
99
+ end
@@ -163,6 +163,10 @@ module ZendeskAPI
163
163
  class DataResource < Data
164
164
  attr_accessor :error, :error_message
165
165
  extend Verbs
166
+
167
+ def self.cbp_path_regexes
168
+ []
169
+ end
166
170
  end
167
171
 
168
172
  # Represents a resource that can only GET
@@ -152,6 +152,10 @@ module ZendeskAPI
152
152
  def self.incremental_export(client, start_time)
153
153
  ZendeskAPI::Collection.new(client, self, :path => "incremental/organizations?start_time=#{start_time.to_i}")
154
154
  end
155
+
156
+ def self.cbp_path_regexes
157
+ [/organizations$/]
158
+ end
155
159
  end
156
160
 
157
161
  class Brand < Resource
@@ -180,6 +184,10 @@ module ZendeskAPI
180
184
 
181
185
  has User
182
186
  has Organization
187
+
188
+ def self.cbp_path_regexes
189
+ [%r{organizations/\d+/subscriptions$}]
190
+ end
183
191
  end
184
192
 
185
193
  class Category < Resource
@@ -258,10 +266,10 @@ module ZendeskAPI
258
266
  end
259
267
 
260
268
  class Topic < Resource
261
- has_many :subscriptions, :class => TopicSubscription, :inline => true
262
- has_many Tag, :extend => Tag::Update, :inline => :create
269
+ has_many :subscriptions, class: TopicSubscription, inline: true
270
+ has_many Tag, extend: Tag::Update, inline: :create
263
271
  has_many Attachment
264
- has_many :uploads, :class => Attachment, :inline => true
272
+ has_many :uploads, class: Attachment, inline: true
265
273
  end
266
274
 
267
275
  class Activity < Resource
@@ -318,7 +326,7 @@ module ZendeskAPI
318
326
  class Comment < DataResource
319
327
  include Save
320
328
 
321
- has_many :uploads, :class => Attachment, :inline => true
329
+ has_many :uploads, class: Attachment, inline: true
322
330
  has :author, :class => User
323
331
 
324
332
  def save
@@ -360,7 +368,7 @@ module ZendeskAPI
360
368
  class TicketEvent < DataResource
361
369
  class Event < Data; end
362
370
 
363
- has_many :child_events, :class => Event
371
+ has_many :child_events, class: Event
364
372
  has Ticket
365
373
  has :updater, :class => User
366
374
 
@@ -378,6 +386,10 @@ module ZendeskAPI
378
386
  extend UpdateMany
379
387
  extend DestroyMany
380
388
 
389
+ def self.cbp_path_regexes
390
+ [/tickets$/]
391
+ end
392
+
381
393
  # Unlike other attributes, "comment" is not a property of the ticket,
382
394
  # but is used as a "comment on save", so it should be kept unchanged,
383
395
  # See https://github.com/zendesk/zendesk_api_client_rb/issues/321
@@ -401,8 +413,8 @@ module ZendeskAPI
401
413
  class Comment < DataResource
402
414
  include Save
403
415
 
404
- has_many :uploads, :class => Attachment, :inline => true
405
- has :author, :class => User
416
+ has_many :uploads, class: Attachment, inline: true
417
+ has :author, class: User
406
418
 
407
419
  def save
408
420
  if new_record?
@@ -429,35 +441,35 @@ module ZendeskAPI
429
441
  has :submitter, :class => User
430
442
  has :assignee, :class => User
431
443
 
432
- has_many :collaborators, :class => User, :inline => true, :extend => (Module.new do
444
+ has_many :collaborators, class: User, inline: true, extend: (Module.new do
433
445
  def to_param
434
446
  map(&:id)
435
447
  end
436
448
  end)
437
449
 
438
450
  has_many Audit
439
- has :metrics, :class => TicketMetric
451
+ has :metrics, class: TicketMetric
440
452
  has Group
441
453
  has Organization
442
454
  has Brand
443
- has :related, :class => TicketRelated
455
+ has :related, class: TicketRelated
444
456
 
445
- has Comment, :inline => true
457
+ has Comment, inline: true
446
458
  has_many Comment
447
459
 
448
- has :last_comment, :class => Comment, :inline => true
449
- has_many :last_comments, :class => Comment, :inline => true
460
+ has :last_comment, class: Comment, inline: true
461
+ has_many :last_comments, class: Comment, inline: true
450
462
 
451
- has_many Tag, :extend => Tag::Update, :inline => :create
463
+ has_many Tag, extend: Tag::Update, inline: :create
452
464
 
453
- has_many :incidents, :class => Ticket
465
+ has_many :incidents, class: Ticket
454
466
 
455
467
  # Gets a incremental export of tickets from the start_time until now.
456
468
  # @param [Client] client The {Client} object to be used
457
469
  # @param [Integer] start_time The start_time parameter
458
470
  # @return [Collection] Collection of {Ticket}
459
471
  def self.incremental_export(client, start_time)
460
- ZendeskAPI::Collection.new(client, self, :path => "incremental/tickets?start_time=#{start_time.to_i}")
472
+ ZendeskAPI::Collection.new(client, self, path: "incremental/tickets?start_time=#{start_time.to_i}")
461
473
  end
462
474
 
463
475
  # Imports a ticket through the imports/tickets endpoint using save!
@@ -466,7 +478,7 @@ module ZendeskAPI
466
478
  # @return [Ticket] Created object or nil
467
479
  def self.import!(client, attributes)
468
480
  new(client, attributes).tap do |ticket|
469
- ticket.save!(:path => "imports/tickets")
481
+ ticket.save!(path: "imports/tickets")
470
482
  end
471
483
  end
472
484
 
@@ -476,7 +488,7 @@ module ZendeskAPI
476
488
  # @return [Ticket] Created object or nil
477
489
  def self.import(client, attributes)
478
490
  ticket = new(client, attributes)
479
- return unless ticket.save(:path => "imports/tickets")
491
+ return unless ticket.save(path: "imports/tickets")
480
492
  ticket
481
493
  end
482
494
  end
@@ -510,9 +522,9 @@ module ZendeskAPI
510
522
  # @internal Optional columns
511
523
 
512
524
  has Group
513
- has :assignee, :class => User
514
- has :requester, :class => User
515
- has :submitter, :class => User
525
+ has :assignee, class: User
526
+ has :requester, class: User
527
+ has :submitter, class: User
516
528
  has Organization
517
529
 
518
530
  def self.model_key
@@ -599,6 +611,10 @@ module ZendeskAPI
599
611
  include Actions
600
612
 
601
613
  has :execution, :class => RuleExecution
614
+
615
+ def self.cbp_path_regexes
616
+ [/triggers$/, %r{triggers/active$}]
617
+ end
602
618
  end
603
619
 
604
620
  class Automation < Rule
@@ -648,6 +664,18 @@ module ZendeskAPI
648
664
 
649
665
  has User
650
666
  has Group
667
+
668
+ def self.cbp_path_regexes
669
+ [%r{groups/\d+/memberships$}]
670
+ end
671
+ end
672
+
673
+ class Group < Resource
674
+ has_many :memberships, class: GroupMembership, path: "memberships"
675
+
676
+ def self.cbp_path_regexes
677
+ [/groups$/, %r{groups/assignable$}]
678
+ end
651
679
  end
652
680
 
653
681
  class User < Resource
@@ -25,6 +25,10 @@ module ZendeskAPI
25
25
  (klass || Result).new(client, attributes)
26
26
  end
27
27
 
28
+ def self.cbp_path_regexes
29
+ []
30
+ end
31
+
28
32
  class Result < Data; end
29
33
 
30
34
  class << self
@@ -1,3 +1,3 @@
1
1
  module ZendeskAPI
2
- VERSION = "3.0.1"
2
+ VERSION = "3.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zendesk_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Davidovitz
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-07-14 00:00:00.000000000 Z
12
+ date: 2023-08-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -136,6 +136,7 @@ files:
136
136
  - lib/zendesk_api/middleware/response/parse_json.rb
137
137
  - lib/zendesk_api/middleware/response/raise_error.rb
138
138
  - lib/zendesk_api/middleware/response/sanitize_response.rb
139
+ - lib/zendesk_api/pagination.rb
139
140
  - lib/zendesk_api/resource.rb
140
141
  - lib/zendesk_api/resources.rb
141
142
  - lib/zendesk_api/search.rb
@@ -152,9 +153,9 @@ licenses:
152
153
  - Apache-2.0
153
154
  metadata:
154
155
  bug_tracker_uri: https://github.com/zendesk/zendesk_api_client_rb/issues
155
- changelog_uri: https://github.com/zendesk/zendesk_api_client_rb/blob/v3.0.1/CHANGELOG.md
156
- documentation_uri: https://www.rubydoc.info/gems/zendesk_api/3.0.1
157
- source_code_uri: https://github.com/zendesk/zendesk_api_client_rb/tree/v3.0.1
156
+ changelog_uri: https://github.com/zendesk/zendesk_api_client_rb/blob/v3.0.2/CHANGELOG.md
157
+ documentation_uri: https://www.rubydoc.info/gems/zendesk_api/3.0.2
158
+ source_code_uri: https://github.com/zendesk/zendesk_api_client_rb/tree/v3.0.2
158
159
  wiki_uri: https://github.com/zendesk/zendesk_api_client_rb/wiki
159
160
  post_install_message:
160
161
  rdoc_options: []