zendesk2 0.1.2 → 0.1.3

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 (37) hide show
  1. data/.gitignore +1 -0
  2. data/Guardfile +1 -0
  3. data/README.md +5 -3
  4. data/TODO.md +3 -1
  5. data/lib/zendesk2/client/models/categories.rb +5 -6
  6. data/lib/zendesk2/client/models/category.rb +18 -8
  7. data/lib/zendesk2/client/models/forums.rb +5 -6
  8. data/lib/zendesk2/client/models/group.rb +48 -0
  9. data/lib/zendesk2/client/models/groups.rb +17 -0
  10. data/lib/zendesk2/client/models/organizations.rb +5 -6
  11. data/lib/zendesk2/client/models/ticket_audits.rb +0 -1
  12. data/lib/zendesk2/client/models/tickets.rb +5 -6
  13. data/lib/zendesk2/client/models/topic_comment.rb +1 -1
  14. data/lib/zendesk2/client/models/topic_comments.rb +1 -16
  15. data/lib/zendesk2/client/models/topics.rb +5 -6
  16. data/lib/zendesk2/client/models/user.rb +1 -0
  17. data/lib/zendesk2/client/models/user_identities.rb +1 -16
  18. data/lib/zendesk2/client/models/user_identity.rb +1 -1
  19. data/lib/zendesk2/client/models/users.rb +0 -1
  20. data/lib/zendesk2/client/requests/create_group.rb +33 -0
  21. data/lib/zendesk2/client/requests/destroy_group.rb +28 -0
  22. data/lib/zendesk2/client/requests/get_assignable_groups.rb +20 -0
  23. data/lib/zendesk2/client/requests/get_group.rb +34 -0
  24. data/lib/zendesk2/client/requests/get_groups.rb +18 -0
  25. data/lib/zendesk2/client/requests/update_group.rb +35 -0
  26. data/lib/zendesk2/client.rb +15 -3
  27. data/lib/zendesk2/collection.rb +76 -1
  28. data/lib/zendesk2/logger.rb +3 -8
  29. data/lib/zendesk2/version.rb +1 -1
  30. data/lib/zendesk2.rb +1 -1
  31. data/spec/groups_spec.rb +14 -0
  32. data/spec/shared/resource.rb +1 -1
  33. data/spec/topic_comments_spec.rb +2 -3
  34. data/spec/user_identities_spec.rb +1 -1
  35. data/zendesk2.gemspec +1 -1
  36. metadata +14 -5
  37. data/lib/zendesk2/paged_collection.rb +0 -41
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .rspec
19
+ doc/
data/Guardfile CHANGED
@@ -7,4 +7,5 @@ guard 'rspec' do
7
7
  watch(%r{^spec/.+_spec\.rb$})
8
8
  watch(%r{^lib/(.+)\.rb$}) { "spec" }
9
9
  watch('spec/spec_helper.rb') { "spec" }
10
+ watch(%r{^spec/(support|matchers|shared)/(.+)\.rb$}) { "spec" }
10
11
  end
data/README.md CHANGED
@@ -28,11 +28,12 @@ Default credentials will be read in from `~/.zendesk2` file in YAML format.
28
28
  :subdomain: zendeskdev
29
29
  :username: zendeskedge@example.com
30
30
  :password: wickedsecurepassword
31
+ :token: reallylongrandomstringprovidedbyzendesk
31
32
  ```
32
33
 
33
34
  ### Creating the client
34
35
 
35
- Either the absolute url or the subdomain is required. Username and password is always required.
36
+ Either the absolute url or the subdomain is required. Username and either password or token are always required.
36
37
 
37
38
  ```ruby
38
39
  Zendesk2::Client.new(subdomain: "engineyard", username: "orchestra", password: "gwoo")
@@ -42,8 +43,8 @@ Zendesk2::Client.new(subdomain: "engineyard", username: "orchestra", password: "
42
43
  or
43
44
 
44
45
  ```ruby
45
- Zendesk2::Client.new(url: "http://support.cloud.engineyard.com", username: "mate", password: "bambilla")
46
- => #<Zendesk2::Client::Real:0x007fd1bae486b0 @url="http://support.cloud.engineyard.com", @username="mate", @password="bambilla", …>
46
+ Zendesk2::Client.new(url: "http://support.cloud.engineyard.com", username: "mate", token: "asdfghjkl1qwertyuiop5zxcvbnm3")
47
+ => #<Zendesk2::Client::Real:0x007fd1bae486b0 @url="http://support.cloud.engineyard.com", @username="mate", @token="asdfghjkl1qwertyuiop5zxcvbnm3", …>
47
48
  ```
48
49
 
49
50
  ### Resources
@@ -55,6 +56,7 @@ Currently support resources
55
56
  * Audit Events
56
57
  * Categories
57
58
  * Forums
59
+ * Groups
58
60
  * Organization
59
61
  * Ticket Audits
60
62
  * Tickets
data/TODO.md CHANGED
@@ -1,2 +1,4 @@
1
1
  # yarddoc
2
- * change attribute enumerations to use yarddoc format
2
+ * forum
3
+ * organization
4
+ * topic
@@ -1,12 +1,11 @@
1
1
  class Zendesk2::Client::Categories < Zendesk2::Collection
2
- include Zendesk2::PagedCollection
3
2
  include Zendesk2::Searchable
4
3
 
5
4
  model Zendesk2::Client::Category
6
5
 
7
- self.collection_method= :get_categories
8
- self.collection_root= "categories"
9
- self.model_method= :get_category
10
- self.model_root= "category"
11
- self.search_type= "category"
6
+ self.collection_method = :get_categories
7
+ self.collection_root = "categories"
8
+ self.model_method = :get_category
9
+ self.model_root = "category"
10
+ self.search_type = "category"
12
11
  end
@@ -1,13 +1,21 @@
1
1
  class Zendesk2::Client::Category < Zendesk2::Model
2
2
  PARAMS = %w[id name description position]
3
3
 
4
- identity :id, type: :integer # ro[yes] mandatory[no] Automatically assigned during creation
5
- attribute :url, type: :string # ro[yes] mandatory[no] The API url of this category
6
- attribute :name, type: :string # ro[no] mandatory[yes] The name of the category
7
- attribute :description, type: :string # ro[no] mandatory[no] The description of the category
8
- attribute :position, type: :integer # ro[no] mandatory[no] The position of this category relative to other categories
9
- attribute :created_at, type: :date # ro[yes] mandatory[no] The time the category was created
10
- attribute :updated_at, type: :date # ro[yes] mandatory[no] The time of the last update of the category
4
+ # @return [Integer] Automatically assigned during creation
5
+ identity :id, type: :integer
6
+
7
+ # @return [Time] The time the category was created
8
+ attribute :created_at, type: :time
9
+ # @return [String] The description of the category
10
+ attribute :description, type: :string
11
+ # @return [String] The name of the category
12
+ attribute :name, type: :string
13
+ # @return [Integer] The position of this category relative to other categories
14
+ attribute :position, type: :integer
15
+ # @return [Time] The time of the last update of the category
16
+ attribute :updated_at, type: :time
17
+ # @return [String] The API url of this category
18
+ attribute :url, type: :string
11
19
 
12
20
  def destroy
13
21
  requires :id
@@ -22,9 +30,11 @@ class Zendesk2::Client::Category < Zendesk2::Model
22
30
  def save!
23
31
  data = if new_record?
24
32
  requires :name
33
+
25
34
  connection.create_category(params).body["category"]
26
35
  else
27
- requires :id
36
+ requires :identity
37
+
28
38
  connection.update_category(params).body["category"]
29
39
  end
30
40
  merge_attributes(data)
@@ -1,12 +1,11 @@
1
1
  class Zendesk2::Client::Forums < Zendesk2::Collection
2
- include Zendesk2::PagedCollection
3
2
  include Zendesk2::Searchable
4
3
 
5
4
  model Zendesk2::Client::Forum
6
5
 
7
- self.collection_method= :get_forums
8
- self.collection_root= "forums"
9
- self.model_method= :get_forum
10
- self.model_root= "forum"
11
- self.search_type= "forum"
6
+ self.collection_method = :get_forums
7
+ self.collection_root = "forums"
8
+ self.model_method = :get_forum
9
+ self.model_root = "forum"
10
+ self.search_type = "forum"
12
11
  end
@@ -0,0 +1,48 @@
1
+ class Zendesk2::Client::Group < Zendesk2::Model
2
+ extend Zendesk2::Attributes
3
+
4
+ PARAMS = %w[name]
5
+
6
+ # @return [Integer] Automatically assigned when creating groups
7
+ identity :id, type: :integer
8
+
9
+ # @return [Time] The time the group was created
10
+ attribute :created_at, type: :time
11
+ # @return [Boolean] Deleted groups get marked as such
12
+ attribute :deleted, type: :boolean
13
+ # @return [String] The name of the group
14
+ attribute :name, type: :string
15
+ # @return [Time] The time of the last update of the group
16
+ attribute :updated_at, type: :time
17
+ # @return [String] The API url of this group
18
+ attribute :url, type: :string
19
+
20
+ def save!
21
+ data = if new_record?
22
+ requires :name
23
+ connection.create_group(params).body["group"]
24
+ else
25
+ requires :identity
26
+ connection.update_group(params.merge("id" => self.identity)).body["group"]
27
+ end
28
+
29
+ merge_attributes(data)
30
+ end
31
+
32
+ def destroy
33
+ requires :identity
34
+
35
+ connection.destroy_group("id" => self.identity)
36
+ self.deleted = true
37
+ end
38
+
39
+ def destroyed?
40
+ self.deleted
41
+ end
42
+
43
+ private
44
+
45
+ def params
46
+ Cistern::Hash.slice(Zendesk2.stringify_keys(attributes), *PARAMS)
47
+ end
48
+ end
@@ -0,0 +1,17 @@
1
+ class Zendesk2::Client::Groups < Zendesk2::Collection
2
+ include Zendesk2::Searchable
3
+
4
+ model Zendesk2::Client::Group
5
+
6
+ self.collection_method = :get_groups
7
+ self.collection_root = "groups"
8
+ self.model_method = :get_group
9
+ self.model_root = "group"
10
+ self.search_type = "group"
11
+
12
+ def assignable
13
+ data = self.connection.get_assignable_groups.body
14
+ collection = self.connection.groups.load(data["groups"])
15
+ collection.merge_attributes(Cistern::Hash.slice(data, "next_page", "previous_page", "count"))
16
+ end
17
+ end
@@ -1,12 +1,11 @@
1
1
  class Zendesk2::Client::Organizations < Zendesk2::Collection
2
- include Zendesk2::PagedCollection
3
2
  include Zendesk2::Searchable
4
3
 
5
4
  model Zendesk2::Client::Organization
6
5
 
7
- self.collection_method= :get_organizations
8
- self.collection_root= "organizations"
9
- self.model_method= :get_organization
10
- self.model_root= "organization"
11
- self.search_type= "organization"
6
+ self.collection_method = :get_organizations
7
+ self.collection_root = "organizations"
8
+ self.model_method = :get_organization
9
+ self.model_root = "organization"
10
+ self.search_type = "organization"
12
11
  end
@@ -1,5 +1,4 @@
1
1
  class Zendesk2::Client::TicketAudits < Zendesk2::Collection
2
- include Zendesk2::PagedCollection
3
2
 
4
3
  model Zendesk2::Client::TicketAudit
5
4
 
@@ -1,12 +1,11 @@
1
1
  class Zendesk2::Client::Tickets < Zendesk2::Collection
2
- include Zendesk2::PagedCollection
3
2
  include Zendesk2::Searchable
4
3
 
5
4
  model Zendesk2::Client::Ticket
6
5
 
7
- self.collection_method= :get_tickets
8
- self.collection_root= "tickets"
9
- self.model_method= :get_ticket
10
- self.model_root= "ticket"
11
- self.search_type= "ticket"
6
+ self.collection_method = :get_tickets
7
+ self.collection_root = "tickets"
8
+ self.model_method = :get_ticket
9
+ self.model_root = "ticket"
10
+ self.search_type = "ticket"
12
11
  end
@@ -46,7 +46,7 @@ class Zendesk2::Client::TopicComment < Zendesk2::Model
46
46
  def reload
47
47
  requires :identity
48
48
 
49
- if data = collection.get(topic_id, identity)
49
+ if data = self.connection.topic_comments("topic_id" => topic_id).get(identity)
50
50
  new_attributes = data.attributes
51
51
  merge_attributes(new_attributes)
52
52
  self
@@ -1,5 +1,4 @@
1
1
  class Zendesk2::Client::TopicComments < Zendesk2::Collection
2
- include Zendesk2::PagedCollection
3
2
  include Zendesk2::Searchable
4
3
 
5
4
  model Zendesk2::Client::TopicComment
@@ -12,19 +11,5 @@ class Zendesk2::Client::TopicComments < Zendesk2::Collection
12
11
  self.model_root = "topic_comment"
13
12
  self.search_type = "topic_comment"
14
13
 
15
- def all(params={})
16
- body = connection.send(collection_method, params.merge("topic_id" => self.topic_id)).body
17
-
18
- collection = self.clone.load(body[collection_root])
19
- collection.merge_attributes(Cistern::Hash.slice(body, "count", "next_page", "previous_page"))
20
- collection
21
- end
22
-
23
- def get(topic_id, topic_comment_id)
24
- if data = self.connection.send(model_method, {"topic_id" => topic_id, "id" => topic_comment_id}).body[self.model_root]
25
- new(data)
26
- end
27
- rescue Zendesk2::Error
28
- nil
29
- end
14
+ scopes << :topic_id
30
15
  end
@@ -1,12 +1,11 @@
1
1
  class Zendesk2::Client::Topics < Zendesk2::Collection
2
- include Zendesk2::PagedCollection
3
2
  include Zendesk2::Searchable
4
3
 
5
4
  model Zendesk2::Client::Topic
6
5
 
7
- self.collection_method= :get_topics
8
- self.collection_root= "topics"
9
- self.model_method= :get_topic
10
- self.model_root= "topic"
11
- self.search_type= "topic"
6
+ self.collection_method = :get_topics
7
+ self.collection_root = "topics"
8
+ self.model_method = :get_topic
9
+ self.model_root = "topic"
10
+ self.search_type = "topic"
12
11
  end
@@ -95,6 +95,7 @@ class Zendesk2::Client::User < Zendesk2::Model
95
95
  end
96
96
 
97
97
  # @param [Time] timestamp time sent with intial handshake
98
+ # @option options [String] :return_to (nil) url to return to after handshake
98
99
  # @return [String] remote authentication login url
99
100
  # @see http://www.zendesk.com/support/api/remote-authentication
100
101
  def login_url(timestamp, options={})
@@ -1,5 +1,4 @@
1
1
  class Zendesk2::Client::UserIdentities < Zendesk2::Collection
2
- include Zendesk2::PagedCollection
3
2
  include Zendesk2::Searchable
4
3
 
5
4
  model Zendesk2::Client::UserIdentity
@@ -12,19 +11,5 @@ class Zendesk2::Client::UserIdentities < Zendesk2::Collection
12
11
  self.model_root = "identity"
13
12
  self.search_type = "identity"
14
13
 
15
- def all(params={})
16
- body = connection.send(collection_method, params.merge("user_id" => self.user_id)).body
17
-
18
- collection = self.clone.load(body[collection_root])
19
- collection.merge_attributes(Cistern::Hash.slice(body, "count", "next_page", "previous_page"))
20
- collection
21
- end
22
-
23
- def get(user_id, user_identity_id)
24
- if data = self.connection.send(model_method, {"user_id" => user_id, "id" => user_identity_id}).body[self.model_root]
25
- new(data)
26
- end
27
- rescue Zendesk2::Error
28
- nil
29
- end
14
+ scopes << :user_id
30
15
  end
@@ -46,7 +46,7 @@ class Zendesk2::Client::UserIdentity < Zendesk2::Model
46
46
  def reload
47
47
  requires :identity
48
48
 
49
- if data = collection.get(user_id, identity)
49
+ if data = self.connection.user_identities("user_id" => user_id).get(identity)
50
50
  new_attributes = data.attributes
51
51
  merge_attributes(new_attributes)
52
52
  self
@@ -1,5 +1,4 @@
1
1
  class Zendesk2::Client::Users < Zendesk2::Collection
2
- include Zendesk2::PagedCollection
3
2
  include Zendesk2::Searchable
4
3
 
5
4
  model Zendesk2::Client::User
@@ -0,0 +1,33 @@
1
+ class Zendesk2::Client
2
+ class Real
3
+ def create_group(params={})
4
+ request(
5
+ :body => {"group" => params},
6
+ :method => :post,
7
+ :path => "/groups.json",
8
+ )
9
+ end
10
+ end # Real
11
+
12
+ class Mock
13
+ def create_group(params={})
14
+ identity = self.class.new_id
15
+
16
+ record = {
17
+ "id" => identity,
18
+ "url" => url_for("/groups/#{identity}.json"),
19
+ "created_at" => Time.now.iso8601,
20
+ "updated_at" => Time.now.iso8601,
21
+ "deleted" => false,
22
+ }.merge(params)
23
+
24
+ self.data[:groups][identity] = record
25
+
26
+ response(
27
+ :method => :post,
28
+ :body => {"group" => record},
29
+ :path => "/groups.json"
30
+ )
31
+ end
32
+ end # Mock
33
+ end # Zendesk2::Client
@@ -0,0 +1,28 @@
1
+ class Zendesk2::Client
2
+ class Real
3
+ def destroy_group(params={})
4
+ id = params["id"]
5
+
6
+ request(
7
+ :method => :delete,
8
+ :path => "/groups/#{id}.json"
9
+ )
10
+ end
11
+ end
12
+
13
+ class Mock
14
+ def destroy_group(params={})
15
+ id = params["id"]
16
+ body = self.data[:groups][id]
17
+ body["deleted"] = true
18
+
19
+ response(
20
+ :method => :delete,
21
+ :path => "/groups/#{id}.json",
22
+ :body => {
23
+ "group" => body,
24
+ },
25
+ )
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ class Zendesk2::Client
2
+ class Real
3
+ def get_assignable_groups(params={})
4
+ page_params = Zendesk2.paging_parameters(params)
5
+
6
+ request(
7
+ :params => page_params,
8
+ :method => :get,
9
+ :path => "/groups/assignable.json",
10
+ )
11
+ end
12
+ end
13
+ class Mock
14
+ def get_assignable_groups(params={})
15
+ filter = lambda { |group| group.select{|g| !g['deleted'] } }
16
+
17
+ page(params, :groups, "/groups/assignable.json", "groups", filter: filter)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,34 @@
1
+ class Zendesk2::Client
2
+ class Real
3
+ def get_group(params={})
4
+ id = params["id"]
5
+
6
+ request(
7
+ :method => :get,
8
+ :path => "/groups/#{id}.json"
9
+ )
10
+ end
11
+ end # Real
12
+
13
+ class Mock
14
+ def get_group(params={})
15
+ id = params["id"]
16
+ path = "/groups/#{id}.json"
17
+
18
+ if body = self.data[:groups][id]
19
+ response(
20
+ :path => path,
21
+ :body => {
22
+ "group" => body
23
+ },
24
+ )
25
+ else
26
+ response(
27
+ :path => path,
28
+ :status => 404,
29
+ :body => {"error" => "RecordNotFound", "description" => "Not found"},
30
+ )
31
+ end
32
+ end
33
+ end # Mock
34
+ end
@@ -0,0 +1,18 @@
1
+ class Zendesk2::Client
2
+ class Real
3
+ def get_groups(params={})
4
+ page_params = Zendesk2.paging_parameters(params)
5
+
6
+ request(
7
+ :params => page_params,
8
+ :method => :get,
9
+ :path => "/groups.json",
10
+ )
11
+ end
12
+ end
13
+ class Mock
14
+ def get_groups(params={})
15
+ page(params, :groups, "/groups.json", "groups")
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ class Zendesk2::Client
2
+ class Real
3
+ def update_group(params={})
4
+ id = params.delete("id")
5
+ path = "/groups/#{id}.json"
6
+
7
+ request(
8
+ :method => :put,
9
+ :path => path,
10
+ :body => {
11
+ "group" => params
12
+ },
13
+ )
14
+ end
15
+ end
16
+ class Mock
17
+ def update_group(params={})
18
+ id = params.delete("id")
19
+ path = "/groups/#{id}.json"
20
+
21
+ if group = self.data[:groups][id]
22
+ group.merge!(params)
23
+ response(
24
+ :method => :put,
25
+ :path => "/groups/#{id}.json",
26
+ :body => {
27
+ "group" => group
28
+ },
29
+ )
30
+ else response(status: 404)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -6,6 +6,7 @@ class Zendesk2::Client < Cistern::Service
6
6
 
7
7
  collection :categories
8
8
  collection :forums
9
+ collection :groups
9
10
  collection :organizations
10
11
  collection :ticket_audits
11
12
  collection :tickets
@@ -16,6 +17,7 @@ class Zendesk2::Client < Cistern::Service
16
17
  model :audit_event
17
18
  model :category
18
19
  model :forum
20
+ model :group
19
21
  model :organization
20
22
  model :ticket
21
23
  model :ticket_audit
@@ -24,8 +26,10 @@ class Zendesk2::Client < Cistern::Service
24
26
  model :user
25
27
  model :user_identity
26
28
 
29
+ request :get_assignable_groups
27
30
  request :create_category
28
31
  request :create_forum
32
+ request :create_group
29
33
  request :create_organization
30
34
  request :create_ticket
31
35
  request :create_topic
@@ -34,6 +38,7 @@ class Zendesk2::Client < Cistern::Service
34
38
  request :create_user_identity
35
39
  request :destroy_category
36
40
  request :destroy_forum
41
+ request :destroy_group
37
42
  request :destroy_organization
38
43
  request :destroy_ticket
39
44
  request :destroy_topic
@@ -47,6 +52,8 @@ class Zendesk2::Client < Cistern::Service
47
52
  request :get_current_user
48
53
  request :get_forum
49
54
  request :get_forums
55
+ request :get_group
56
+ request :get_groups
50
57
  request :get_organization
51
58
  request :get_organization_tickets
52
59
  request :get_organization_users
@@ -69,6 +76,7 @@ class Zendesk2::Client < Cistern::Service
69
76
  request :mark_user_identity_primary
70
77
  request :update_category
71
78
  request :update_forum
79
+ request :update_group
72
80
  request :update_organization
73
81
  request :update_ticket
74
82
  request :update_topic
@@ -100,14 +108,17 @@ class Zendesk2::Client < Cistern::Service
100
108
  adapter = options[:adapter] || :net_http
101
109
  connection_options = options[:connection_options] || {ssl: {verify: false}}
102
110
  @username = options[:username] || Zendesk2.defaults[:username]
111
+ token = options[:token] || Zendesk2.defaults[:token]
103
112
  password = options[:password] || Zendesk2.defaults[:password]
104
- @token = options[:token]
113
+ @username += "/token" if token
114
+ @auth_token = token || password
105
115
 
106
- raise "Missing required options: [:username, :password]" unless @username && password
116
+ raise "Missing required options: :username" unless @username
117
+ raise "Missing required options: :password or :token" unless password || token
107
118
 
108
119
  @connection = Faraday.new({url: @url}.merge(connection_options)) do |builder|
109
120
  # response
110
- builder.use Faraday::Request::BasicAuthentication, @username, password
121
+ builder.use Faraday::Request::BasicAuthentication, @username, @auth_token
111
122
  builder.use Faraday::Response::RaiseError
112
123
  builder.response :json
113
124
 
@@ -146,6 +157,7 @@ class Zendesk2::Client < Cistern::Service
146
157
  @data ||= {
147
158
  :categories => {},
148
159
  :forums => {},
160
+ :groups => {},
149
161
  :identities => {},
150
162
  :organizations => {},
151
163
  :ticket_audits => {},
@@ -1,5 +1,25 @@
1
- # @abstract adds {#create!} method
1
+ # @abstract Subclass and set #{collection_method}, #{collection_root}, #{model_method}, #{model_root} and #{model}
2
+ # adds {#create!} method to {Cistern::Collection}.
2
3
  class Zendesk2::Collection < Cistern::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 next_page
17
+ all("url" => next_page_link) if next_page_link
18
+ end
19
+
20
+ def previous_page
21
+ all("url" => previous_page_link) if previous_page_link
22
+ end
3
23
 
4
24
  # Attempt creation of resource and explode if unsuccessful
5
25
  # @raise [Zendesk2::Error] if creation was unsuccessful
@@ -16,4 +36,59 @@ class Zendesk2::Collection < Cistern::Collection
16
36
  model = self.new(attributes.merge(Zendesk2.stringify_keys(self.attributes)))
17
37
  model.save
18
38
  end
39
+
40
+ # Fetch a collection of resources
41
+ def all(params={})
42
+ scoped_attributes = self.class.scopes.inject({}){|r,k| r.merge(k.to_s => send(k))}
43
+ scoped_attributes.merge!(params)
44
+ body = connection.send(collection_method, scoped_attributes).body
45
+
46
+ collection = self.clone.load(body[collection_root])
47
+ collection.merge_attributes(Cistern::Hash.slice(body, "count", "next_page", "previous_page"))
48
+ collection
49
+ end
50
+
51
+ # Fetch a single of resource
52
+ # @overload get!(identity)
53
+ # fetch a un-namespaced specific record or a namespaced record under the current {#scopes}
54
+ # @param [Integer] identity identity of the record
55
+ # @overload get!(scope)
56
+ # directly fetch a namespaced record
57
+ # @param [Hash] scope parameters to fetch record
58
+ # @example Fetch a record without contextual scoping
59
+ # self.identities.all("user_id" => 2, "id" => 4) # context defined directly
60
+ # @example Fetch a record with contextual scoping
61
+ # self.identities("user_id" => 2).get(4) # context defined in collection
62
+ # user.identities.get(4) # context defined by encapsulating model
63
+ # @raise [Zendesk2::Error] if the record cannot be found or other request error
64
+ # @return [Zendesk2::Model] fetched resource corresponding to value of {Zendesk2::Collection#model}
65
+ def get!(identity_or_hash)
66
+ scoped_attributes = self.class.scopes.inject({}){|r,k| r.merge(k.to_s => send(k))}
67
+ if identity_or_hash.is_a?(Hash)
68
+ scoped_attributes.merge!(identity_or_hash)
69
+ else scoped_attributes.merge!("id" => identity_or_hash)
70
+ end
71
+
72
+ if data = self.connection.send(model_method, scoped_attributes).body[self.model_root]
73
+ new(data)
74
+ end
75
+ end
76
+
77
+ # Quiet version of {#get!}
78
+ # @see #get!
79
+ # @return [Zendesk2::Model] Fetched model when successful
80
+ # @return [NilClass] return nothing if record cannot be found
81
+ def get(*args)
82
+ get!(*args)
83
+ rescue Zendesk2::Error
84
+ nil
85
+ end
86
+
87
+ module ClassMethods
88
+ attr_accessor :collection_method, :collection_root, :model_method, :model_root
89
+
90
+ def scopes
91
+ @scopes ||= []
92
+ end
93
+ end
19
94
  end
@@ -1,27 +1,22 @@
1
- require 'forwardable'
2
-
3
1
  class Zendesk2::Logger < Faraday::Response::Middleware
4
2
  extend Forwardable
5
3
 
6
4
  def initialize(app, logger = nil)
7
5
  super(app)
8
- @logger = logger || begin
9
- require 'logger'
10
- ::Logger.new(STDOUT)
11
- end
6
+ @logger = logger || ::Logger.new(STDOUT)
12
7
  end
13
8
 
14
9
  def_delegators :@logger, :debug, :info, :warn, :error, :fatal
15
10
 
16
11
  def call(env)
17
- info "#{env[:method]} #{env[:url].to_s}"
12
+ info("#{env[:method]} => #{env[:url].to_s}")
18
13
  debug('request') { dump_headers env[:request_headers] }
19
14
  debug('request.body') { env[:body] }
20
15
  super
21
16
  end
22
17
 
23
18
  def on_complete(env)
24
- info('Status') { env[:status].to_s }
19
+ info("#{env[:status]} <= #{env[:url].to_s}")
25
20
  debug('response') { dump_headers env[:response_headers] }
26
21
  debug('response.body') { env[:body] }
27
22
  end
@@ -1,3 +1,3 @@
1
1
  module Zendesk2
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
data/lib/zendesk2.rb CHANGED
@@ -9,12 +9,12 @@ require 'faraday_middleware'
9
9
  # stdlib
10
10
  require 'time'
11
11
  require 'logger'
12
+ require 'forwardable'
12
13
 
13
14
  module Zendesk2
14
15
  autoload :Attributes, 'zendesk2/attributes'
15
16
  autoload :Error, 'zendesk2/error'
16
17
  autoload :Client, 'zendesk2/client'
17
- autoload :PagedCollection, 'zendesk2/paged_collection'
18
18
  autoload :Searchable, 'zendesk2/searchable'
19
19
  autoload :Logger, 'zendesk2/logger'
20
20
  autoload :Model, 'zendesk2/model'
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe "groups" do
4
+ let(:client) { create_client }
5
+ it_should_behave_like "a resource", :groups,
6
+ lambda { {name: Zendesk2.uuid} },
7
+ lambda { {name: Zendesk2.uuid} }
8
+
9
+ it "should list assignable groups" do
10
+ client.groups.create(name: Zendesk2.uuid) # assignable by default
11
+
12
+ client.groups.assignable.should be_all{|g| !g.deleted}
13
+ end
14
+ end
@@ -12,7 +12,7 @@ shared_examples "a resource" do |_collection, _params, _update_params, _options|
12
12
 
13
13
  it "by fetching a specific record" do
14
14
  record = collection.create(params)
15
- collection.get(*fetch_params.call(record)).should == record
15
+ collection.get(fetch_params.call(record)).should == record
16
16
  end
17
17
 
18
18
  context "that is paged" do
@@ -5,12 +5,11 @@ describe "topic_comments" do
5
5
  let(:user) { client.users.create(email: "zendesk2+#{Zendesk2.uuid}@example.org", name: Zendesk2.uuid, verified: true) }
6
6
  let(:forum) { client.forums.create(name: Zendesk2.uuid) }
7
7
  let(:topic) { client.topics.create(title: Zendesk2.uuid, body: Zendesk2.uuid, forum: forum) }
8
- it_should_behave_like "a resource",
9
- :topic_comments,
8
+ it_should_behave_like "a resource", :topic_comments,
10
9
  lambda { {body: Zendesk2.uuid, topic_id: topic.id, user_id: user.id} },
11
10
  lambda { {body: Zendesk2.uuid} },
12
11
  {
13
- :fetch_params => lambda {|tc| [tc.topic_id, tc.id]},
12
+ :fetch_params => lambda {|tc| {"topic_id" => tc.topic_id, "id" => tc.id}},
14
13
  :collection => lambda { client.topic_comments(topic_id: topic.id) },
15
14
  }
16
15
  end
@@ -8,7 +8,7 @@ describe "user_identities" do
8
8
  lambda { {value: "ey+#{Zendesk2.uuid}@example.org", type: "email", user_id: user.id} },
9
9
  lambda { {verified: true} },
10
10
  {
11
- :fetch_params => lambda {|uc| [uc.user_id, uc.id]},
11
+ :fetch_params => lambda {|uc| {"user_id" => uc.user_id, "id" => uc.id}},
12
12
  :collection => lambda { client.user_identities(user_id: user.id) },
13
13
  }
14
14
  end
data/zendesk2.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Zendesk2::VERSION
17
17
 
18
- gem.add_dependency "cistern", "~> 0.1.3"
18
+ gem.add_dependency "cistern", "~> 0.2.0"
19
19
  gem.add_dependency "faraday"
20
20
  gem.add_dependency "faraday_middleware"
21
21
  gem.add_dependency "addressable"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zendesk2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-29 00:00:00.000000000 Z
12
+ date: 2013-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cistern
@@ -18,14 +18,14 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.1.3
21
+ version: 0.2.0
22
22
  none: false
23
23
  type: :runtime
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - ~>
27
27
  - !ruby/object:Gem::Version
28
- version: 0.1.3
28
+ version: 0.2.0
29
29
  none: false
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: faraday
@@ -98,6 +98,8 @@ files:
98
98
  - lib/zendesk2/client/models/category.rb
99
99
  - lib/zendesk2/client/models/forum.rb
100
100
  - lib/zendesk2/client/models/forums.rb
101
+ - lib/zendesk2/client/models/group.rb
102
+ - lib/zendesk2/client/models/groups.rb
101
103
  - lib/zendesk2/client/models/organization.rb
102
104
  - lib/zendesk2/client/models/organizations.rb
103
105
  - lib/zendesk2/client/models/ticket.rb
@@ -114,6 +116,7 @@ files:
114
116
  - lib/zendesk2/client/models/users.rb
115
117
  - lib/zendesk2/client/requests/create_category.rb
116
118
  - lib/zendesk2/client/requests/create_forum.rb
119
+ - lib/zendesk2/client/requests/create_group.rb
117
120
  - lib/zendesk2/client/requests/create_organization.rb
118
121
  - lib/zendesk2/client/requests/create_ticket.rb
119
122
  - lib/zendesk2/client/requests/create_topic.rb
@@ -122,12 +125,14 @@ files:
122
125
  - lib/zendesk2/client/requests/create_user_identity.rb
123
126
  - lib/zendesk2/client/requests/destroy_category.rb
124
127
  - lib/zendesk2/client/requests/destroy_forum.rb
128
+ - lib/zendesk2/client/requests/destroy_group.rb
125
129
  - lib/zendesk2/client/requests/destroy_organization.rb
126
130
  - lib/zendesk2/client/requests/destroy_ticket.rb
127
131
  - lib/zendesk2/client/requests/destroy_topic.rb
128
132
  - lib/zendesk2/client/requests/destroy_topic_comment.rb
129
133
  - lib/zendesk2/client/requests/destroy_user.rb
130
134
  - lib/zendesk2/client/requests/destroy_user_identity.rb
135
+ - lib/zendesk2/client/requests/get_assignable_groups.rb
131
136
  - lib/zendesk2/client/requests/get_audits.rb
132
137
  - lib/zendesk2/client/requests/get_categories.rb
133
138
  - lib/zendesk2/client/requests/get_category.rb
@@ -135,6 +140,8 @@ files:
135
140
  - lib/zendesk2/client/requests/get_current_user.rb
136
141
  - lib/zendesk2/client/requests/get_forum.rb
137
142
  - lib/zendesk2/client/requests/get_forums.rb
143
+ - lib/zendesk2/client/requests/get_group.rb
144
+ - lib/zendesk2/client/requests/get_groups.rb
138
145
  - lib/zendesk2/client/requests/get_organization.rb
139
146
  - lib/zendesk2/client/requests/get_organization_tickets.rb
140
147
  - lib/zendesk2/client/requests/get_organization_users.rb
@@ -157,6 +164,7 @@ files:
157
164
  - lib/zendesk2/client/requests/search_user.rb
158
165
  - lib/zendesk2/client/requests/update_category.rb
159
166
  - lib/zendesk2/client/requests/update_forum.rb
167
+ - lib/zendesk2/client/requests/update_group.rb
160
168
  - lib/zendesk2/client/requests/update_organization.rb
161
169
  - lib/zendesk2/client/requests/update_ticket.rb
162
170
  - lib/zendesk2/client/requests/update_topic.rb
@@ -167,11 +175,11 @@ files:
167
175
  - lib/zendesk2/error.rb
168
176
  - lib/zendesk2/logger.rb
169
177
  - lib/zendesk2/model.rb
170
- - lib/zendesk2/paged_collection.rb
171
178
  - lib/zendesk2/searchable.rb
172
179
  - lib/zendesk2/version.rb
173
180
  - spec/categories_spec.rb
174
181
  - spec/forums_spec.rb
182
+ - spec/groups_spec.rb
175
183
  - spec/organizations_spec.rb
176
184
  - spec/shared/resource.rb
177
185
  - spec/spec_helper.rb
@@ -209,6 +217,7 @@ summary: Zendesk V2 API client
209
217
  test_files:
210
218
  - spec/categories_spec.rb
211
219
  - spec/forums_spec.rb
220
+ - spec/groups_spec.rb
212
221
  - spec/organizations_spec.rb
213
222
  - spec/shared/resource.rb
214
223
  - spec/spec_helper.rb
@@ -1,41 +0,0 @@
1
- module Zendesk2::PagedCollection
2
- def self.included(klass)
3
- klass.send(:attribute, :count)
4
- klass.send(:attribute, :next_page_link, {:aliases => "next_page"})
5
- klass.send(:attribute, :previous_page_link, {:aliases => "previous_page"})
6
- klass.send(:extend, Zendesk2::PagedCollection::Attributes)
7
- end
8
-
9
- def collection_method; self.class.collection_method; end
10
- def collection_root; self.class.collection_root; end
11
- def model_method; self.class.model_method; end
12
- def model_root; self.class.model_root; end
13
-
14
- def all(params={})
15
- body = connection.send(collection_method, params).body
16
-
17
- collection = self.clone.load(body[collection_root])
18
- collection.merge_attributes(Cistern::Hash.slice(body, "count", "next_page", "previous_page"))
19
- collection
20
- end
21
-
22
- def get(id)
23
- if data = self.connection.send(model_method, {"id" => id}).body[self.model_root]
24
- new(data)
25
- end
26
- rescue Zendesk2::Error
27
- nil
28
- end
29
-
30
- def next_page
31
- all("url" => next_page_link) if next_page_link
32
- end
33
-
34
- def previous_page
35
- all("url" => previous_page_link) if previous_page_link
36
- end
37
-
38
- module Attributes
39
- attr_accessor :collection_method, :collection_root, :model_method, :model_root
40
- end
41
- end