zendesk2 0.0.13 → 0.0.14
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.
- data/README.md +30 -25
- data/lib/zendesk2/attributes.rb +23 -0
- data/lib/zendesk2/client/models/categories.rb +12 -0
- data/lib/zendesk2/client/models/category.rb +38 -0
- data/lib/zendesk2/client/models/forum.rb +50 -0
- data/lib/zendesk2/client/models/forums.rb +12 -0
- data/lib/zendesk2/client/models/organization.rb +3 -1
- data/lib/zendesk2/client/models/organizations.rb +2 -12
- data/lib/zendesk2/client/models/ticket.rb +9 -13
- data/lib/zendesk2/client/models/tickets.rb +2 -8
- data/lib/zendesk2/client/models/user.rb +7 -9
- data/lib/zendesk2/client/models/users.rb +2 -8
- data/lib/zendesk2/client/requests/create_category.rb +32 -0
- data/lib/zendesk2/client/requests/create_forum.rb +33 -0
- data/lib/zendesk2/client/requests/create_user.rb +25 -6
- data/lib/zendesk2/client/requests/destroy_category.rb +27 -0
- data/lib/zendesk2/client/requests/destroy_forum.rb +28 -0
- data/lib/zendesk2/client/requests/get_categories.rb +18 -0
- data/lib/zendesk2/client/requests/get_category.rb +32 -0
- data/lib/zendesk2/client/requests/get_forum.rb +26 -0
- data/lib/zendesk2/client/requests/get_forums.rb +18 -0
- data/lib/zendesk2/client/requests/search.rb +2 -2
- data/lib/zendesk2/client/requests/update_category.rb +29 -0
- data/lib/zendesk2/client/requests/update_forum.rb +30 -0
- data/lib/zendesk2/client/requests/update_user.rb +26 -9
- data/lib/zendesk2/client.rb +24 -3
- data/lib/zendesk2/searchable.rb +17 -0
- data/lib/zendesk2/version.rb +1 -1
- data/lib/zendesk2.rb +3 -0
- data/spec/categories_spec.rb +9 -0
- data/spec/forums_spec.rb +9 -0
- data/spec/shared/resource.rb +8 -1
- data/spec/users_spec.rb +15 -1
- data/zendesk2.gemspec +1 -1
- metadata +23 -3
data/README.md
CHANGED
@@ -20,47 +20,52 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
Default credentials will be read in from `~/.zendesk2` file in YAML format.
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
```yaml
|
24
|
+
---
|
25
|
+
:subdomain: zendeskdev
|
26
|
+
:username: zendeskedge@example.com
|
27
|
+
:password: wickedsecurepassword
|
28
|
+
```
|
27
29
|
|
28
30
|
### Creating the client
|
29
31
|
|
30
32
|
Either the absolute url or the subdomain is required. Username and password is always required.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
```ruby
|
34
|
+
Zendesk2::Client.new(subdomain: "engineyard", username: "orchestra", password: "gwoo")
|
35
|
+
=> #<Zendesk2::Client::Real:0x007f99da1f9430 @url="https://engineyard.zendesk.com/api/v2", @username="orchestra", @password="gwoo", …>
|
36
|
+
```
|
35
37
|
or
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
```ruby
|
39
|
+
Zendesk2::Client.new(url: "http://support.cloud.engineyard.com", username: "mate", password: "bambilla")
|
40
|
+
=> #<Zendesk2::Client::Real:0x007fd1bae486b0 @url="http://support.cloud.engineyard.com", @username="mate", @password="bambilla", …>
|
41
|
+
```
|
39
42
|
### Resources
|
40
43
|
|
41
44
|
#### Collections
|
42
45
|
|
43
46
|
Currently support resources
|
44
47
|
|
48
|
+
* Categories
|
45
49
|
* User
|
46
50
|
* Ticket
|
47
51
|
* Organization
|
52
|
+
* Forums
|
48
53
|
|
49
54
|
All collection are accessed like so:
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
55
|
+
```ruby
|
56
|
+
client.users.all
|
57
|
+
=> <Zendesk2::Client::Users
|
58
|
+
count=1779,
|
59
|
+
next_page_link="https://dev.zendesk.com/api/v2/users.json?page=2",
|
60
|
+
previous_page_link=nil
|
61
|
+
[
|
62
|
+
<Zendesk2::Client::User
|
63
|
+
id=125394183,
|
64
|
+
url="https://dev.zendesk.com/api/v2/users/125394183.json",
|
65
|
+
...
|
66
|
+
>
|
67
|
+
]
|
68
|
+
```
|
64
69
|
Collections also respond to `create` and `new`
|
65
70
|
|
66
71
|
client.users.create(email: "ohhai@example.org", name: "lulz")
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Zendesk2::Attributes
|
2
|
+
def assoc_reader(name, options={})
|
3
|
+
assoc_key = options[:key] || "#{name}_id"
|
4
|
+
collection = options[:collection] || "#{name}s"
|
5
|
+
define_method(name) do
|
6
|
+
self.connection.send(collection).get(self.send(assoc_key))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def assoc_writer(name, options={})
|
11
|
+
assoc_key = options[:key] || "#{name}_id"
|
12
|
+
define_method("#{name}=") do |assoc|
|
13
|
+
self.send("#{assoc_key}=", assoc.id)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def assoc_accessor(name, options={})
|
18
|
+
assoc_reader(name, options)
|
19
|
+
assoc_writer(name, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
# TODO: collection
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Zendesk2::Client::Categories < Cistern::Collection
|
2
|
+
include Zendesk2::PagedCollection
|
3
|
+
include Zendesk2::Searchable
|
4
|
+
|
5
|
+
model Zendesk2::Client::Category
|
6
|
+
|
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"
|
12
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Zendesk2::Client::Category < Cistern::Model
|
2
|
+
PARAMS = %w[id name description position]
|
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
|
11
|
+
|
12
|
+
def destroy
|
13
|
+
requires :id
|
14
|
+
|
15
|
+
connection.destroy_category("id" => self.id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroyed?
|
19
|
+
!self.reload
|
20
|
+
end
|
21
|
+
|
22
|
+
def save
|
23
|
+
data = if new_record?
|
24
|
+
requires :name
|
25
|
+
connection.create_category(params).body["category"]
|
26
|
+
else
|
27
|
+
requires :id
|
28
|
+
connection.update_category(params).body["category"]
|
29
|
+
end
|
30
|
+
merge_attributes(data)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def params
|
36
|
+
Cistern::Hash.slice(Zendesk2.stringify_keys(attributes), *PARAMS)
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class Zendesk2::Client::Forum < Cistern::Model
|
2
|
+
extend Zendesk2::Attributes
|
3
|
+
|
4
|
+
PARAMS = %w[id name description category_id organization_id locale_id locked position forum_type access]
|
5
|
+
|
6
|
+
identity :id, type: :integer # ro yes mandatory no Automatically assigned upon creation
|
7
|
+
attribute :url, type: :string # ro yes mandatory no The API url of this forum
|
8
|
+
attribute :name, type: :string # ro no mandatory yes The name of the forum
|
9
|
+
attribute :description, type: :string # ro no mandatory no A description of the forum
|
10
|
+
attribute :category_id, type: :integer # ro no mandatory no Category this forum is in
|
11
|
+
attribute :organization_id, type: :integer # ro no mandatory no Organization this forum is restricted to
|
12
|
+
attribute :locale_id, type: :integer # ro no mandatory no User locale id this forum is restricted to
|
13
|
+
attribute :locked, type: :boolean # ro no mandatory no Whether this forum is locked such that new entries and comments cannot be made
|
14
|
+
attribute :unanswered_topics, type: :integer # ro yes mandatory no Contains the number of unanswered questions if this forum's topics are questions.
|
15
|
+
attribute :position, type: :integer # ro no mandatory no The position of this forum relative to other forums in the same category
|
16
|
+
attribute :forum_type, type: :string # ro no mandatory no The type of the topics in this forum, valid values: "articles", "ideas" or "questions"
|
17
|
+
attribute :access, type: :string # ro no mandatory no Who has access to this forum, valid values: "everybody", "logged-in users" or "agents only"
|
18
|
+
attribute :created_at, type: :date # ro yes mandatory no The time the forum was created
|
19
|
+
attribute :updated_at, type: :date # ro yes mandatory no The time of the last update of the forum
|
20
|
+
|
21
|
+
assoc_accessor :organization
|
22
|
+
assoc_accessor :category
|
23
|
+
|
24
|
+
def destroy
|
25
|
+
requires :identity
|
26
|
+
|
27
|
+
connection.destroy_forum("id" => self.identity)
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroyed?
|
31
|
+
!self.reload
|
32
|
+
end
|
33
|
+
|
34
|
+
def save
|
35
|
+
data = if new_record?
|
36
|
+
requires :name
|
37
|
+
connection.create_forum(params).body["forum"]
|
38
|
+
else
|
39
|
+
requires :identity
|
40
|
+
connection.update_forum(params).body["forum"]
|
41
|
+
end
|
42
|
+
merge_attributes(data)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def params
|
48
|
+
Cistern::Hash.slice(Zendesk2.stringify_keys(attributes), *PARAMS)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Zendesk2::Client::Forums < Cistern::Collection
|
2
|
+
include Zendesk2::PagedCollection
|
3
|
+
include Zendesk2::Searchable
|
4
|
+
|
5
|
+
model Zendesk2::Client::Forum
|
6
|
+
|
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"
|
12
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class Zendesk2::Client::Organization < Cistern::Model
|
2
|
+
PARAMS = %w[id details domain_names external_id group_id shared_comments shared_tickets tags name notes]
|
2
3
|
identity :id, type: :integer
|
4
|
+
attribute :url, type: :string
|
3
5
|
attribute :created_at, type: :time
|
4
6
|
attribute :details, type: :string
|
5
7
|
attribute :domain_names, type: :array
|
@@ -56,7 +58,7 @@ class Zendesk2::Client::Organization < Cistern::Model
|
|
56
58
|
private
|
57
59
|
|
58
60
|
def params
|
59
|
-
writable_attributes = Cistern::Hash.slice(Zendesk2.stringify_keys(attributes),
|
61
|
+
writable_attributes = Cistern::Hash.slice(Zendesk2.stringify_keys(attributes), *PARAMS)
|
60
62
|
writable_attributes.delete("external_id") if writable_attributes["external_id"].to_s == "0"
|
61
63
|
writable_attributes.delete("group_id") if writable_attributes["group_id"].to_s == "0"
|
62
64
|
writable_attributes
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Zendesk2::Client::Organizations < Cistern::Collection
|
2
2
|
include Zendesk2::PagedCollection
|
3
|
+
include Zendesk2::Searchable
|
3
4
|
|
4
5
|
model Zendesk2::Client::Organization
|
5
6
|
|
@@ -7,16 +8,5 @@ class Zendesk2::Client::Organizations < Cistern::Collection
|
|
7
8
|
self.collection_root= "organizations"
|
8
9
|
self.model_method= :get_organization
|
9
10
|
self.model_root= "organization"
|
10
|
-
|
11
|
-
def current
|
12
|
-
new(connection.get_current_organization.body["organization"])
|
13
|
-
end
|
14
|
-
|
15
|
-
def search(parameters)
|
16
|
-
body = connection.search(parameters.merge("type" => "organization")).body
|
17
|
-
if data = body.delete("results")
|
18
|
-
load(data)
|
19
|
-
end
|
20
|
-
merge_attributes(body)
|
21
|
-
end
|
11
|
+
self.search_type= "organization"
|
22
12
|
end
|
@@ -1,4 +1,8 @@
|
|
1
1
|
class Zendesk2::Client::Ticket < Cistern::Model
|
2
|
+
extend Zendesk2::Attributes
|
3
|
+
|
4
|
+
PARAMS = %w[external_id via requester_id submitter_id assignee_id organization_id subject description fields recipient status collaborator_ids]
|
5
|
+
|
2
6
|
identity :id, type: :id
|
3
7
|
attribute :external_id
|
4
8
|
attribute :via
|
@@ -23,6 +27,10 @@ class Zendesk2::Client::Ticket < Cistern::Model
|
|
23
27
|
attribute :tags, type: :array
|
24
28
|
attribute :fields, type: :array
|
25
29
|
|
30
|
+
assoc_reader :organization
|
31
|
+
assoc_accessor :requester
|
32
|
+
assoc_reader :submitter
|
33
|
+
|
26
34
|
def save
|
27
35
|
if new_record?
|
28
36
|
requires :subject, :description
|
@@ -53,22 +61,10 @@ class Zendesk2::Client::Ticket < Cistern::Model
|
|
53
61
|
!self.reload
|
54
62
|
end
|
55
63
|
|
56
|
-
def requester=(requester)
|
57
|
-
self.requester_id= requester.id
|
58
|
-
end
|
59
|
-
|
60
|
-
def requester
|
61
|
-
self.connection.users.get(self.requester_id)
|
62
|
-
end
|
63
|
-
|
64
|
-
def submitter
|
65
|
-
self.connection.users.get(submitter_id)
|
66
|
-
end
|
67
|
-
|
68
64
|
private
|
69
65
|
|
70
66
|
def params
|
71
|
-
Cistern::Hash.slice(Zendesk2.stringify_keys(attributes),
|
67
|
+
Cistern::Hash.slice(Zendesk2.stringify_keys(attributes), *PARAMS)
|
72
68
|
end
|
73
69
|
|
74
70
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Zendesk2::Client::Tickets < Cistern::Collection
|
2
2
|
include Zendesk2::PagedCollection
|
3
|
+
include Zendesk2::Searchable
|
3
4
|
|
4
5
|
model Zendesk2::Client::Ticket
|
5
6
|
|
@@ -7,12 +8,5 @@ class Zendesk2::Client::Tickets < Cistern::Collection
|
|
7
8
|
self.collection_root= "tickets"
|
8
9
|
self.model_method= :get_ticket
|
9
10
|
self.model_root= "ticket"
|
10
|
-
|
11
|
-
def search(term)
|
12
|
-
body = connection.search_ticket("query" => term).body
|
13
|
-
if data = body.delete("results")
|
14
|
-
load(data)
|
15
|
-
end
|
16
|
-
merge_attributes(body)
|
17
|
-
end
|
11
|
+
self.search_type= "ticket"
|
18
12
|
end
|
@@ -1,4 +1,8 @@
|
|
1
1
|
class Zendesk2::Client::User < Cistern::Model
|
2
|
+
extend Zendesk2::Attributes
|
3
|
+
|
4
|
+
PARAMS = %w[name email organization_id external_id alias verified locate_id time_zone phone signature details notes role custom_role_id moderator ticket_restriction only_private_comments]
|
5
|
+
|
2
6
|
identity :id, type: :id
|
3
7
|
attribute :url
|
4
8
|
attribute :external_id
|
@@ -29,6 +33,8 @@ class Zendesk2::Client::User < Cistern::Model
|
|
29
33
|
attribute :photo
|
30
34
|
attribute :authenticity_token
|
31
35
|
|
36
|
+
assoc_accessor :organization
|
37
|
+
|
32
38
|
def save
|
33
39
|
if new_record?
|
34
40
|
requires :name, :email
|
@@ -101,18 +107,10 @@ class Zendesk2::Client::User < Cistern::Model
|
|
101
107
|
connection.tickets.load(data)
|
102
108
|
end
|
103
109
|
|
104
|
-
def organization=(organization)
|
105
|
-
self.organization_id= organization.id
|
106
|
-
end
|
107
|
-
|
108
|
-
def organization
|
109
|
-
self.connection.organizations.get(self.organization_id)
|
110
|
-
end
|
111
|
-
|
112
110
|
private
|
113
111
|
|
114
112
|
def params
|
115
|
-
writable_attributes = Cistern::Hash.slice(Zendesk2.stringify_keys(attributes),
|
113
|
+
writable_attributes = Cistern::Hash.slice(Zendesk2.stringify_keys(attributes), *PARAMS)
|
116
114
|
writable_attributes.delete("organization_id") if writable_attributes["organization_id"] == 0
|
117
115
|
writable_attributes.delete("custom_role_id") if writable_attributes["custom_role_id"] == 0
|
118
116
|
writable_attributes
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Zendesk2::Client::Users < Cistern::Collection
|
2
2
|
include Zendesk2::PagedCollection
|
3
|
+
include Zendesk2::Searchable
|
3
4
|
|
4
5
|
model Zendesk2::Client::User
|
5
6
|
|
@@ -7,16 +8,9 @@ class Zendesk2::Client::Users < Cistern::Collection
|
|
7
8
|
self.collection_root= "users"
|
8
9
|
self.model_method= :get_user
|
9
10
|
self.model_root= "user"
|
11
|
+
self.search_type= "user"
|
10
12
|
|
11
13
|
def current
|
12
14
|
new(connection.get_current_user.body["user"])
|
13
15
|
end
|
14
|
-
|
15
|
-
def search(term)
|
16
|
-
body = connection.search_user("query" => term).body
|
17
|
-
if data = body.delete("results")
|
18
|
-
load(data)
|
19
|
-
end
|
20
|
-
merge_attributes(body)
|
21
|
-
end
|
22
16
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def create_category(params={})
|
4
|
+
request(
|
5
|
+
:body => {"category" => params},
|
6
|
+
:method => :post,
|
7
|
+
:path => "/categories.json",
|
8
|
+
)
|
9
|
+
end
|
10
|
+
end # Real
|
11
|
+
|
12
|
+
class Mock
|
13
|
+
def create_category(params={})
|
14
|
+
identity = self.class.new_id
|
15
|
+
|
16
|
+
record = {
|
17
|
+
"id" => identity,
|
18
|
+
"url" => url_for("/categories/#{identity}.json"),
|
19
|
+
"created_at" => Time.now.iso8601,
|
20
|
+
"updated_at" => Time.now.iso8601,
|
21
|
+
}.merge(params)
|
22
|
+
|
23
|
+
self.data[:categories][identity]= record
|
24
|
+
|
25
|
+
response(
|
26
|
+
:method => :post,
|
27
|
+
:body => {"category" => record},
|
28
|
+
:path => "/categories.json"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end # Mock
|
32
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def create_forum(params={})
|
4
|
+
request(
|
5
|
+
:body => {"forum" => params},
|
6
|
+
:method => :post,
|
7
|
+
:path => "/forums.json",
|
8
|
+
)
|
9
|
+
end
|
10
|
+
end # Real
|
11
|
+
|
12
|
+
class Mock
|
13
|
+
def create_forum(params={})
|
14
|
+
identity = self.class.new_id
|
15
|
+
|
16
|
+
record = {
|
17
|
+
"id" => identity,
|
18
|
+
"url" => url_for("/forums/#{identity}.json"),
|
19
|
+
"created_at" => Time.now.iso8601,
|
20
|
+
"updated_at" => Time.now.iso8601,
|
21
|
+
}.merge(params)
|
22
|
+
|
23
|
+
path = "/forums.json"
|
24
|
+
self.data[:forums][identity]= record
|
25
|
+
|
26
|
+
response(
|
27
|
+
:method => :post,
|
28
|
+
:body => {"forum" => record},
|
29
|
+
:path => path,
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end # Mock
|
33
|
+
end
|
@@ -21,13 +21,32 @@ class Zendesk2::Client
|
|
21
21
|
"active" => true,
|
22
22
|
}.merge(params)
|
23
23
|
|
24
|
-
|
24
|
+
path = "/users.json"
|
25
|
+
if record["email"] && self.data[:users].find{|k,u| u["email"] == record["email"] && k != identity}
|
26
|
+
response(
|
27
|
+
:method => :put,
|
28
|
+
:path => path,
|
29
|
+
:status => 422,
|
30
|
+
:body => {
|
31
|
+
"error" => "RecordInvalid",
|
32
|
+
"description" => "Record validation errors", "details" => {
|
33
|
+
"email" => [ {
|
34
|
+
"type" => "#{record["email"]} is already being used by another user",
|
35
|
+
"description" => "Email: #{record["email"]} is already being used by another user"
|
36
|
+
} ]
|
37
|
+
}
|
38
|
+
}
|
39
|
+
)
|
40
|
+
else
|
25
41
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
42
|
+
self.data[:users][identity]= record
|
43
|
+
|
44
|
+
response(
|
45
|
+
:method => :post,
|
46
|
+
:body => {"user" => record},
|
47
|
+
:path => path,
|
48
|
+
)
|
49
|
+
end
|
31
50
|
end
|
32
51
|
end # Mock
|
33
52
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def destroy_category(params={})
|
4
|
+
id = params["id"]
|
5
|
+
|
6
|
+
request(
|
7
|
+
:method => :delete,
|
8
|
+
:path => "/categories/#{id}.json"
|
9
|
+
)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Mock
|
14
|
+
def destroy_category(params={})
|
15
|
+
id = params["id"]
|
16
|
+
body = self.data[:categories].delete(id)
|
17
|
+
|
18
|
+
response(
|
19
|
+
:method => :delete,
|
20
|
+
:path => "/categories/#{id}.json",
|
21
|
+
:body => {
|
22
|
+
"category" => body,
|
23
|
+
},
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def destroy_forum(params={})
|
4
|
+
id = params["id"]
|
5
|
+
|
6
|
+
request(
|
7
|
+
:method => :delete,
|
8
|
+
:path => "/forums/#{id}.json"
|
9
|
+
)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Mock
|
14
|
+
def destroy_forum(params={})
|
15
|
+
id = params["id"]
|
16
|
+
path = "/forums/#{id}.json"
|
17
|
+
|
18
|
+
body = self.data[:forums].delete(id)
|
19
|
+
response(
|
20
|
+
:method => :delete,
|
21
|
+
:path => path,
|
22
|
+
:body => {
|
23
|
+
"forum" => body,
|
24
|
+
},
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def get_categories(params={})
|
4
|
+
page_params = Zendesk2.paging_parameters(params)
|
5
|
+
|
6
|
+
request(
|
7
|
+
:params => page_params,
|
8
|
+
:method => :get,
|
9
|
+
:path => "/categories.json",
|
10
|
+
)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
class Mock
|
14
|
+
def get_categories(params={})
|
15
|
+
page(params, :categories, "/categories.json", "categories")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def get_category(params={})
|
4
|
+
id = params["id"]
|
5
|
+
|
6
|
+
request(
|
7
|
+
:method => :get,
|
8
|
+
:path => "/categories/#{id}.json"
|
9
|
+
)
|
10
|
+
end
|
11
|
+
end # Real
|
12
|
+
|
13
|
+
class Mock
|
14
|
+
def get_category(params={})
|
15
|
+
id = params["id"]
|
16
|
+
if body = self.data[:categories][id]
|
17
|
+
|
18
|
+
response(
|
19
|
+
:path => "/categories/#{id}.json",
|
20
|
+
:body => {
|
21
|
+
"category" => body
|
22
|
+
},
|
23
|
+
)
|
24
|
+
else
|
25
|
+
response(
|
26
|
+
:path => "/categories/#{id}.json",
|
27
|
+
:status => 404
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end # Mock
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def get_forum(params={})
|
4
|
+
id = params["id"]
|
5
|
+
|
6
|
+
request(
|
7
|
+
:method => :get,
|
8
|
+
:path => "/forums/#{id}.json"
|
9
|
+
)
|
10
|
+
end
|
11
|
+
end # Real
|
12
|
+
|
13
|
+
class Mock
|
14
|
+
def get_forum(params={})
|
15
|
+
id = params["id"]
|
16
|
+
body = self.data[:forums][id]
|
17
|
+
|
18
|
+
response(
|
19
|
+
:path => "/forums/#{id}.json",
|
20
|
+
:body => {
|
21
|
+
"forum" => body
|
22
|
+
},
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end # Mock
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def get_forums(params={})
|
4
|
+
page_params = Zendesk2.paging_parameters(params)
|
5
|
+
|
6
|
+
request(
|
7
|
+
:params => page_params,
|
8
|
+
:method => :get,
|
9
|
+
:path => "/forums.json",
|
10
|
+
)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
class Mock
|
14
|
+
def get_forums(params={})
|
15
|
+
page(params, :forums, "/forums.json", "forums")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -4,7 +4,7 @@ class Zendesk2::Client
|
|
4
4
|
term = query.map{|k,v| "#{k}:#{v}"}.join(" ")
|
5
5
|
request(
|
6
6
|
:method => :get,
|
7
|
-
:params => {query: term},
|
7
|
+
:params => {query: "\"#{term}\""},
|
8
8
|
:path => "/search.json",
|
9
9
|
)
|
10
10
|
end
|
@@ -13,7 +13,7 @@ class Zendesk2::Client
|
|
13
13
|
class Mock
|
14
14
|
def search(query)
|
15
15
|
type = query.delete("type")
|
16
|
-
collection = type.nil? ? self.data.values : self.data[
|
16
|
+
collection = type.nil? ? self.data.values : self.data[pluralize(type).to_sym]
|
17
17
|
|
18
18
|
results = collection.select{|k,v| query.all?{|term, condition| v[term.to_s] == condition}}.values
|
19
19
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def update_category(params={})
|
4
|
+
id = params.delete("id")
|
5
|
+
|
6
|
+
request(
|
7
|
+
:method => :put,
|
8
|
+
:path => "/categories/#{id}.json",
|
9
|
+
:body => {
|
10
|
+
"category" => params
|
11
|
+
},
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
class Mock
|
16
|
+
def update_category(params={})
|
17
|
+
id = params.delete("id")
|
18
|
+
body = self.data[:categories][id].merge!(params)
|
19
|
+
|
20
|
+
response(
|
21
|
+
:method => :put,
|
22
|
+
:path => "/categories/#{id}.json",
|
23
|
+
:body => {
|
24
|
+
"category" => body
|
25
|
+
},
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Zendesk2::Client
|
2
|
+
class Real
|
3
|
+
def update_forum(params={})
|
4
|
+
id = params.delete("id")
|
5
|
+
|
6
|
+
request(
|
7
|
+
:method => :put,
|
8
|
+
:path => "/forums/#{id}.json",
|
9
|
+
:body => {
|
10
|
+
"forum" => params
|
11
|
+
},
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
class Mock
|
16
|
+
def update_forum(params={})
|
17
|
+
id = params.delete("id")
|
18
|
+
path = "/forums/#{id}.json"
|
19
|
+
|
20
|
+
body = self.data[:forums][id].merge!(params)
|
21
|
+
response(
|
22
|
+
:method => :put,
|
23
|
+
:path => path,
|
24
|
+
:body => {
|
25
|
+
"forum" => body
|
26
|
+
},
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -15,15 +15,32 @@ class Zendesk2::Client
|
|
15
15
|
class Mock
|
16
16
|
def update_user(params={})
|
17
17
|
id = params.delete("id")
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
18
|
+
path = "/users/#{id}.json"
|
19
|
+
if params["email"] && self.data[:users].find{|k,u| u["email"] == params["email"] && k != id}
|
20
|
+
response(
|
21
|
+
:method => :put,
|
22
|
+
:path => path,
|
23
|
+
:status => 422,
|
24
|
+
:body => {
|
25
|
+
"error" => "RecordInvalid",
|
26
|
+
"description" => "Record validation errors", "details" => {
|
27
|
+
"email" => [ {
|
28
|
+
"type" => "#{params["email"]} is already being used by another user",
|
29
|
+
"description" => "Email: #{params["email"]} is already being used by another user"
|
30
|
+
} ]
|
31
|
+
}
|
32
|
+
}
|
33
|
+
)
|
34
|
+
else
|
35
|
+
body = self.data[:users][id].merge!(params)
|
36
|
+
response(
|
37
|
+
:method => :put,
|
38
|
+
:path => path,
|
39
|
+
:body => {
|
40
|
+
"user" => body
|
41
|
+
},
|
42
|
+
)
|
43
|
+
end
|
27
44
|
end
|
28
45
|
end
|
29
46
|
end
|
data/lib/zendesk2/client.rb
CHANGED
@@ -3,6 +3,10 @@ class Zendesk2::Client < Cistern::Service
|
|
3
3
|
model_path "zendesk2/client/models"
|
4
4
|
request_path "zendesk2/client/requests"
|
5
5
|
|
6
|
+
model :category
|
7
|
+
collection :categories
|
8
|
+
model :forum
|
9
|
+
collection :forums
|
6
10
|
model :organization
|
7
11
|
collection :organizations
|
8
12
|
model :ticket
|
@@ -10,24 +14,34 @@ class Zendesk2::Client < Cistern::Service
|
|
10
14
|
model :user
|
11
15
|
collection :users
|
12
16
|
|
17
|
+
request :create_category
|
18
|
+
request :create_forum
|
13
19
|
request :create_organization
|
14
20
|
request :create_ticket
|
15
21
|
request :create_user
|
22
|
+
request :destroy_category
|
23
|
+
request :destroy_forum
|
16
24
|
request :destroy_organization
|
17
25
|
request :destroy_ticket
|
18
26
|
request :destroy_user
|
19
27
|
request :get_current_user
|
28
|
+
request :get_category
|
29
|
+
request :get_forum
|
20
30
|
request :get_organization
|
21
31
|
request :get_organization_tickets
|
22
32
|
request :get_organization_users
|
23
33
|
request :get_ticket
|
24
34
|
request :get_user
|
35
|
+
request :get_categories
|
36
|
+
request :get_forums
|
25
37
|
request :get_organizations
|
26
38
|
request :get_requested_tickets
|
27
39
|
request :get_ccd_tickets
|
28
40
|
request :get_tickets
|
29
41
|
request :get_users
|
30
42
|
request :search
|
43
|
+
request :update_category
|
44
|
+
request :update_forum
|
31
45
|
request :update_organization
|
32
46
|
request :update_ticket
|
33
47
|
request :update_user
|
@@ -36,7 +50,7 @@ class Zendesk2::Client < Cistern::Service
|
|
36
50
|
|
37
51
|
class Real
|
38
52
|
|
39
|
-
|
53
|
+
attr_accessor :username, :url, :token, :logger
|
40
54
|
|
41
55
|
def initialize(options={})
|
42
56
|
url = options[:url] || begin
|
@@ -52,7 +66,7 @@ class Zendesk2::Client < Cistern::Service
|
|
52
66
|
|
53
67
|
@url = URI.parse(url).to_s
|
54
68
|
|
55
|
-
logger
|
69
|
+
@logger = options[:logger] || Logger.new(nil)
|
56
70
|
adapter = options[:adapter] || :net_http
|
57
71
|
connection_options = options[:connection_options] || {ssl: {verify: false}}
|
58
72
|
@username = options[:username] || Zendesk2.defaults[:username]
|
@@ -65,13 +79,13 @@ class Zendesk2::Client < Cistern::Service
|
|
65
79
|
# response
|
66
80
|
builder.use Faraday::Request::BasicAuthentication, @username, password
|
67
81
|
builder.use Faraday::Response::RaiseError
|
68
|
-
builder.use Zendesk2::Logger, logger if logger
|
69
82
|
builder.response :json
|
70
83
|
|
71
84
|
# request
|
72
85
|
builder.request :multipart
|
73
86
|
builder.request :json
|
74
87
|
|
88
|
+
builder.use Zendesk2::Logger, @logger
|
75
89
|
builder.adapter adapter
|
76
90
|
end
|
77
91
|
end
|
@@ -103,6 +117,8 @@ class Zendesk2::Client < Cistern::Service
|
|
103
117
|
:users => {},
|
104
118
|
:organizations => {},
|
105
119
|
:tickets => {},
|
120
|
+
:forums => {},
|
121
|
+
:categories => {},
|
106
122
|
}
|
107
123
|
end
|
108
124
|
|
@@ -181,6 +197,11 @@ class Zendesk2::Client < Cistern::Service
|
|
181
197
|
)
|
182
198
|
end
|
183
199
|
|
200
|
+
def pluralize(word)
|
201
|
+
[[/y$/, 'ies'], [/$/, 's']].find{|regex, replace| word.gsub!(regex, replace) if word.match(regex)}
|
202
|
+
word
|
203
|
+
end
|
204
|
+
|
184
205
|
def response(options={})
|
185
206
|
method = options[:method] || :get
|
186
207
|
status = options[:status] || 200
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Zendesk2::Searchable
|
2
|
+
def self.included(klass)
|
3
|
+
klass.send(:extend, Zendesk2::Searchable::Attributes)
|
4
|
+
end
|
5
|
+
|
6
|
+
def search(parameters)
|
7
|
+
body = connection.search(parameters.merge("type" => self.class.search_type)).body
|
8
|
+
if data = body.delete("results")
|
9
|
+
load(data)
|
10
|
+
end
|
11
|
+
merge_attributes(body)
|
12
|
+
end
|
13
|
+
|
14
|
+
module Attributes
|
15
|
+
attr_accessor :search_type
|
16
|
+
end
|
17
|
+
end
|
data/lib/zendesk2/version.rb
CHANGED
data/lib/zendesk2.rb
CHANGED
@@ -8,11 +8,14 @@ require 'faraday_middleware'
|
|
8
8
|
|
9
9
|
# stdlib
|
10
10
|
require 'time'
|
11
|
+
require 'logger'
|
11
12
|
|
12
13
|
module Zendesk2
|
14
|
+
autoload :Attributes, 'zendesk2/attributes'
|
13
15
|
autoload :Error, 'zendesk2/error'
|
14
16
|
autoload :Client, 'zendesk2/client'
|
15
17
|
autoload :PagedCollection, 'zendesk2/paged_collection'
|
18
|
+
autoload :Searchable, 'zendesk2/searchable'
|
16
19
|
autoload :Logger, 'zendesk2/logger'
|
17
20
|
|
18
21
|
def self.defaults
|
data/spec/forums_spec.rb
ADDED
data/spec/shared/resource.rb
CHANGED
@@ -12,6 +12,7 @@ shared_examples "a resource" do |_collection, _params, _update_params|
|
|
12
12
|
before(:each) do
|
13
13
|
2.times.each { collection.create(instance_exec(&_params)) }
|
14
14
|
end
|
15
|
+
|
15
16
|
it "by retrieving the first page" do
|
16
17
|
collection.all("per_page" => "1").size.should == 1
|
17
18
|
end
|
@@ -42,11 +43,17 @@ shared_examples "a resource" do |_collection, _params, _update_params|
|
|
42
43
|
end
|
43
44
|
|
44
45
|
it "by destroy a record" do
|
46
|
+
pending if _collection == :forums
|
45
47
|
record = collection.create(params)
|
46
48
|
record.identity.should_not be_nil
|
47
49
|
record.destroy
|
48
50
|
record.should be_destroyed
|
49
51
|
end
|
50
52
|
|
51
|
-
|
53
|
+
# Search index takes 2-3 minutes according to the docs
|
54
|
+
it "should search" do
|
55
|
+
pending unless Zendesk2::Client.mocking?
|
56
|
+
record = collection.create(params)
|
57
|
+
collection.search(params).should include(record)
|
58
|
+
end
|
52
59
|
end
|
data/spec/users_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe "users" do
|
|
5
5
|
it_should_behave_like "a resource",
|
6
6
|
:users,
|
7
7
|
lambda { {email: "zendesk2+#{Zendesk2.uuid}@example.org", name: Zendesk2.uuid, verified: true} },
|
8
|
-
|
8
|
+
lambda { {name: Zendesk2.uuid} }
|
9
9
|
|
10
10
|
it "should get current user" do
|
11
11
|
current_user = client.users.current
|
@@ -15,6 +15,14 @@ describe "users" do
|
|
15
15
|
|
16
16
|
describe do
|
17
17
|
let(:user) { client.users.create(email: "zendesk2+#{Zendesk2.uuid}@example.org", name: Zendesk2.uuid) }
|
18
|
+
after(:all) { user.destroy }
|
19
|
+
|
20
|
+
it "should update organization" do
|
21
|
+
organization = client.organizations.create(name: Zendesk2.uuid)
|
22
|
+
user.organization= organization
|
23
|
+
user.save.should be_true
|
24
|
+
user.organization.should == organization
|
25
|
+
end
|
18
26
|
|
19
27
|
it "should get requested tickets" do
|
20
28
|
ticket = client.tickets.create(requester: user, subject: Zendesk2.uuid, description: Zendesk2.uuid)
|
@@ -36,6 +44,12 @@ describe "users" do
|
|
36
44
|
user.should_not be_destroyed
|
37
45
|
end
|
38
46
|
|
47
|
+
it "should hate non-unique emails" do
|
48
|
+
email = "zendesk2+#{Zendesk2.uuid}@example.org"
|
49
|
+
client.users.create(email: email, name: Zendesk2.uuid)
|
50
|
+
lambda { client.users.create(email: email, name: Zendesk2.uuid) }.should raise_exception(Zendesk2::Error)
|
51
|
+
end
|
52
|
+
|
39
53
|
it "should form login url"
|
40
54
|
end
|
41
55
|
end
|
data/zendesk2.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.email = ["me@joshualane.com"]
|
7
7
|
gem.description = %q{Zendesk V2 API client}
|
8
8
|
gem.summary = %q{Zendesk V2 API client}
|
9
|
-
gem.homepage = ""
|
9
|
+
gem.homepage = "http://joshualane.com/zendesk2"
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
12
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
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.0.
|
4
|
+
version: 0.0.14
|
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-07-
|
12
|
+
date: 2012-07-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cistern
|
@@ -91,21 +91,34 @@ files:
|
|
91
91
|
- README.md
|
92
92
|
- Rakefile
|
93
93
|
- lib/zendesk2.rb
|
94
|
+
- lib/zendesk2/attributes.rb
|
94
95
|
- lib/zendesk2/client.rb
|
96
|
+
- lib/zendesk2/client/models/categories.rb
|
97
|
+
- lib/zendesk2/client/models/category.rb
|
98
|
+
- lib/zendesk2/client/models/forum.rb
|
99
|
+
- lib/zendesk2/client/models/forums.rb
|
95
100
|
- lib/zendesk2/client/models/organization.rb
|
96
101
|
- lib/zendesk2/client/models/organizations.rb
|
97
102
|
- lib/zendesk2/client/models/ticket.rb
|
98
103
|
- lib/zendesk2/client/models/tickets.rb
|
99
104
|
- lib/zendesk2/client/models/user.rb
|
100
105
|
- lib/zendesk2/client/models/users.rb
|
106
|
+
- lib/zendesk2/client/requests/create_category.rb
|
107
|
+
- lib/zendesk2/client/requests/create_forum.rb
|
101
108
|
- lib/zendesk2/client/requests/create_organization.rb
|
102
109
|
- lib/zendesk2/client/requests/create_ticket.rb
|
103
110
|
- lib/zendesk2/client/requests/create_user.rb
|
111
|
+
- lib/zendesk2/client/requests/destroy_category.rb
|
112
|
+
- lib/zendesk2/client/requests/destroy_forum.rb
|
104
113
|
- lib/zendesk2/client/requests/destroy_organization.rb
|
105
114
|
- lib/zendesk2/client/requests/destroy_ticket.rb
|
106
115
|
- lib/zendesk2/client/requests/destroy_user.rb
|
116
|
+
- lib/zendesk2/client/requests/get_categories.rb
|
117
|
+
- lib/zendesk2/client/requests/get_category.rb
|
107
118
|
- lib/zendesk2/client/requests/get_ccd_tickets.rb
|
108
119
|
- lib/zendesk2/client/requests/get_current_user.rb
|
120
|
+
- lib/zendesk2/client/requests/get_forum.rb
|
121
|
+
- lib/zendesk2/client/requests/get_forums.rb
|
109
122
|
- lib/zendesk2/client/requests/get_organization.rb
|
110
123
|
- lib/zendesk2/client/requests/get_organization_tickets.rb
|
111
124
|
- lib/zendesk2/client/requests/get_organization_users.rb
|
@@ -116,13 +129,18 @@ files:
|
|
116
129
|
- lib/zendesk2/client/requests/get_user.rb
|
117
130
|
- lib/zendesk2/client/requests/get_users.rb
|
118
131
|
- lib/zendesk2/client/requests/search.rb
|
132
|
+
- lib/zendesk2/client/requests/update_category.rb
|
133
|
+
- lib/zendesk2/client/requests/update_forum.rb
|
119
134
|
- lib/zendesk2/client/requests/update_organization.rb
|
120
135
|
- lib/zendesk2/client/requests/update_ticket.rb
|
121
136
|
- lib/zendesk2/client/requests/update_user.rb
|
122
137
|
- lib/zendesk2/error.rb
|
123
138
|
- lib/zendesk2/logger.rb
|
124
139
|
- lib/zendesk2/paged_collection.rb
|
140
|
+
- lib/zendesk2/searchable.rb
|
125
141
|
- lib/zendesk2/version.rb
|
142
|
+
- spec/categories_spec.rb
|
143
|
+
- spec/forums_spec.rb
|
126
144
|
- spec/organizations_spec.rb
|
127
145
|
- spec/shared/resource.rb
|
128
146
|
- spec/spec_helper.rb
|
@@ -130,7 +148,7 @@ files:
|
|
130
148
|
- spec/tickets_spec.rb
|
131
149
|
- spec/users_spec.rb
|
132
150
|
- zendesk2.gemspec
|
133
|
-
homepage:
|
151
|
+
homepage: http://joshualane.com/zendesk2
|
134
152
|
licenses: []
|
135
153
|
post_install_message:
|
136
154
|
rdoc_options: []
|
@@ -155,6 +173,8 @@ signing_key:
|
|
155
173
|
specification_version: 3
|
156
174
|
summary: Zendesk V2 API client
|
157
175
|
test_files:
|
176
|
+
- spec/categories_spec.rb
|
177
|
+
- spec/forums_spec.rb
|
158
178
|
- spec/organizations_spec.rb
|
159
179
|
- spec/shared/resource.rb
|
160
180
|
- spec/spec_helper.rb
|