zendesk2 0.1.2 → 0.1.3

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