bugherd_client 0.0.6 → 0.0.8
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +2 -1
- data/.travis.yml +4 -1
- data/README.md +23 -38
- data/Rakefile +6 -1
- data/bin/console +17 -0
- data/bugherd_client.gemspec +17 -13
- data/lib/bugherd_client.rb +19 -16
- data/lib/bugherd_client/client.rb +44 -18
- data/lib/bugherd_client/errors.rb +19 -5
- data/lib/bugherd_client/resources/v1/base.rb +2 -2
- data/lib/bugherd_client/resources/v1/comment.rb +1 -1
- data/lib/bugherd_client/resources/v1/project.rb +4 -4
- data/lib/bugherd_client/resources/v1/task.rb +11 -8
- data/lib/bugherd_client/resources/v2/attachment.rb +73 -0
- data/lib/bugherd_client/resources/v2/base.rb +24 -5
- data/lib/bugherd_client/resources/v2/comment.rb +2 -2
- data/lib/bugherd_client/resources/v2/organization.rb +5 -5
- data/lib/bugherd_client/resources/v2/project.rb +22 -13
- data/lib/bugherd_client/resources/v2/task.rb +34 -14
- data/lib/bugherd_client/resources/v2/webhook.rb +54 -0
- data/lib/bugherd_client/version.rb +1 -1
- data/spec/bugherd_client/client_spec.rb +63 -11
- data/spec/bugherd_client/v2/organization_spec.rb +21 -0
- data/spec/bugherd_client/v2/project_spec.rb +66 -0
- data/spec/bugherd_client/v2/task_spec.rb +46 -0
- data/spec/bugherd_client/v2/user_spec.rb +50 -0
- data/spec/bugherd_client/v2/webhook_spec.rb +20 -0
- data/spec/cassettes/guests_all.yml +64 -0
- data/spec/cassettes/members_all.yml +66 -0
- data/spec/cassettes/organizations_get.yml +62 -0
- data/spec/cassettes/projects_active.yml +65 -0
- data/spec/cassettes/projects_all.yml +65 -0
- data/spec/cassettes/projects_find_failure.yml +60 -0
- data/spec/cassettes/projects_find_success.yml +65 -0
- data/spec/cassettes/tasks_all.yml +87 -0
- data/spec/cassettes/tasks_find_success.yml +69 -0
- data/spec/cassettes/users_all.yml +66 -0
- data/spec/cassettes/webhooks_all.yml +64 -0
- data/spec/spec_helper.rb +23 -9
- data/spec/support/http_helper.rb +7 -0
- metadata +130 -23
@@ -12,7 +12,7 @@ module BugherdClient
|
|
12
12
|
STATUSES = ['feedback', 'backlog','todo','doing','done','closed']
|
13
13
|
STATUSES.each.with_index do |status, index|
|
14
14
|
if index == 0
|
15
|
-
Task.const_set("STATUS_#{status.upcase}", nil)
|
15
|
+
Task.const_set("STATUS_#{status.upcase}", nil)
|
16
16
|
else
|
17
17
|
Task.const_set("STATUS_#{status.upcase}", index-1)
|
18
18
|
end
|
@@ -37,15 +37,15 @@ module BugherdClient
|
|
37
37
|
|
38
38
|
#
|
39
39
|
# Create a new Task
|
40
|
-
# attributes:
|
41
|
-
# description, priority, status, tag_names(Array),
|
42
|
-
# requester_id or requester_email,
|
40
|
+
# attributes:
|
41
|
+
# description, priority, status, tag_names(Array),
|
42
|
+
# requester_id or requester_email,
|
43
43
|
# assigned_to_id or assigned_to_email
|
44
44
|
# external_id
|
45
45
|
# if status is null the Task is automatically put in the Feedback panel
|
46
|
-
#
|
47
|
-
# Values for
|
48
|
-
# Values for
|
46
|
+
# 'requester_email' can be any email address while 'assigned_to_email' needs to be of a current project member.
|
47
|
+
# Values for 'priority' are not set, critical, important, normal, and minor.
|
48
|
+
# Values for 'status' are backlog, todo, doing, done, and closed. Omit this field or set as 'null' to send tasks to the Feedback panel.
|
49
49
|
# External ID is an API-only field. It cannot be set from the BugHerd application, only using the API. An external ID can be used to track originating IDs from other systems in BugHerd bugs.
|
50
50
|
def create(project_id, attributes={})
|
51
51
|
raw_response = post_request("projects/#{project_id}/tasks", task: attributes)
|
@@ -57,8 +57,11 @@ module BugherdClient
|
|
57
57
|
parse_response(raw_response)
|
58
58
|
end
|
59
59
|
|
60
|
+
def delete(project_id, task_id)
|
61
|
+
end
|
62
|
+
|
60
63
|
end
|
61
64
|
|
62
65
|
end
|
63
66
|
end
|
64
|
-
end
|
67
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module BugherdClient
|
2
|
+
module Resources
|
3
|
+
module V2
|
4
|
+
|
5
|
+
class Attachment < Base
|
6
|
+
|
7
|
+
# LIST
|
8
|
+
#
|
9
|
+
# Get a paginated list of attachments for a task.
|
10
|
+
# GET /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments.json
|
11
|
+
def all(project_id, task_id)
|
12
|
+
raw_response = get_request("projects/#{project_id}/tasks/#{task_id}/attachments")
|
13
|
+
parse_response(raw_response, :attachments)
|
14
|
+
end
|
15
|
+
|
16
|
+
# SHOW
|
17
|
+
#
|
18
|
+
# Get detail for specific attachment.
|
19
|
+
# GET /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments/#{id}.json
|
20
|
+
def find(project_id, task_id, attachment_id)
|
21
|
+
raw_response = get_request("projects/#{project_id}/tasks/#{task_id}/attachments/#{attachment_id}")
|
22
|
+
parse_response(raw_response)
|
23
|
+
end
|
24
|
+
|
25
|
+
# CREATE
|
26
|
+
#
|
27
|
+
# Adds a new attachment to the specified task using an existing URL.
|
28
|
+
# POST /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments.json
|
29
|
+
#
|
30
|
+
# PARAMS
|
31
|
+
# {'attachment':{
|
32
|
+
# 'file_name':'resolution.gif',
|
33
|
+
# 'url':'http://i.imgur.com/U9h3jZI.gif'
|
34
|
+
# }}
|
35
|
+
def create(project_id, task_id, payload)
|
36
|
+
raw_response = post_request("projects/#{project_id}/tasks/#{task_id}/attachments", attachment: payload)
|
37
|
+
parse_response(raw_response, :attachment)
|
38
|
+
end
|
39
|
+
|
40
|
+
# UPLOAD
|
41
|
+
#
|
42
|
+
# Upload a new attachment and add it to the specified task.
|
43
|
+
# The file contents need to be specified as the POST data on this request.
|
44
|
+
#
|
45
|
+
# Note that your upload needs to be reasonable in size as the maximum time the request
|
46
|
+
# may take is around 30 seconds.
|
47
|
+
# If you have larger uploads please create arrange your own file upload
|
48
|
+
# and create the attachment from a URL instead.
|
49
|
+
#
|
50
|
+
# POST /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments/upload
|
51
|
+
#
|
52
|
+
# Note in the sample below please specify an existing file name.
|
53
|
+
def upload(project_id, task_id, payload)
|
54
|
+
uri = "projects/#{project_id}/tasks/#{task_id}/attachments/upload"
|
55
|
+
headers = { content_type: 'application/binary' }
|
56
|
+
raw_response = post_request(uri, payload.merge(headers: headers))
|
57
|
+
parse_response(raw_response, :attachment)
|
58
|
+
end
|
59
|
+
|
60
|
+
# DELETE
|
61
|
+
#
|
62
|
+
# Delete an attachment from a task. Note that this action is permanent and cannot be undone.
|
63
|
+
# DELETE /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments/#{id}.json
|
64
|
+
def delete(project_id, task_id, attachment_id)
|
65
|
+
raw_response = delete_request("projects/#{project_id}/tasks/#{task_id}/attachments/#{attachment_id}")
|
66
|
+
parse_response(raw_response)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end # V2
|
72
|
+
end # Resources
|
73
|
+
end # BugherdClient
|
@@ -18,16 +18,22 @@ module BugherdClient
|
|
18
18
|
self.class.instance_methods(false)
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
# store a reference to the HTTP connection
|
22
|
+
attr_accessor :connection
|
23
|
+
|
24
|
+
attr_accessor :options
|
25
|
+
|
22
26
|
def initialize(conn, opts={})
|
23
27
|
@connection, @options = conn, opts
|
24
28
|
end
|
25
29
|
|
26
|
-
def send_request(method=
|
30
|
+
def send_request(method='GET', path='', params={}, headers={})
|
27
31
|
headers = DEFAULT_HEADER_ATTRS.merge(headers)
|
28
32
|
params.merge!(headers)
|
29
33
|
method_name = method.to_s.downcase
|
30
34
|
self.connection[path].__send__(method_name, params)
|
35
|
+
rescue RestClient::Exception => e
|
36
|
+
raise(BugherdClient::Errors::HttpRequestError.new(e.message, e.http_code))
|
31
37
|
end
|
32
38
|
|
33
39
|
[:get, :post, :put, :patch, :delete].each do |method_name|
|
@@ -36,16 +42,29 @@ module BugherdClient
|
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
45
|
+
def converter(body)
|
46
|
+
case body
|
47
|
+
when Hash
|
48
|
+
::Hashie::Mash.new(body)
|
49
|
+
when Array
|
50
|
+
body.map { |item| item.is_a?(Hash) ? converter(item) : item }
|
51
|
+
else
|
52
|
+
body
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
39
56
|
def parse_response(response, root_element=nil)
|
40
|
-
if root_element
|
41
|
-
JSON.parse(response)
|
57
|
+
parsed = if root_element
|
58
|
+
p = JSON.parse(response)
|
59
|
+
p.key?(root_element.to_s) ? p[root_element.to_s] : p
|
42
60
|
else
|
43
61
|
JSON.parse(response)
|
44
62
|
end
|
63
|
+
converter(parsed)
|
45
64
|
end
|
46
65
|
|
47
66
|
end
|
48
67
|
|
49
68
|
end
|
50
69
|
end
|
51
|
-
end
|
70
|
+
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
module BugherdClient
|
2
2
|
module Resources
|
3
3
|
module V2
|
4
|
-
|
4
|
+
|
5
5
|
class Organization < Base
|
6
6
|
|
7
7
|
#
|
8
8
|
# Get more detail of your account.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
def get
|
11
11
|
raw_response = self.connection['organization'].get
|
12
12
|
parse_response(raw_response, :organization)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
16
|
+
end # V2
|
17
|
+
end # Resources
|
18
|
+
end # BugherdClient
|
@@ -6,7 +6,7 @@ module BugherdClient
|
|
6
6
|
|
7
7
|
#
|
8
8
|
# Get more detail of your account.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
def all
|
11
11
|
raw_response = get_request('projects')
|
12
12
|
parse_response(raw_response, :projects)
|
@@ -14,18 +14,27 @@ module BugherdClient
|
|
14
14
|
|
15
15
|
#
|
16
16
|
# Show details for a specific project
|
17
|
-
#
|
17
|
+
#
|
18
18
|
def find(project_id)
|
19
19
|
raw_response = get_request("projects/#{project_id}")
|
20
20
|
parse_response(raw_response, :project)
|
21
21
|
end
|
22
22
|
|
23
|
+
# CREATE
|
24
|
+
#
|
25
|
+
# Create a new project. The project will initially have no members.
|
26
|
+
# POST /api_v2/projects.json
|
27
|
+
#
|
28
|
+
# PARAMS:
|
29
|
+
# {
|
30
|
+
# "name": "My Website",
|
31
|
+
# "devurl": "http://www.example.com",
|
32
|
+
# "is_active": true,
|
33
|
+
# "is_public": false
|
34
|
+
# }
|
23
35
|
#
|
24
|
-
# Create a Project, will initially have no members
|
25
|
-
# attributes: name, devurl, is_public, is_active
|
26
|
-
#
|
27
36
|
def create(attributes={})
|
28
|
-
raw_response = post_request(
|
37
|
+
raw_response = post_request('projects', project: attributes)
|
29
38
|
parse_response(raw_response, :project)
|
30
39
|
end
|
31
40
|
|
@@ -37,7 +46,7 @@ module BugherdClient
|
|
37
46
|
parse_response(raw_response, :project)
|
38
47
|
end
|
39
48
|
|
40
|
-
#
|
49
|
+
#
|
41
50
|
# Delete a project and all associated data. Use with care, deleted projects cannot be recovered.
|
42
51
|
# API: 1,2
|
43
52
|
def delete(project_id)
|
@@ -45,7 +54,7 @@ module BugherdClient
|
|
45
54
|
parse_response(raw_response)
|
46
55
|
end
|
47
56
|
|
48
|
-
#
|
57
|
+
#
|
49
58
|
# Add an existing guest to a project, or invite someone by email address.
|
50
59
|
# required: project_id
|
51
60
|
# attributes: user_id, email
|
@@ -55,11 +64,11 @@ module BugherdClient
|
|
55
64
|
parse_response(raw_response)
|
56
65
|
end
|
57
66
|
|
58
|
-
#
|
67
|
+
#
|
59
68
|
# Add an existing guest to a project, or invite someone by email address.
|
60
69
|
# required: project_id
|
61
70
|
# attributes: user_id
|
62
|
-
#
|
71
|
+
#
|
63
72
|
def add_member(project_id, attributes={})
|
64
73
|
raw_response = post_request("projects/#{project_id}/add_member", attributes)
|
65
74
|
parse_response(raw_response)
|
@@ -68,13 +77,13 @@ module BugherdClient
|
|
68
77
|
|
69
78
|
#
|
70
79
|
# Get all active projects
|
71
|
-
#
|
80
|
+
#
|
72
81
|
def active
|
73
82
|
raw_response = get_request('projects/active')
|
74
83
|
parse_response(raw_response, :projects)
|
75
84
|
end
|
76
85
|
end
|
77
|
-
|
86
|
+
|
78
87
|
end
|
79
88
|
end
|
80
|
-
end
|
89
|
+
end
|
@@ -5,20 +5,31 @@ module BugherdClient
|
|
5
5
|
class Task < Base
|
6
6
|
|
7
7
|
PRIORITIES = ['not set', 'critical', 'important', 'normal','minor']
|
8
|
-
PRIORITIES.each
|
9
|
-
|
8
|
+
PRIORITIES.each { |p| Task.const_set("PRIORITY_#{p.gsub(' ', '').upcase}", p) }
|
9
|
+
def priorities
|
10
|
+
self.class::PRIORITIES
|
10
11
|
end
|
11
12
|
|
12
|
-
STATUSES
|
13
|
-
STATUSES.each
|
14
|
-
|
13
|
+
STATUSES = ['backlog','todo','doing','done','closed']
|
14
|
+
STATUSES.each { |s| Task.const_set("STATUS_#{s.upcase}", s) }
|
15
|
+
def statuses
|
16
|
+
self.class::STATUSES
|
15
17
|
end
|
16
18
|
|
19
|
+
VALID_QUERY_KEYS = [:page, :updated_since, :created_since, :status, :priority, :assigned_to_id, :external_id]
|
20
|
+
|
17
21
|
#
|
18
22
|
# Get a full list of tasks for a project, including archived tasks.
|
19
|
-
# filters: updated_since, created_since, status, priority, tag
|
23
|
+
# filters: updated_since, created_since, status, priority, tag,
|
24
|
+
# assigned_to_id, and external_id.
|
25
|
+
#
|
26
|
+
# example:
|
27
|
+
#
|
28
|
+
# client.tasks.all(45, { status: 'backlog' })
|
29
|
+
#
|
20
30
|
def all(project_id, filter_attributes={})
|
21
31
|
params = filter_attributes.empty? ? {} : { params: filter_attributes }
|
32
|
+
validate_filter_attributes!(filter_attributes) unless filter_attributes.empty?
|
22
33
|
raw_response = get_request("projects/#{project_id}/tasks", params)
|
23
34
|
parse_response(raw_response, :tasks)
|
24
35
|
end
|
@@ -28,20 +39,20 @@ module BugherdClient
|
|
28
39
|
#
|
29
40
|
def find(project_id, task_id)
|
30
41
|
raw_response = get_request("projects/#{project_id}/tasks/#{task_id}")
|
31
|
-
parse_response(raw_response)
|
42
|
+
parse_response(raw_response, :task)
|
32
43
|
end
|
33
44
|
|
34
45
|
#
|
35
46
|
# Create a new Task
|
36
|
-
# attributes:
|
37
|
-
# description, priority, status, tag_names(Array),
|
38
|
-
# requester_id or requester_email,
|
47
|
+
# attributes:
|
48
|
+
# description, priority, status, tag_names(Array),
|
49
|
+
# requester_id or requester_email,
|
39
50
|
# assigned_to_id or assigned_to_email
|
40
51
|
# external_id
|
41
52
|
# if status is null the Task is automatically put in the Feedback panel
|
42
|
-
#
|
43
|
-
# Values for
|
44
|
-
# Values for
|
53
|
+
# 'requester_email' can be any email address while 'assigned_to_email' needs to be of a current project member.
|
54
|
+
# Values for 'priority' are not set, critical, important, normal, and minor.
|
55
|
+
# Values for 'status' are backlog, todo, doing, done, and closed. Omit this field or set as 'null' to send tasks to the Feedback panel.
|
45
56
|
# External ID is an API-only field. It cannot be set from the BugHerd application, only using the API. An external ID can be used to track originating IDs from other systems in BugHerd bugs.
|
46
57
|
def create(project_id, attributes={})
|
47
58
|
raw_response = post_request("projects/#{project_id}/tasks", task: attributes)
|
@@ -53,8 +64,17 @@ module BugherdClient
|
|
53
64
|
parse_response(raw_response)
|
54
65
|
end
|
55
66
|
|
67
|
+
private
|
68
|
+
def validate_filter_attributes!(input_filters = {})
|
69
|
+
input_filters.keys.compact.each do |k|
|
70
|
+
unless VALID_QUERY_KEYS.include?(k.to_sym)
|
71
|
+
raise(BugherdClient::Errors::InvalidQueryKey.new(k, VALID_QUERY_KEYS))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
56
76
|
end
|
57
77
|
|
58
78
|
end
|
59
79
|
end
|
60
|
-
end
|
80
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module BugherdClient
|
2
|
+
module Resources
|
3
|
+
module V2
|
4
|
+
class Webhook < Base
|
5
|
+
|
6
|
+
EVENTS = ['task_create', 'task_update', 'task_destroy', 'comment']
|
7
|
+
def events
|
8
|
+
self.class::EVENTS
|
9
|
+
end
|
10
|
+
|
11
|
+
# LIST
|
12
|
+
#
|
13
|
+
# Get a list of currently installed webhooks.
|
14
|
+
#
|
15
|
+
# GET /api_v2/webhooks.json
|
16
|
+
def all
|
17
|
+
raw_response = get_request('webhooks')
|
18
|
+
parse_response(raw_response, :webhooks)
|
19
|
+
end
|
20
|
+
|
21
|
+
# CREATE
|
22
|
+
#
|
23
|
+
# When installing a webhook, specify an event you wish to hook into.
|
24
|
+
# Choose from: 'task_create', 'task_update', 'comment' or 'task_destroy'.
|
25
|
+
# To get activity for all 3 events, create an entry for each event.
|
26
|
+
#
|
27
|
+
# 'project_id' is optional; it only needs to be specified if you'd only like
|
28
|
+
# events on a specific project. Omitting 'project_id' results in notifications
|
29
|
+
# of activity on all your projects.
|
30
|
+
#
|
31
|
+
# PARAMS
|
32
|
+
# {
|
33
|
+
# 'project_id':1,
|
34
|
+
# 'target_url':'https://app.example.com/api/bugherd_sync/project/1/task_create',
|
35
|
+
# 'event':'task_create'
|
36
|
+
# }
|
37
|
+
#
|
38
|
+
def create(payload = {})
|
39
|
+
raw_response = post_request('webhooks', payload)
|
40
|
+
parse_response(raw_response, :webhook)
|
41
|
+
end
|
42
|
+
|
43
|
+
# DELETE
|
44
|
+
#
|
45
|
+
# DELETE /api_v2/webhooks/#{id}.json
|
46
|
+
def delete(webhook_id)
|
47
|
+
raw_response = delete_request("webhooks/#{webhook_id}")
|
48
|
+
parse_response(raw_response)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end # V2
|
53
|
+
end # Resources
|
54
|
+
end # BugherdClient
|