zendesk2 0.4.4 → 0.4.5

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -0
  3. data/lib/zendesk2/client/models/categories.rb +1 -1
  4. data/lib/zendesk2/client/models/forums.rb +1 -1
  5. data/lib/zendesk2/client/models/groups.rb +1 -1
  6. data/lib/zendesk2/client/models/membership.rb +1 -1
  7. data/lib/zendesk2/client/models/organization.rb +2 -0
  8. data/lib/zendesk2/client/models/organizations.rb +1 -1
  9. data/lib/zendesk2/client/models/ticket_audits.rb +1 -1
  10. data/lib/zendesk2/client/models/ticket_comments.rb +1 -1
  11. data/lib/zendesk2/client/models/ticket_metrics.rb +1 -1
  12. data/lib/zendesk2/client/models/tickets.rb +1 -1
  13. data/lib/zendesk2/client/models/topic_comments.rb +1 -1
  14. data/lib/zendesk2/client/models/topics.rb +1 -1
  15. data/lib/zendesk2/client/models/user_field.rb +59 -0
  16. data/lib/zendesk2/client/models/user_fields.rb +11 -0
  17. data/lib/zendesk2/client/models/user_identity.rb +1 -1
  18. data/lib/zendesk2/client/models/users.rb +1 -1
  19. data/lib/zendesk2/client/requests/create_membership.rb +10 -0
  20. data/lib/zendesk2/client/requests/create_user.rb +2 -12
  21. data/lib/zendesk2/client/requests/create_user_field.rb +44 -0
  22. data/lib/zendesk2/client/requests/destroy_user.rb +1 -0
  23. data/lib/zendesk2/client/requests/destroy_user_field.rb +27 -0
  24. data/lib/zendesk2/client/requests/get_category.rb +7 -14
  25. data/lib/zendesk2/client/requests/get_group.rb +6 -14
  26. data/lib/zendesk2/client/requests/get_membership.rb +6 -14
  27. data/lib/zendesk2/client/requests/get_organization.rb +7 -14
  28. data/lib/zendesk2/client/requests/get_organization_memberships.rb +1 -1
  29. data/lib/zendesk2/client/requests/get_ticket.rb +6 -14
  30. data/lib/zendesk2/client/requests/get_ticket_audit.rb +7 -18
  31. data/lib/zendesk2/client/requests/get_ticket_field.rb +6 -15
  32. data/lib/zendesk2/client/requests/get_ticket_fields.rb +1 -1
  33. data/lib/zendesk2/client/requests/get_ticket_metric.rb +6 -17
  34. data/lib/zendesk2/client/requests/get_topic_comment.rb +3 -6
  35. data/lib/zendesk2/client/requests/get_topic_comments.rb +1 -1
  36. data/lib/zendesk2/client/requests/get_user.rb +9 -13
  37. data/lib/zendesk2/client/requests/get_user_field.rb +25 -0
  38. data/lib/zendesk2/client/requests/get_user_fields.rb +18 -0
  39. data/lib/zendesk2/client/requests/get_user_identity.rb +6 -15
  40. data/lib/zendesk2/client/requests/get_user_memberships.rb +1 -1
  41. data/lib/zendesk2/client/requests/mark_membership_default.rb +2 -6
  42. data/lib/zendesk2/client/requests/mark_user_identity_primary.rb +3 -6
  43. data/lib/zendesk2/client/requests/update_group.rb +8 -14
  44. data/lib/zendesk2/client/requests/update_topic_comment.rb +2 -2
  45. data/lib/zendesk2/client/requests/update_user_field.rb +28 -0
  46. data/lib/zendesk2/client.rb +79 -15
  47. data/lib/zendesk2/collection.rb +1 -18
  48. data/lib/zendesk2/paged_collection.rb +100 -0
  49. data/lib/zendesk2/version.rb +1 -1
  50. data/lib/zendesk2.rb +9 -7
  51. data/spec/categories_spec.rb +6 -4
  52. data/spec/forums_spec.rb +7 -4
  53. data/spec/groups_spec.rb +6 -3
  54. data/spec/memberships_spec.rb +31 -5
  55. data/spec/organizations_spec.rb +6 -3
  56. data/spec/shared/zendesk_resource.rb +66 -48
  57. data/spec/ticket_fields_spec.rb +6 -3
  58. data/spec/tickets_spec.rb +6 -3
  59. data/spec/topic_comments_spec.rb +6 -5
  60. data/spec/topics_spec.rb +7 -5
  61. data/spec/user_fields_spec.rb +12 -0
  62. data/spec/user_identities_spec.rb +7 -7
  63. data/spec/users_spec.rb +7 -4
  64. metadata +12 -6
  65. data/spec/config_spec.rb +0 -17
  66. data/spec/shared/resource.rb +0 -66
@@ -3,8 +3,6 @@
3
3
  class Zendesk2::Collection < Cistern::Collection
4
4
  def self.inherited(klass)
5
5
  klass.send(:attribute, :count)
6
- klass.send(:attribute, :next_page_link, {:aliases => "next_page"})
7
- klass.send(:attribute, :previous_page_link, {:aliases => "previous_page"})
8
6
  klass.send(:extend, ClassMethods)
9
7
  end
10
8
 
@@ -13,21 +11,6 @@ class Zendesk2::Collection < Cistern::Collection
13
11
  def model_method; self.class.model_method; end
14
12
  def model_root; self.class.model_root; end
15
13
 
16
- def new_page
17
- page = self.clone
18
- %w[count next_page_link previous_page_link].each { |k| page.attributes.delete(k) }
19
- page.records = []
20
- page
21
- end
22
-
23
- def next_page
24
- new_page.all("url" => next_page_link) if next_page_link
25
- end
26
-
27
- def previous_page
28
- new_page.all("url" => previous_page_link) if previous_page_link
29
- end
30
-
31
14
  # Attempt creation of resource and explode if unsuccessful
32
15
  # @raise [Zendesk2::Error] if creation was unsuccessful
33
16
  # @return [Cistern::Model]
@@ -50,7 +33,7 @@ class Zendesk2::Collection < Cistern::Collection
50
33
  body = connection.send(collection_method, scoped_attributes).body
51
34
 
52
35
  self.load(body[collection_root])
53
- self.merge_attributes(Cistern::Hash.slice(body, "count", "next_page", "previous_page"))
36
+ self.merge_attributes(Cistern::Hash.slice(body, "count"))
54
37
  self
55
38
  end
56
39
 
@@ -0,0 +1,100 @@
1
+ # @abstract Subclass and set #{collection_method}, #{collection_root}, #{model_method}, #{model_root} and #{model}
2
+ # adds {#create!} method to {Cistern::Collection}.
3
+ class Zendesk2::PagedCollection < Zendesk2::Collection
4
+ def self.inherited(klass)
5
+ klass.send(:attribute, :count)
6
+ klass.send(:attribute, :next_page_link, {:aliases => "next_page"})
7
+ klass.send(:attribute, :previous_page_link, {:aliases => "previous_page"})
8
+ klass.send(:extend, ClassMethods)
9
+ end
10
+
11
+ def collection_method; self.class.collection_method; end
12
+ def collection_root; self.class.collection_root; end
13
+ def model_method; self.class.model_method; end
14
+ def model_root; self.class.model_root; end
15
+
16
+ def new_page
17
+ page = self.clone
18
+ %w[count next_page_link previous_page_link].each { |k| page.attributes.delete(k) }
19
+ page.records = []
20
+ page
21
+ end
22
+
23
+ def next_page
24
+ new_page.all("url" => next_page_link) if next_page_link
25
+ end
26
+
27
+ def previous_page
28
+ new_page.all("url" => previous_page_link) if previous_page_link
29
+ end
30
+
31
+ # Attempt creation of resource and explode if unsuccessful
32
+ # @raise [Zendesk2::Error] if creation was unsuccessful
33
+ # @return [Cistern::Model]
34
+ def create!(attributes={})
35
+ model = self.new(attributes.merge(Zendesk2.stringify_keys(self.attributes)))
36
+ model.save!
37
+ end
38
+
39
+ # Quietly attempt creation of resource. Check {#new_record?} and {#errors} for success
40
+ # @see {#create!} to raise an exception on failure
41
+ # @return [Cistern::Model, FalseClass]
42
+ def create(attributes={})
43
+ model = self.new(attributes.merge(Zendesk2.stringify_keys(self.attributes)))
44
+ model.save
45
+ end
46
+
47
+ # Fetch a collection of resources
48
+ def all(params={})
49
+ scoped_attributes = self.class.scopes.inject({}){|r,k| r.merge(k.to_s => send(k))}.merge(params)
50
+ body = connection.send(collection_method, scoped_attributes).body
51
+
52
+ self.load(body[collection_root])
53
+ self.merge_attributes(Cistern::Hash.slice(body, "count", "next_page", "previous_page"))
54
+ self
55
+ end
56
+
57
+ # Fetch a single of resource
58
+ # @overload get!(identity)
59
+ # fetch a un-namespaced specific record or a namespaced record under the current {#scopes}
60
+ # @param [Integer] identity identity of the record
61
+ # @overload get!(scope)
62
+ # directly fetch a namespaced record
63
+ # @param [Hash] scope parameters to fetch record
64
+ # @example Fetch a record without contextual scoping
65
+ # self.identities.all("user_id" => 2, "id" => 4) # context defined directly
66
+ # @example Fetch a record with contextual scoping
67
+ # self.identities("user_id" => 2).get(4) # context defined in collection
68
+ # user.identities.get(4) # context defined by encapsulating model
69
+ # @raise [Zendesk2::Error] if the record cannot be found or other request error
70
+ # @return [Zendesk2::Model] fetched resource corresponding to value of {Zendesk2::Collection#model}
71
+ def get!(identity_or_hash)
72
+ scoped_attributes = self.class.scopes.inject({}){|r,k| r.merge(k.to_s => send(k))}
73
+ if identity_or_hash.is_a?(Hash)
74
+ scoped_attributes.merge!(identity_or_hash)
75
+ else scoped_attributes.merge!("id" => identity_or_hash)
76
+ end
77
+
78
+ if data = self.connection.send(model_method, scoped_attributes).body[self.model_root]
79
+ new(data)
80
+ end
81
+ end
82
+
83
+ # Quiet version of {#get!}
84
+ # @see #get!
85
+ # @return [Zendesk2::Model] Fetched model when successful
86
+ # @return [NilClass] return nothing if record cannot be found
87
+ def get(*args)
88
+ get!(*args)
89
+ rescue Zendesk2::Error
90
+ nil
91
+ end
92
+
93
+ module ClassMethods
94
+ attr_accessor :collection_method, :collection_root, :model_method, :model_root
95
+
96
+ def scopes
97
+ @scopes ||= []
98
+ end
99
+ end
100
+ end
@@ -1,3 +1,3 @@
1
1
  module Zendesk2
2
- VERSION = "0.4.4"
2
+ VERSION = "0.4.5"
3
3
  end
data/lib/zendesk2.rb CHANGED
@@ -14,13 +14,15 @@ require 'time'
14
14
  require 'yaml'
15
15
 
16
16
  module Zendesk2
17
- autoload :Attributes, 'zendesk2/attributes'
18
- autoload :Error, 'zendesk2/error'
19
- autoload :Client, 'zendesk2/client'
20
- autoload :Searchable, 'zendesk2/searchable'
21
- autoload :Logger, 'zendesk2/logger'
22
- autoload :Model, 'zendesk2/model'
23
- autoload :Collection, 'zendesk2/collection'
17
+ require 'zendesk2/attributes'
18
+ require 'zendesk2/attributes'
19
+ require 'zendesk2/error'
20
+ require 'zendesk2/client'
21
+ require 'zendesk2/searchable'
22
+ require 'zendesk2/logger'
23
+ require 'zendesk2/model'
24
+ require 'zendesk2/collection'
25
+ require 'zendesk2/paged_collection'
24
26
 
25
27
  def self.defaults
26
28
  @defaults ||= if File.exists?(File.expand_path("~/.zendesk2"))
@@ -2,8 +2,10 @@ require 'spec_helper'
2
2
 
3
3
  describe "categories" do
4
4
  let(:client) { create_client }
5
- it_should_behave_like "a resource",
6
- :categories,
7
- lambda { {name: Zendesk2.uuid} },
8
- lambda { {name: Zendesk2.uuid} }
5
+
6
+ include_examples "zendesk resource", {
7
+ :collection => lambda { client.categories },
8
+ :create_params => lambda { { name: Zendesk2.uuid } },
9
+ :update_params => lambda { { name: Zendesk2.uuid } },
10
+ }
9
11
  end
data/spec/forums_spec.rb CHANGED
@@ -2,8 +2,11 @@ require 'spec_helper'
2
2
 
3
3
  describe "forums" do
4
4
  let(:client) { create_client }
5
- it_should_behave_like "a resource",
6
- :forums,
7
- lambda { {name: Zendesk2.uuid} },
8
- lambda { {name: Zendesk2.uuid} }
5
+
6
+ include_examples "zendesk resource", {
7
+ :collection => lambda { client.forums },
8
+ :create_params => lambda { { name: Zendesk2.uuid } },
9
+ :update_params => lambda { { name: Zendesk2.uuid } },
10
+ :delayed_destroy => true,
11
+ }
9
12
  end
data/spec/groups_spec.rb CHANGED
@@ -2,9 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe "groups" do
4
4
  let(:client) { create_client }
5
- it_should_behave_like "a resource", :groups,
6
- lambda { {name: Zendesk2.uuid} },
7
- lambda { {name: Zendesk2.uuid} }
5
+
6
+ include_examples "zendesk resource", {
7
+ :collection => lambda { client.groups },
8
+ :create_params => lambda { { name: Zendesk2.uuid } },
9
+ :update_params => lambda { { name: Zendesk2.uuid } },
10
+ }
8
11
 
9
12
  it "should list assignable groups" do
10
13
  client.groups.create(name: Zendesk2.uuid) # assignable by default
@@ -6,11 +6,11 @@ describe "memberships" do
6
6
  let(:organization) { client.organizations.create!(name: Zendesk2.uuid) }
7
7
 
8
8
  include_examples "zendesk resource", {
9
- :params => lambda { {organization_id: organization.id, user_id: user.id} },
10
- :collection => lambda { client.memberships(user: user) },
11
- :paged => false,
12
- :update => false,
13
- :search => false,
9
+ :create_params => lambda { {organization_id: organization.id, user_id: user.id} },
10
+ :collection => lambda { client.memberships(user: user) },
11
+ :paged => false,
12
+ :update => false,
13
+ :search => false,
14
14
  }
15
15
 
16
16
  it "should be marked as default" do
@@ -50,4 +50,30 @@ describe "memberships" do
50
50
  user.memberships.to_a.should == [user_membership]
51
51
  another_user.memberships.size.should == 2
52
52
  end
53
+
54
+ describe "create_membership" do
55
+ it "should error when organization does not exist" do
56
+ expect {
57
+ client.create_membership("user_id" => user.identity, "organization_id" => 99)
58
+ }.to raise_exception(Zendesk2::Error, /RecordInvalid/)
59
+ end
60
+
61
+ it "should error when missing parameters" do
62
+ expect { client.create_membership({}) }.to raise_exception(ArgumentError, "missing parameters: user_id, organization_id")
63
+ end
64
+
65
+ it "should error when creating a duplicate membership" do
66
+ client.create_membership("user_id" => user.identity, "organization_id" => organization.identity)
67
+
68
+ expect {
69
+ client.create_membership("user_id" => user.identity, "organization_id" => organization.identity)
70
+ }.to raise_exception(Zendesk2::Error, /RecordInvalid/)
71
+ end
72
+
73
+ it "should error when user does not exist" do
74
+ expect {
75
+ client.create_membership("user_id" => 99, "organization_id" => organization.identity)
76
+ }.to raise_exception(Zendesk2::Error, /RecordNotFound/)
77
+ end
78
+ end
53
79
  end
@@ -2,9 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe "organizations" do
4
4
  let(:client) { create_client }
5
- it_should_behave_like "a resource", :organizations,
6
- lambda { {name: Zendesk2.uuid} },
7
- lambda { {name: Zendesk2.uuid} }
5
+
6
+ include_examples "zendesk resource", {
7
+ :collection => lambda { client.organizations },
8
+ :create_params => lambda { { name: Zendesk2.uuid } },
9
+ :update_params => lambda { { name: Zendesk2.uuid } },
10
+ }
8
11
 
9
12
  describe "with an organization" do
10
13
  let(:organization) { client.organizations.create(name: Zendesk2.uuid) }
@@ -1,64 +1,82 @@
1
1
  shared_examples "zendesk resource" do |options={}|
2
- let(:collection) { instance_exec(&options[:collection]) }
3
- let(:params) { instance_exec(&options[:params]) || {} }
4
- let(:update_params) { instance_exec(&options[:update_params]) }
5
- let(:fetch_params) { options[:fetch_params] || lambda { |r| r.identity } }
2
+ context "as a resource" do
3
+ let!(:collection) { instance_exec(&options[:collection]) }
4
+ let(:create_params) { instance_exec(&options[:create_params]) || {} }
5
+ let(:update_params) { instance_exec(&options[:update_params]) }
6
+ let(:fetch_params) { options[:fetch_params] || lambda { |r| r.identity } }
6
7
 
7
- it "should be created" do
8
- record = collection.create!(params)
9
- record.identity.should_not be_nil
10
- end
8
+ let(:record) { @record }
9
+ after(:each) { @record && @record.destroy }
11
10
 
12
- it "should be fetched" do
13
- record = collection.create!(params)
14
- collection.get!(fetch_params.call(record)).should == record
15
- end
11
+ it "should be created" do
12
+ @record = collection.create!(create_params)
13
+ record.identity.should_not be_nil
14
+ end
16
15
 
17
- if options.fetch(:paged, true)
18
- context "paging" do
19
- before(:each) do
20
- 3.times.each { collection.create!(instance_exec(&_params)) }
21
- end
16
+ it "should be fetched" do
17
+ @record = collection.create!(create_params)
18
+ collection.get!(fetch_params.call(record)).should == record
19
+ end
22
20
 
23
- it "should retrieve first page" do
24
- collection.all("per_page" => "1").size.should == 1
25
- end
21
+ if options.fetch(:paged, true)
22
+ context "paging" do
23
+ before(:each) do
24
+ @resources = 3.times.map { collection.create!(instance_exec(&options[:create_params])) }
25
+ end
26
26
 
27
- it "should retrieve next page" do
28
- first_page = collection.all("per_page" => 1)
29
- second_page = collection.all("per_page" => 1).next_page
30
- second_page.should_not == first_page
31
- end
27
+ after(:each) { @resources.each { |r| r.destroy } }
28
+
29
+ it "should retrieve first page" do
30
+ collection.all("per_page" => "1").size.should == 1
31
+ end
32
+
33
+ it "should retrieve next page" do
34
+ first_page = collection.all("per_page" => 1)
35
+ second_page = collection.all("per_page" => 1).next_page
36
+ second_page.should_not == first_page
37
+ end
32
38
 
33
- it "should retreive previous page" do
34
- first_page = collection.all("per_page" => "1")
35
- previous_to_second_page = collection.all("per_page" => 1).next_page.previous_page
36
- previous_to_second_page.should == first_page
39
+ it "should retreive previous page" do
40
+ first_page = collection.all("per_page" => "1")
41
+ previous_to_second_page = collection.all("per_page" => 1).next_page.previous_page
42
+ previous_to_second_page.should == first_page
43
+ end
44
+ end
45
+ else
46
+ context "paging" do
47
+ it "should not be present" do
48
+ collection.class.attributes.should_not have_key(:next_page_link)
49
+ collection.class.attributes.should_not have_key(:previous_page_link)
50
+ collection.class.attributes.should have_key(:count)
51
+ end
37
52
  end
38
53
  end
39
- end
40
54
 
41
- if options.fetch(:update, true)
42
- it "should be updated" do
43
- record = collection.create!(params)
44
- record.merge_attributes(update_params)
45
- record.save
46
- update_params.each {|k,v| record.send(k).should == v}
55
+ if options.fetch(:update, true)
56
+ it "should be updated" do
57
+ @record = collection.create!(create_params)
58
+ record.merge_attributes(update_params)
59
+ record.save
60
+ update_params.each {|k,v| record.send(k).should == v}
61
+ end
47
62
  end
48
- end
49
63
 
50
- it "should be destroyed" do
51
- record = collection.create!(params)
52
- record.identity.should_not be_nil
53
- record.destroy
54
- record.should be_destroyed
55
- end
64
+ it "should be destroyed" do
65
+ @record = collection.create!(create_params)
66
+ record.identity.should_not be_nil
67
+ record.destroy
56
68
 
57
- if options.fetch(:search, true) && Zendesk2::Client.mocking?
58
- # Search index takes 2-3 minutes according to the docs
59
- it "should search" do
60
- record = collection.create!(params)
61
- collection.search(params).should include(record)
69
+ if !options.fetch(:delayed_destroy, false) && !Zendesk2::Client.mocking?
70
+ record.should be_destroyed
71
+ end
72
+ end
73
+
74
+ if options.fetch(:search, true) && Zendesk2::Client.mocking?
75
+ # Search index takes 2-3 minutes according to the docs
76
+ it "should search" do
77
+ @record = collection.create!(create_params)
78
+ collection.search(create_params).should include(record)
79
+ end
62
80
  end
63
81
  end
64
82
  end
@@ -3,7 +3,10 @@ require 'spec_helper'
3
3
  describe "ticket_fields" do
4
4
  let(:client) { create_client }
5
5
 
6
- it_should_behave_like "a resource", :ticket_fields,
7
- lambda { { title: Zendesk2.uuid, type: "text" } },
8
- lambda { { title: Zendesk2.uuid } }
6
+ include_examples "zendesk resource", {
7
+ :collection => lambda { client.ticket_fields },
8
+ :create_params => lambda { { title: Zendesk2.uuid, type: "text" } },
9
+ :update_params => lambda { { title: Zendesk2.uuid } },
10
+ :paged => false,
11
+ }
9
12
  end
data/spec/tickets_spec.rb CHANGED
@@ -2,9 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe "tickets" do
4
4
  let(:client) { create_client }
5
- it_should_behave_like "a resource", :tickets,
6
- lambda { {subject: Zendesk2.uuid, description: Zendesk2.uuid} },
7
- lambda { {subject: Zendesk2.uuid} }
5
+
6
+ include_examples "zendesk resource", {
7
+ :collection => lambda { client.tickets },
8
+ :create_params => lambda { {subject: Zendesk2.uuid, description: Zendesk2.uuid} },
9
+ :update_params => lambda { {subject: Zendesk2.uuid} },
10
+ }
8
11
 
9
12
  describe "when creating a ticket" do
10
13
  let!(:requester_email) { "#{Zendesk2.uuid}@example.org" }