tracker_api 1.9.0 → 1.13.0
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/.github/workflows/ruby-tests.yml +34 -0
- data/Gemfile +2 -2
- data/README.md +7 -4
- data/lib/tracker_api.rb +13 -1
- data/lib/tracker_api/client.rb +2 -2
- data/lib/tracker_api/endpoints/attachment.rb +3 -1
- data/lib/tracker_api/endpoints/blockers.rb +20 -0
- data/lib/tracker_api/endpoints/comment.rb +15 -5
- data/lib/tracker_api/endpoints/comments.rb +10 -5
- data/lib/tracker_api/endpoints/iteration.rb +35 -0
- data/lib/tracker_api/endpoints/release.rb +17 -0
- data/lib/tracker_api/endpoints/releases.rb +20 -0
- data/lib/tracker_api/endpoints/review.rb +21 -0
- data/lib/tracker_api/endpoints/reviews.rb +21 -0
- data/lib/tracker_api/endpoints/search.rb +1 -1
- data/lib/tracker_api/endpoints/stories.rb +10 -0
- data/lib/tracker_api/error.rb +12 -2
- data/lib/tracker_api/file_utility.rb +1 -1
- data/lib/tracker_api/resources/blocker.rb +18 -0
- data/lib/tracker_api/resources/comment.rb +2 -2
- data/lib/tracker_api/resources/cycle_time_details.rb +21 -0
- data/lib/tracker_api/resources/daily_history_container.rb +13 -0
- data/lib/tracker_api/resources/epic.rb +10 -1
- data/lib/tracker_api/resources/iteration.rb +14 -0
- data/lib/tracker_api/resources/project.rb +13 -0
- data/lib/tracker_api/resources/release.rb +29 -0
- data/lib/tracker_api/resources/review.rb +35 -0
- data/lib/tracker_api/resources/review_type.rb +15 -0
- data/lib/tracker_api/resources/story.rb +29 -3
- data/lib/tracker_api/version.rb +1 -1
- data/test/client_test.rb +52 -52
- data/test/comment_test.rb +101 -32
- data/test/error_test.rb +8 -2
- data/test/file_attachment_test.rb +2 -2
- data/test/iteration_test.rb +31 -0
- data/test/minitest_helper.rb +7 -4
- data/test/project_test.rb +59 -47
- data/test/release_test.rb +22 -0
- data/test/review_test.rb +27 -0
- data/test/story_test.rb +65 -48
- data/test/task_test.rb +3 -3
- data/test/vcr/cassettes/create_epic_attachments.json +1 -0
- data/test/vcr/cassettes/create_epic_comment.json +1 -0
- data/test/vcr/cassettes/create_epic_comment_with_attachment.json +1 -0
- data/test/vcr/cassettes/create_story_attachments.json +1 -0
- data/test/vcr/cassettes/create_story_comment.json +1 -1
- data/test/vcr/cassettes/create_story_comment_with_attachment.json +1 -0
- data/test/vcr/cassettes/delete_epic_attachments.json +1 -0
- data/test/vcr/cassettes/delete_epic_comment.json +1 -0
- data/test/vcr/cassettes/delete_story_attachments.json +1 -0
- data/test/vcr/cassettes/delete_story_comment.json +1 -0
- data/test/vcr/cassettes/get_current_iteration.json +1 -1
- data/test/vcr/cassettes/get_cycle_time_details.json +1 -0
- data/test/vcr/cassettes/get_daily_history_container.json +1 -0
- data/test/vcr/cassettes/get_epic.json +1 -0
- data/test/vcr/cassettes/get_epic_comments.json +1 -0
- data/test/vcr/cassettes/get_releases.json +1 -0
- data/test/vcr/cassettes/get_story_reviews.json +1 -0
- data/test/vcr/cassettes/release_stories.json +1 -0
- data/test/vcr/cassettes/save_epic_comment.json +1 -0
- data/test/vcr/cassettes/save_review.json +1 -0
- data/test/vcr/cassettes/save_story_comment.json +1 -0
- data/test/vcr/cassettes/search_project.json +1 -1
- data/test/workspace_test.rb +5 -5
- data/tracker_api.gemspec +2 -2
- metadata +63 -8
- data/.travis.yml +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d6e9b2c5ba26b416431288d39fe55c9309b753f8ba59572975cf5f424a328a4
|
|
4
|
+
data.tar.gz: 18f138d620e770815349ddad72c728055c7ca35cfdfa89170daf410c4f3db39e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fbd90b8f2549b18d5d22f4f1dbf743db182db643be68b4920daaff25f68ebdf3664785903118afc106edf44ae58474e54ac1b582e3b063428f7e6c5f47ec1096
|
|
7
|
+
data.tar.gz: ab1c688fbf08697ecb2705031f82a842357756ff812e0295ffd1dcbac43131db038379225e4265bc554fdc16852af8a205a16d2c0a46978024ee4a5a29cae84a
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Ruby Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
ruby-version: [2.7, 2.6, 2.5]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v2
|
|
20
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
|
21
|
+
uses: ruby/setup-ruby@v1
|
|
22
|
+
with:
|
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: bundle install
|
|
26
|
+
- name: Run tests
|
|
27
|
+
run: bundle exec rake test
|
|
28
|
+
- name: Upload Coverage
|
|
29
|
+
uses: paambaati/codeclimate-action@v2.7.5
|
|
30
|
+
env:
|
|
31
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
|
32
|
+
with:
|
|
33
|
+
coverageLocations: ${{github.workspace}}/coverage/.resultset.json:simplecov
|
|
34
|
+
if: matrix.ruby-version == '2.7'
|
data/Gemfile
CHANGED
|
@@ -3,5 +3,5 @@ source 'https://rubygems.org'
|
|
|
3
3
|
# Specify your gem's dependencies in tracker_api.gemspec
|
|
4
4
|
gemspec
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
# pinned until code climate figures out the new output format https://github.com/codeclimate/test-reporter/issues/418
|
|
7
|
+
gem 'simplecov', '< 0.18', require: false, group: :test
|
data/README.md
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
# TrackerApi
|
|
2
2
|
|
|
3
3
|
[](http://badge.fury.io/rb/tracker_api)
|
|
4
|
-
[](https://gemnasium.com/dashofcode/tracker_api)
|
|
4
|
+
[](https://github.com/ProductPlan/tracker_api/actions)
|
|
5
|
+
[](https://codeclimate.com/github/ProductPlan/tracker_api/maintainability)
|
|
6
|
+
[](https://codeclimate.com/github/ProductPlan/tracker_api/test_coverage)
|
|
8
7
|
|
|
9
8
|
This gem allows you to easily use the [Pivotal Tracker v5 API](https://www.pivotaltracker.com/help/api/rest/v5).
|
|
10
9
|
|
|
@@ -86,6 +85,10 @@ task = story.tasks.first # Get
|
|
|
86
85
|
task.complete = true
|
|
87
86
|
task.save # Mark a task complete
|
|
88
87
|
|
|
88
|
+
review = story.reviews.first # Mark a review as complete
|
|
89
|
+
review.status = 'pass'
|
|
90
|
+
review.save
|
|
91
|
+
|
|
89
92
|
epics = project.epics # Get all epics for a project
|
|
90
93
|
epic = epics.first
|
|
91
94
|
label = epic.label # Get an epic's label
|
data/lib/tracker_api.rb
CHANGED
|
@@ -4,7 +4,7 @@ require 'tracker_api/version'
|
|
|
4
4
|
require 'faraday'
|
|
5
5
|
require 'faraday_middleware'
|
|
6
6
|
require 'pathname'
|
|
7
|
-
require '
|
|
7
|
+
require 'mini_mime'
|
|
8
8
|
|
|
9
9
|
if defined?(ActiveSupport)
|
|
10
10
|
require 'active_support/core_ext/object/blank'
|
|
@@ -38,8 +38,10 @@ module TrackerApi
|
|
|
38
38
|
|
|
39
39
|
module Endpoints
|
|
40
40
|
autoload :Activity, 'tracker_api/endpoints/activity'
|
|
41
|
+
autoload :Blockers, 'tracker_api/endpoints/blockers'
|
|
41
42
|
autoload :Epic, 'tracker_api/endpoints/epic'
|
|
42
43
|
autoload :Epics, 'tracker_api/endpoints/epics'
|
|
44
|
+
autoload :Iteration, 'tracker_api/endpoints/iteration'
|
|
43
45
|
autoload :Iterations, 'tracker_api/endpoints/iterations'
|
|
44
46
|
autoload :Labels, 'tracker_api/endpoints/labels'
|
|
45
47
|
autoload :Me, 'tracker_api/endpoints/me'
|
|
@@ -62,6 +64,10 @@ module TrackerApi
|
|
|
62
64
|
autoload :StoryTransitions, 'tracker_api/endpoints/story_transitions'
|
|
63
65
|
autoload :Attachment, 'tracker_api/endpoints/attachment'
|
|
64
66
|
autoload :Attachments, 'tracker_api/endpoints/attachments'
|
|
67
|
+
autoload :Releases, 'tracker_api/endpoints/releases'
|
|
68
|
+
autoload :Release, 'tracker_api/endpoints/release'
|
|
69
|
+
autoload :Review, 'tracker_api/endpoints/review'
|
|
70
|
+
autoload :Reviews, 'tracker_api/endpoints/reviews'
|
|
65
71
|
end
|
|
66
72
|
|
|
67
73
|
module Resources
|
|
@@ -71,6 +77,7 @@ module TrackerApi
|
|
|
71
77
|
end
|
|
72
78
|
autoload :Activity, 'tracker_api/resources/activity'
|
|
73
79
|
autoload :Account, 'tracker_api/resources/account'
|
|
80
|
+
autoload :Blocker, 'tracker_api/resources/blocker'
|
|
74
81
|
autoload :Change, 'tracker_api/resources/change'
|
|
75
82
|
autoload :Epic, 'tracker_api/resources/epic'
|
|
76
83
|
autoload :EpicsSearchResult, 'tracker_api/resources/epics_search_result'
|
|
@@ -93,5 +100,10 @@ module TrackerApi
|
|
|
93
100
|
autoload :Webhook, 'tracker_api/resources/webhook'
|
|
94
101
|
autoload :StoryTransition, 'tracker_api/resources/story_transition'
|
|
95
102
|
autoload :FileAttachment, 'tracker_api/resources/file_attachment'
|
|
103
|
+
autoload :Release, 'tracker_api/resources/release'
|
|
104
|
+
autoload :CycleTimeDetails, 'tracker_api/resources/cycle_time_details'
|
|
105
|
+
autoload :DailyHistoryContainer, 'tracker_api/resources/daily_history_container'
|
|
106
|
+
autoload :Review, 'tracker_api/resources/review'
|
|
107
|
+
autoload :ReviewType, 'tracker_api/resources/review_type'
|
|
96
108
|
end
|
|
97
109
|
end
|
data/lib/tracker_api/client.rb
CHANGED
|
@@ -25,7 +25,7 @@ module TrackerApi
|
|
|
25
25
|
@url = Addressable::URI.parse(url).to_s
|
|
26
26
|
@api_version = options.fetch(:api_version, '/services/v5')
|
|
27
27
|
@logger = options.fetch(:logger, ::Logger.new(nil))
|
|
28
|
-
adapter = options.fetch(:adapter
|
|
28
|
+
adapter = options.fetch(:adapter) { defined?(JRUBY_VERSION) ? :net_http : :excon }
|
|
29
29
|
connection_options = options.fetch(:connection_options, { ssl: { verify: true } })
|
|
30
30
|
@auto_paginate = options.fetch(:auto_paginate, true)
|
|
31
31
|
@token = options[:token]
|
|
@@ -223,7 +223,7 @@ module TrackerApi
|
|
|
223
223
|
req.body = body
|
|
224
224
|
end
|
|
225
225
|
response
|
|
226
|
-
rescue Faraday::
|
|
226
|
+
rescue Faraday::ClientError, Faraday::ServerError => e
|
|
227
227
|
status_code = e.response[:status]
|
|
228
228
|
case status_code
|
|
229
229
|
when 400..499 then raise TrackerApi::Errors::ClientError.new(e)
|
|
@@ -19,7 +19,9 @@ module TrackerApi
|
|
|
19
19
|
# end
|
|
20
20
|
|
|
21
21
|
def get(comment)
|
|
22
|
-
|
|
22
|
+
comment_target_slug = !comment.story_id.nil? ? "stories/#{comment.story_id}" : "epics/#{comment.epic_id}"
|
|
23
|
+
|
|
24
|
+
data = client.get("/projects/#{comment.project_id}/#{comment_target_slug}/comments/#{comment.id}?fields=file_attachments").body["file_attachments"]
|
|
23
25
|
raise Errors::UnexpectedData, 'Array of file attachments expected' unless data.is_a? Array
|
|
24
26
|
|
|
25
27
|
data.map do |file_attachment|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module TrackerApi
|
|
2
|
+
module Endpoints
|
|
3
|
+
class Blockers
|
|
4
|
+
attr_accessor :client
|
|
5
|
+
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def get(project_id, story_id, params = {})
|
|
11
|
+
data = client.get("/projects/#{project_id}/stories/#{story_id}/blockers", params: params).body
|
|
12
|
+
raise Errors::UnexpectedData, 'Array of Blockers expected' unless data.is_a? Array
|
|
13
|
+
|
|
14
|
+
data.map do |blocker|
|
|
15
|
+
Resources::Blocker.new({ client: client, project_id: project_id }.merge(blocker))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -7,16 +7,24 @@ module TrackerApi
|
|
|
7
7
|
@client = client
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def create(project_id, story_id, params
|
|
11
|
-
|
|
10
|
+
def create(project_id, story_id: nil, epic_id: nil, params: {})
|
|
11
|
+
raise ArgumentError, 'One of story id or epic id must be provided.' if story_id.nil? && epic_id.nil?
|
|
12
|
+
|
|
13
|
+
comment_target_slug = !story_id.nil? ? "stories/#{story_id}" : "epics/#{epic_id}"
|
|
14
|
+
|
|
15
|
+
data = client.post("/projects/#{project_id}/#{comment_target_slug}/comments", params: params).body
|
|
12
16
|
Resources::Comment.new({ client: client, project_id: project_id }.merge(data))
|
|
13
17
|
end
|
|
14
18
|
|
|
15
19
|
def update(comment, params={})
|
|
16
20
|
raise ArgumentError, 'Valid comment required to update.' unless comment.instance_of?(Resources::Comment)
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
comment_target_slug = !comment.story_id.nil? ? "stories/#{comment.story_id}" : "epics/#{comment.epic_id}"
|
|
23
|
+
|
|
24
|
+
path = "/projects/#{comment.project_id}/#{comment_target_slug}/comments/#{comment.id}"
|
|
25
|
+
if params.represented.file_attachment_ids_to_add.present? || params.represented.file_attachment_ids_to_remove.present?
|
|
26
|
+
path += "?fields=:default,file_attachments"
|
|
27
|
+
end
|
|
20
28
|
data = client.put(path, params: params).body
|
|
21
29
|
|
|
22
30
|
comment.attributes = data
|
|
@@ -27,7 +35,9 @@ module TrackerApi
|
|
|
27
35
|
def delete(comment)
|
|
28
36
|
raise ArgumentError, 'Valid comment required to update.' unless comment.instance_of?(Resources::Comment)
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
comment_target_slug = !comment.story_id.nil? ? "stories/#{comment.story_id}" : "epics/#{comment.epic_id}"
|
|
39
|
+
|
|
40
|
+
client.delete("/projects/#{comment.project_id}/#{comment_target_slug}/comments/#{comment.id}").body
|
|
31
41
|
end
|
|
32
42
|
end
|
|
33
43
|
end
|
|
@@ -7,14 +7,19 @@ module TrackerApi
|
|
|
7
7
|
@client = client
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def get(project_id, story_id, params
|
|
11
|
-
|
|
10
|
+
def get(project_id, story_id: nil, epic_id: nil, params: {})
|
|
11
|
+
raise ArgumentError, 'One of story id or epic id must be provided.' if story_id.nil? && epic_id.nil?
|
|
12
|
+
|
|
13
|
+
comment_target_slug = !story_id.nil? ? "stories/#{story_id}" : "epics/#{epic_id}"
|
|
14
|
+
|
|
15
|
+
data = client.paginate("/projects/#{project_id}/#{comment_target_slug}/comments", params: params)
|
|
12
16
|
raise Errors::UnexpectedData, 'Array of comments expected' unless data.is_a? Array
|
|
13
17
|
|
|
14
18
|
data.map do |comment|
|
|
15
|
-
Resources::Comment.new({
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
Resources::Comment.new({
|
|
20
|
+
client: client,
|
|
21
|
+
project_id: project_id
|
|
22
|
+
}.merge(comment))
|
|
18
23
|
end
|
|
19
24
|
end
|
|
20
25
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module TrackerApi
|
|
2
|
+
module Endpoints
|
|
3
|
+
class Iteration
|
|
4
|
+
attr_accessor :client
|
|
5
|
+
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def get(project_id, iteration_number)
|
|
11
|
+
data = client.get("/projects/#{project_id}/iterations/#{iteration_number}").body
|
|
12
|
+
|
|
13
|
+
Resources::Iteration.new({ client: client, project_id: project_id }.merge(data))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def get_analytics_cycle_time_details(project_id, iteration_number)
|
|
17
|
+
data = client.paginate("/projects/#{project_id}/iterations/#{iteration_number}/analytics/cycle_time_details")
|
|
18
|
+
raise Errors::UnexpectedData, 'Array of cycle time details expected' unless data.is_a? Array
|
|
19
|
+
|
|
20
|
+
data.map do |cycle_time_details|
|
|
21
|
+
Resources::CycleTimeDetails.new(
|
|
22
|
+
{ project_id: project_id, iteration_number: iteration_number }.merge(cycle_time_details)
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def get_history(project_id, iteration_number)
|
|
28
|
+
data = client.get("/projects/#{project_id}/history/iterations/#{iteration_number}/days").body
|
|
29
|
+
raise Errors::UnexpectedData, 'Hash of history data expected' unless data.is_a? Hash
|
|
30
|
+
|
|
31
|
+
Resources::DailyHistoryContainer.new({ project_id: project_id, iteration_number: iteration_number }.merge(data))
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module TrackerApi
|
|
2
|
+
module Endpoints
|
|
3
|
+
class Release
|
|
4
|
+
attr_accessor :client
|
|
5
|
+
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def get(project_id, id, params={})
|
|
11
|
+
data = client.get("/projects/#{project_id}/releases/#{id}", params: params).body
|
|
12
|
+
|
|
13
|
+
Resources::Release.new({ client: client }.merge(data))
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module TrackerApi
|
|
2
|
+
module Endpoints
|
|
3
|
+
class Releases
|
|
4
|
+
attr_accessor :client
|
|
5
|
+
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def get(project_id, params={})
|
|
11
|
+
data = client.paginate("/projects/#{project_id}/releases", params: params)
|
|
12
|
+
raise Errors::UnexpectedData, 'Array of releases expected' unless data.is_a? Array
|
|
13
|
+
|
|
14
|
+
data.map do |release|
|
|
15
|
+
Resources::Release.new({ client: client, project_id: project_id }.merge(release))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module TrackerApi
|
|
2
|
+
module Endpoints
|
|
3
|
+
class Review
|
|
4
|
+
attr_accessor :client
|
|
5
|
+
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def update(review, params = {})
|
|
11
|
+
raise ArgumentError, 'Valid review required to update.' unless review.instance_of?(Resources::Review)
|
|
12
|
+
|
|
13
|
+
data = client.put("/projects/#{review.project_id}/stories/#{review.story_id}/reviews/#{review.id}", params: params).body
|
|
14
|
+
|
|
15
|
+
review.attributes = data
|
|
16
|
+
review.clean!
|
|
17
|
+
review
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module TrackerApi
|
|
2
|
+
module Endpoints
|
|
3
|
+
class Reviews
|
|
4
|
+
attr_accessor :client
|
|
5
|
+
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def get(project_id, story_id, params={})
|
|
11
|
+
params[:fields] ||= ":default,review_type"
|
|
12
|
+
data = client.paginate("/projects/#{project_id}/stories/#{story_id}/reviews", params: params)
|
|
13
|
+
raise Errors::UnexpectedData, 'Successful responses to this request return an array containing zero or more instances of the review resource. This response was not an array.' unless data.is_a? Array
|
|
14
|
+
|
|
15
|
+
data.map do |review|
|
|
16
|
+
Resources::Review.new({ client: client, project_id: project_id }.merge(review))
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -10,7 +10,7 @@ module TrackerApi
|
|
|
10
10
|
def get(project_id, query, options={})
|
|
11
11
|
raise ArgumentError, 'Valid query string required to search' unless query.is_a?(String)
|
|
12
12
|
|
|
13
|
-
options
|
|
13
|
+
options[:params] = { query: query }
|
|
14
14
|
data = client.get("/projects/#{project_id}/search", options).body
|
|
15
15
|
|
|
16
16
|
raise Errors::UnexpectedData, 'Hash of search results expect' unless data.is_a? Hash
|
|
@@ -17,6 +17,16 @@ module TrackerApi
|
|
|
17
17
|
Resources::Story.new({ client: client, project_id: project_id }.merge(story))
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
|
+
|
|
21
|
+
def get_release(project_id, release_id, params={})
|
|
22
|
+
data = client.paginate("/projects/#{project_id}/releases/#{release_id}/stories", params: params)
|
|
23
|
+
|
|
24
|
+
raise Errors::UnexpectedData, 'Array of stories expected' unless data.is_a? Array
|
|
25
|
+
|
|
26
|
+
data.map do |story|
|
|
27
|
+
Resources::Story.new({ client: client, project_id: project_id }.merge(story))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
20
30
|
end
|
|
21
31
|
end
|
|
22
32
|
end
|
data/lib/tracker_api/error.rb
CHANGED
|
@@ -5,14 +5,24 @@ module TrackerApi
|
|
|
5
5
|
def initialize(wrapped_exception)
|
|
6
6
|
@wrapped_exception = wrapped_exception
|
|
7
7
|
@response = wrapped_exception.response
|
|
8
|
-
message = if wrapped_exception.is_a?(Faraday::
|
|
8
|
+
message = if wrapped_exception.is_a?(Faraday::ParsingError)
|
|
9
9
|
wrapped_exception.message
|
|
10
|
-
elsif
|
|
10
|
+
elsif faraday_response_error?(wrapped_exception)
|
|
11
11
|
wrapped_exception.response.inspect
|
|
12
12
|
else
|
|
13
13
|
wrapped_exception.instance_variable_get(:@wrapped_exception).inspect
|
|
14
14
|
end
|
|
15
15
|
super(message)
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
# faraday 16.0 re-organized their errors. The errors we're interested in,
|
|
21
|
+
# Faraday::ClientError before 16.0 and Faraday::ServerError introduced in
|
|
22
|
+
# 16.0, are represented by this conditional.
|
|
23
|
+
def faraday_response_error?(wrapped_exception)
|
|
24
|
+
wrapped_exception.is_a?(Faraday::Error) &&
|
|
25
|
+
wrapped_exception.respond_to?(:response)
|
|
26
|
+
end
|
|
17
27
|
end
|
|
18
28
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module TrackerApi
|
|
2
|
+
module Resources
|
|
3
|
+
class Blocker
|
|
4
|
+
include Shared::Base
|
|
5
|
+
|
|
6
|
+
attribute :client
|
|
7
|
+
attribute :project_id, Integer
|
|
8
|
+
|
|
9
|
+
attribute :story_id, Integer
|
|
10
|
+
attribute :person_id, Integer
|
|
11
|
+
attribute :description, String
|
|
12
|
+
attribute :resolved, Boolean
|
|
13
|
+
attribute :created_at, DateTime
|
|
14
|
+
attribute :updated_at, DateTime
|
|
15
|
+
attribute :kind, String
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|