zendesk2 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
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" }