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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tests.yml +34 -0
  3. data/Gemfile +2 -2
  4. data/README.md +7 -4
  5. data/lib/tracker_api.rb +13 -1
  6. data/lib/tracker_api/client.rb +2 -2
  7. data/lib/tracker_api/endpoints/attachment.rb +3 -1
  8. data/lib/tracker_api/endpoints/blockers.rb +20 -0
  9. data/lib/tracker_api/endpoints/comment.rb +15 -5
  10. data/lib/tracker_api/endpoints/comments.rb +10 -5
  11. data/lib/tracker_api/endpoints/iteration.rb +35 -0
  12. data/lib/tracker_api/endpoints/release.rb +17 -0
  13. data/lib/tracker_api/endpoints/releases.rb +20 -0
  14. data/lib/tracker_api/endpoints/review.rb +21 -0
  15. data/lib/tracker_api/endpoints/reviews.rb +21 -0
  16. data/lib/tracker_api/endpoints/search.rb +1 -1
  17. data/lib/tracker_api/endpoints/stories.rb +10 -0
  18. data/lib/tracker_api/error.rb +12 -2
  19. data/lib/tracker_api/file_utility.rb +1 -1
  20. data/lib/tracker_api/resources/blocker.rb +18 -0
  21. data/lib/tracker_api/resources/comment.rb +2 -2
  22. data/lib/tracker_api/resources/cycle_time_details.rb +21 -0
  23. data/lib/tracker_api/resources/daily_history_container.rb +13 -0
  24. data/lib/tracker_api/resources/epic.rb +10 -1
  25. data/lib/tracker_api/resources/iteration.rb +14 -0
  26. data/lib/tracker_api/resources/project.rb +13 -0
  27. data/lib/tracker_api/resources/release.rb +29 -0
  28. data/lib/tracker_api/resources/review.rb +35 -0
  29. data/lib/tracker_api/resources/review_type.rb +15 -0
  30. data/lib/tracker_api/resources/story.rb +29 -3
  31. data/lib/tracker_api/version.rb +1 -1
  32. data/test/client_test.rb +52 -52
  33. data/test/comment_test.rb +101 -32
  34. data/test/error_test.rb +8 -2
  35. data/test/file_attachment_test.rb +2 -2
  36. data/test/iteration_test.rb +31 -0
  37. data/test/minitest_helper.rb +7 -4
  38. data/test/project_test.rb +59 -47
  39. data/test/release_test.rb +22 -0
  40. data/test/review_test.rb +27 -0
  41. data/test/story_test.rb +65 -48
  42. data/test/task_test.rb +3 -3
  43. data/test/vcr/cassettes/create_epic_attachments.json +1 -0
  44. data/test/vcr/cassettes/create_epic_comment.json +1 -0
  45. data/test/vcr/cassettes/create_epic_comment_with_attachment.json +1 -0
  46. data/test/vcr/cassettes/create_story_attachments.json +1 -0
  47. data/test/vcr/cassettes/create_story_comment.json +1 -1
  48. data/test/vcr/cassettes/create_story_comment_with_attachment.json +1 -0
  49. data/test/vcr/cassettes/delete_epic_attachments.json +1 -0
  50. data/test/vcr/cassettes/delete_epic_comment.json +1 -0
  51. data/test/vcr/cassettes/delete_story_attachments.json +1 -0
  52. data/test/vcr/cassettes/delete_story_comment.json +1 -0
  53. data/test/vcr/cassettes/get_current_iteration.json +1 -1
  54. data/test/vcr/cassettes/get_cycle_time_details.json +1 -0
  55. data/test/vcr/cassettes/get_daily_history_container.json +1 -0
  56. data/test/vcr/cassettes/get_epic.json +1 -0
  57. data/test/vcr/cassettes/get_epic_comments.json +1 -0
  58. data/test/vcr/cassettes/get_releases.json +1 -0
  59. data/test/vcr/cassettes/get_story_reviews.json +1 -0
  60. data/test/vcr/cassettes/release_stories.json +1 -0
  61. data/test/vcr/cassettes/save_epic_comment.json +1 -0
  62. data/test/vcr/cassettes/save_review.json +1 -0
  63. data/test/vcr/cassettes/save_story_comment.json +1 -0
  64. data/test/vcr/cassettes/search_project.json +1 -1
  65. data/test/workspace_test.rb +5 -5
  66. data/tracker_api.gemspec +2 -2
  67. metadata +63 -8
  68. data/.travis.yml +0 -13
data/test/comment_test.rb CHANGED
@@ -7,71 +7,140 @@ describe TrackerApi::Resources::Comment do
7
7
  let(:project) { VCR.use_cassette('get project') { client.project(project_id) } }
8
8
  let(:story_id) { '66728004' }
9
9
  let(:story) { VCR.use_cassette('get story') { project.story(story_id) } }
10
- let(:comments) { VCR.use_cassette('get comments') { story.comments } }
11
- let(:existing_comment) { comments.first }
10
+ let(:story_comments) { VCR.use_cassette('get story comments') { story.comments } }
11
+ let(:epic_id) { '4737194' }
12
+ let(:epic) { VCR.use_cassette('get epic') { project.epic(epic_id) } }
13
+ let(:epic_comments) { VCR.use_cassette('get epic comments') { epic.comments } }
14
+ let(:existing_story_comment) { story_comments.first }
15
+ let(:existing_epic_comment) { epic_comments.first }
12
16
 
13
17
  it 'can create a comment given a story' do
14
18
  text = "Test creating a comment"
15
19
  comment = nil
16
- VCR.use_cassette('create comment', record: :new_episodes) do
20
+ VCR.use_cassette('create story comment', record: :new_episodes) do
17
21
  comment = story.create_comment(text: text)
18
22
  end
19
23
 
20
- comment.text.must_equal text
21
- comment.clean?.must_equal true
24
+ _(comment.text).must_equal text
25
+ _(comment.clean?).must_equal true
22
26
  end
23
27
 
24
- it 'can create a comment with file attachment' do
28
+ it 'can create a comment given an epic' do
29
+ text = "Test creating a comment"
30
+ comment = nil
31
+ VCR.use_cassette('create epic comment', record: :new_episodes) do
32
+ comment = epic.create_comment(text: text)
33
+ end
34
+
35
+ _(comment.text).must_equal text
36
+ _(comment.clean?).must_equal true
37
+ end
38
+
39
+ it 'can create a story comment with file attachment' do
25
40
  text = "Test creating a comment"
26
41
  comment = nil
27
42
  files = [File.expand_path('../Gemfile', File.dirname(__FILE__))]
28
- VCR.use_cassette('create comment with attachment', record: :new_episodes) do
43
+ VCR.use_cassette('create story comment with attachment', record: :new_episodes) do
29
44
  comment = story.create_comment(text: text, files: files)
30
45
  end
31
- comment.text.must_equal text
32
- comment.attachments.size.must_equal 1
33
- comment.clean?.must_equal true
46
+ _(comment.text).must_equal text
47
+ _(comment.attachments.size).must_equal 1
48
+ _(comment.clean?).must_equal true
49
+ end
50
+
51
+ it 'can create an epic comment with file attachment' do
52
+ text = "Test creating a comment"
53
+ comment = nil
54
+ files = [File.expand_path('../Gemfile', File.dirname(__FILE__))]
55
+ VCR.use_cassette('create epic comment with attachment', record: :new_episodes) do
56
+ comment = epic.create_comment(text: text, files: files)
57
+ end
58
+ _(comment.text).must_equal text
59
+ _(comment.attachments.size).must_equal 1
60
+ _(comment.clean?).must_equal true
61
+ end
62
+
63
+ it 'can update an existing story comment' do
64
+ new_text = "#{existing_story_comment.text}+"
65
+ existing_story_comment.text = new_text
66
+
67
+ VCR.use_cassette('save story comment', record: :new_episodes) do
68
+ existing_story_comment.save
69
+ end
70
+
71
+ _(existing_story_comment.text).must_equal new_text
72
+ _(existing_story_comment.clean?).must_equal true
34
73
  end
35
74
 
36
- it 'can update an existing comment' do
37
- new_text = "#{existing_comment.text}+"
38
- existing_comment.text = new_text
75
+ it 'can update an existing epic comment' do
76
+ new_text = "#{existing_epic_comment.text}+"
77
+ existing_epic_comment.text = new_text
78
+
79
+ VCR.use_cassette('save epic comment', record: :new_episodes) do
80
+ existing_epic_comment.save
81
+ end
82
+
83
+ _(existing_epic_comment.text).must_equal new_text
84
+ _(existing_epic_comment.clean?).must_equal true
85
+ end
39
86
 
40
- VCR.use_cassette('save comment', record: :new_episodes) do
41
- existing_comment.save
87
+ it 'can create attachments in a story comment' do
88
+ files = [File.expand_path('../Gemfile', File.dirname(__FILE__))]
89
+ VCR.use_cassette('create story attachments', record: :new_episodes) do
90
+ existing_story_comment.create_attachments(files: files)
91
+ assert existing_story_comment.attachments.size > 0
92
+ _(existing_story_comment.clean?).must_equal true
42
93
  end
94
+ end
43
95
 
44
- existing_comment.text.must_equal new_text
45
- existing_comment.clean?.must_equal true
96
+ it 'can create attachments in an epic comment' do
97
+ files = [File.expand_path('../Gemfile', File.dirname(__FILE__))]
98
+ VCR.use_cassette('create epic attachments', record: :new_episodes) do
99
+ existing_epic_comment.create_attachments(files: files)
100
+ assert existing_epic_comment.attachments.size > 0
101
+ _(existing_epic_comment.clean?).must_equal true
102
+ end
46
103
  end
47
104
 
48
- it 'can create attachments in a comment' do
105
+ it 'can delete attachments in a story comment' do
49
106
  files = [File.expand_path('../Gemfile', File.dirname(__FILE__))]
50
- VCR.use_cassette('create attachments', record: :new_episodes) do
51
- existing_comment.create_attachments(files: files)
52
- existing_comment.attachments.size.must_equal 1
53
- existing_comment.clean?.must_equal true
107
+ VCR.use_cassette('delete story attachments', record: :new_episodes) do
108
+ existing_story_comment.create_attachments(files: files)
109
+ assert existing_story_comment.attachments.size > 0
110
+ existing_story_comment.delete_attachments
111
+ _(existing_story_comment.attachments.size).must_equal 0
54
112
  end
55
113
  end
56
114
 
57
- it 'can delete attachments in a comment' do
115
+ it 'can delete attachments in an epic comment' do
58
116
  files = [File.expand_path('../Gemfile', File.dirname(__FILE__))]
59
- VCR.use_cassette('delete attachments', record: :new_episodes) do
60
- existing_comment.create_attachments(files: files)
61
- existing_comment.attachments.size.must_equal 1
62
- existing_comment.delete_attachments
63
- existing_comment.attachments.size.must_equal 0
117
+ VCR.use_cassette('delete epic attachments', record: :new_episodes) do
118
+ existing_epic_comment.create_attachments(files: files)
119
+ assert existing_epic_comment.attachments.size > 0
120
+ existing_epic_comment.delete_attachments
121
+ _(existing_epic_comment.attachments.size).must_equal 0
64
122
  end
65
123
  end
66
124
 
67
- it 'can delete a comment' do
68
- VCR.use_cassette('delete comment', record: :new_episodes) do
125
+ it 'can delete a story comment' do
126
+ VCR.use_cassette('delete story comment', record: :new_episodes) do
69
127
  current_story = project.story(story_id)
70
128
  new_comment_id = current_story.create_comment(text: "test comment").id
71
- current_story.comments.last.id.must_equal new_comment_id
129
+ _(current_story.comments.last.id).must_equal new_comment_id
72
130
  current_story.comments.last.delete
73
131
  current_story = project.story(story_id)
74
- current_story.comments.last.id.wont_equal new_comment_id
132
+ _(current_story.comments.last.id).wont_equal new_comment_id
133
+ end
134
+ end
135
+
136
+ it 'can delete an epic comment' do
137
+ VCR.use_cassette('delete epic comment', record: :new_episodes) do
138
+ current_epic = project.epic(epic_id)
139
+ new_comment_id = current_epic.create_comment(text: "test comment").id
140
+ _(current_epic.comments.last.id).must_equal new_comment_id
141
+ current_epic.comments.last.delete
142
+ current_epic = project.epic(epic_id)
143
+ _(current_epic.comments.last.id).wont_equal new_comment_id
75
144
  end
76
145
  end
77
146
  end
data/test/error_test.rb CHANGED
@@ -22,7 +22,7 @@ describe TrackerApi::Error do
22
22
  end
23
23
  end
24
24
  end
25
-
25
+
26
26
  it 'raises RuntimeError for HTTP status codes < 400 and > 500' do
27
27
  [399, 600].each do |status_code|
28
28
  mock_faraday_error(status_code)
@@ -35,7 +35,13 @@ describe TrackerApi::Error do
35
35
  # Simulate the error Faraday will raise with a specific HTTP status code so
36
36
  # we can test our rescuing of those errors
37
37
  def mock_faraday_error(status_code)
38
+ mocked_error_class = if (500..599).include?(status_code) && Faraday::VERSION.to_f >= 16.0
39
+ Faraday::ServerError
40
+ else
41
+ Faraday::ClientError
42
+ end
43
+
38
44
  ::Faraday::Connection.any_instance.stubs(:get).
39
- raises(::Faraday::Error::ClientError.new(nil, { status: status_code}))
45
+ raises(mocked_error_class.new(nil, { status: status_code}))
40
46
  end
41
47
  end
@@ -11,9 +11,9 @@ describe TrackerApi::Resources::FileAttachment do
11
11
  it 'can be deleted' do
12
12
  VCR.use_cassette('delete an attachment', record: :new_episodes) do
13
13
  comment_with_attachments = story.create_comment(text: "test comment", files: [File.expand_path('../Gemfile', File.dirname(__FILE__))])
14
- comment_with_attachments.attachments(reload: true).size.must_equal 1
14
+ _(comment_with_attachments.attachments(reload: true).size).must_equal 1
15
15
  comment_with_attachments.attachments.first.delete
16
- comment_with_attachments.attachments(reload: true).size.must_equal 0
16
+ _(comment_with_attachments.attachments(reload: true).size).must_equal 0
17
17
  end
18
18
  end
19
19
  end
@@ -0,0 +1,31 @@
1
+ require_relative 'minitest_helper'
2
+
3
+ describe TrackerApi::Resources::Iteration do
4
+ let(:pt_user) { PT_USER_1 }
5
+ let(:client) { TrackerApi::Client.new token: pt_user[:token] }
6
+ let(:project_id) { pt_user[:project_id] }
7
+ let(:project) { VCR.use_cassette('get project') { client.project(project_id) } }
8
+ let(:iteration) { VCR.use_cassette('get current iteration') { project.iterations(scope: "current").first } }
9
+
10
+ describe "#cycle_time_details" do
11
+ it "gets all cycle_time_details for this iteration" do
12
+ VCR.use_cassette('get cycle time details', record: :new_episodes) do
13
+ cycle_time_details = iteration.cycle_time_details
14
+
15
+ _(cycle_time_details).wont_be_empty
16
+ cycle_time_detail = cycle_time_details.first
17
+ _(cycle_time_detail).must_be_instance_of TrackerApi::Resources::CycleTimeDetails
18
+ end
19
+ end
20
+ end
21
+
22
+ describe "#get_history" do
23
+ it "gets all history for a particular iteration" do
24
+ VCR.use_cassette('get daily history container', record: :new_episodes) do
25
+ daily_history_container = iteration.get_history
26
+
27
+ _(daily_history_container).must_be_instance_of TrackerApi::Resources::DailyHistoryContainer
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,12 +1,15 @@
1
1
  #Bundler.require(:test)
2
2
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
3
 
4
- require 'coveralls'
5
- Coveralls.wear!
4
+ require 'simplecov'
5
+ SimpleCov.start
6
6
 
7
7
  require 'minitest/byebug' if ENV['DEBUG']
8
8
  require 'minitest/autorun'
9
- require 'mocha/mini_test'
9
+
10
+ require 'mocha'
11
+ require('mocha/minitest')
12
+
10
13
  require 'awesome_print'
11
14
  require 'multi_json'
12
15
  require 'vcr'
@@ -20,7 +23,7 @@ VCR.configure do |c|
20
23
  c.ignore_localhost = true
21
24
  c.cassette_library_dir = File.expand_path('../vcr/cassettes', __FILE__).to_s
22
25
  c.default_cassette_options = { serialize_with: :json }
23
- c.hook_into :excon
26
+ c.hook_into :faraday
24
27
  c.allow_http_connections_when_no_cassette = false
25
28
  end
26
29
 
data/test/project_test.rb CHANGED
@@ -11,9 +11,9 @@ describe TrackerApi::Resources::Project do
11
11
  VCR.use_cassette('get epics', record: :new_episodes) do
12
12
  epics = project.epics
13
13
 
14
- epics.wont_be_empty
14
+ _(epics).wont_be_empty
15
15
  epic = epics.first
16
- epic.must_be_instance_of TrackerApi::Resources::Epic
16
+ _(epic).must_be_instance_of TrackerApi::Resources::Epic
17
17
  end
18
18
  end
19
19
 
@@ -28,9 +28,9 @@ describe TrackerApi::Resources::Project do
28
28
  it 'does not make an extra request' do
29
29
  epics = project_with_epics.epics
30
30
 
31
- epics.wont_be_empty
31
+ _(epics).wont_be_empty
32
32
  epic = epics.first
33
- epic.must_be_instance_of TrackerApi::Resources::Epic
33
+ _(epic).must_be_instance_of TrackerApi::Resources::Epic
34
34
  end
35
35
  end
36
36
  end
@@ -46,9 +46,9 @@ describe TrackerApi::Resources::Project do
46
46
  it 'gets all labels for this project' do
47
47
  labels = project_with_labels.labels
48
48
 
49
- labels.wont_be_empty
49
+ _(labels).wont_be_empty
50
50
  label = labels.first
51
- label.must_be_instance_of TrackerApi::Resources::Label
51
+ _(label).must_be_instance_of TrackerApi::Resources::Label
52
52
  end
53
53
  end
54
54
 
@@ -56,9 +56,9 @@ describe TrackerApi::Resources::Project do
56
56
  VCR.use_cassette('get labels', record: :new_episodes) do
57
57
  labels = project.labels
58
58
 
59
- labels.wont_be_empty
59
+ _(labels).wont_be_empty
60
60
  label = labels.first
61
- label.must_be_instance_of TrackerApi::Resources::Label
61
+ _(label).must_be_instance_of TrackerApi::Resources::Label
62
62
  end
63
63
  end
64
64
  end
@@ -69,11 +69,11 @@ describe TrackerApi::Resources::Project do
69
69
  offset = -project.number_of_done_iterations_to_show.to_i
70
70
  done_iterations = project.iterations(scope: :done, offset: offset)
71
71
 
72
- done_iterations.wont_be_empty
73
- done_iterations.length.must_be :<=, project.number_of_done_iterations_to_show
72
+ _(done_iterations).wont_be_empty
73
+ _(done_iterations.length).must_be :<=, project.number_of_done_iterations_to_show
74
74
 
75
75
  iteration = done_iterations.first
76
- iteration.must_be_instance_of TrackerApi::Resources::Iteration
76
+ _(iteration).must_be_instance_of TrackerApi::Resources::Iteration
77
77
  end
78
78
  end
79
79
 
@@ -81,14 +81,14 @@ describe TrackerApi::Resources::Project do
81
81
  VCR.use_cassette('get current iteration', record: :new_episodes) do
82
82
  iterations = project.iterations(scope: :current)
83
83
 
84
- iterations.wont_be_empty
84
+ _(iterations).wont_be_empty
85
85
 
86
86
  current = iterations.first
87
- current.must_be_instance_of TrackerApi::Resources::Iteration
88
- current.stories.wont_be_empty
87
+ _(current).must_be_instance_of TrackerApi::Resources::Iteration
88
+ _(current.stories).wont_be_empty
89
89
 
90
90
  story = current.stories.first
91
- story.must_be_instance_of TrackerApi::Resources::Story
91
+ _(story).must_be_instance_of TrackerApi::Resources::Story
92
92
  end
93
93
  end
94
94
 
@@ -96,13 +96,13 @@ describe TrackerApi::Resources::Project do
96
96
  VCR.use_cassette('get current iteration', record: :new_episodes) do
97
97
  iterations = project.iterations(scope: :current, fields: ":default,velocity,points,accepted_points,effective_points")
98
98
 
99
- iterations.wont_be_empty
99
+ _(iterations).wont_be_empty
100
100
 
101
101
  current = iterations.first
102
- current.velocity.must_equal 10.0
103
- current.points.must_equal 9.0
104
- current.accepted_points.must_equal 0
105
- current.effective_points.must_equal 9.0
102
+ _(current.velocity).must_equal 10.0
103
+ _(current.points).must_equal 9.0
104
+ _(current.accepted_points).must_equal 0
105
+ _(current.effective_points).must_equal 9.0
106
106
  end
107
107
  end
108
108
 
@@ -110,26 +110,26 @@ describe TrackerApi::Resources::Project do
110
110
  VCR.use_cassette('get iteration by number', record: :new_episodes) do
111
111
  iterations = project.iterations(number: 2)
112
112
 
113
- iterations.size.must_equal 1
114
- iterations.first.must_be_instance_of TrackerApi::Resources::Iteration
115
- iterations.first.number.must_equal 2
113
+ _(iterations.size).must_equal 1
114
+ _(iterations.first).must_be_instance_of TrackerApi::Resources::Iteration
115
+ _(iterations.first.number).must_equal 2
116
116
 
117
117
  iterations = project.iterations(number: 1)
118
118
 
119
- iterations.size.must_equal 1
120
- iterations.first.must_be_instance_of TrackerApi::Resources::Iteration
121
- iterations.first.number.must_equal 1
119
+ _(iterations.size).must_equal 1
120
+ _(iterations.first).must_be_instance_of TrackerApi::Resources::Iteration
121
+ _(iterations.first.number).must_equal 1
122
122
 
123
123
  iterations = project.iterations(number: 10_000)
124
124
 
125
- iterations.must_be_empty
125
+ _(iterations).must_be_empty
126
126
  end
127
127
  end
128
128
 
129
129
  it 'requires an iteration number > 0' do
130
130
  VCR.use_cassette('get iteration by number', record: :new_episodes) do
131
- -> { project.iterations(number: 0) }.must_raise(ArgumentError, /> 0/)
132
- -> { project.iterations(number: -1) }.must_raise(ArgumentError, /> 0/)
131
+ _(-> { project.iterations(number: 0) }).must_raise(ArgumentError, /> 0/)
132
+ _(-> { project.iterations(number: -1) }).must_raise(ArgumentError, /> 0/)
133
133
  end
134
134
  end
135
135
  end
@@ -139,11 +139,11 @@ describe TrackerApi::Resources::Project do
139
139
  VCR.use_cassette('get unscheduled stories', record: :new_episodes) do
140
140
  stories = project.stories(with_state: :unscheduled)
141
141
 
142
- stories.wont_be_empty
142
+ _(stories).wont_be_empty
143
143
 
144
144
  story = stories.first
145
- story.must_be_instance_of TrackerApi::Resources::Story
146
- story.current_state.must_equal 'unscheduled'
145
+ _(story).must_be_instance_of TrackerApi::Resources::Story
146
+ _(story.current_state).must_equal 'unscheduled'
147
147
  end
148
148
  end
149
149
 
@@ -151,10 +151,10 @@ describe TrackerApi::Resources::Project do
151
151
  VCR.use_cassette('create story') do
152
152
  story = project.create_story(name: 'Test story')
153
153
 
154
- story.must_be_instance_of TrackerApi::Resources::Story
155
- story.id.wont_be_nil
156
- story.id.must_be :>, 0
157
- story.name.must_equal 'Test story'
154
+ _(story).must_be_instance_of TrackerApi::Resources::Story
155
+ _(_(story.id)).wont_be_nil
156
+ _(story.id).must_be :>, 0
157
+ _(story.name).must_equal 'Test story'
158
158
  end
159
159
  end
160
160
 
@@ -162,10 +162,10 @@ describe TrackerApi::Resources::Project do
162
162
  VCR.use_cassette('create story with lengthy params') do
163
163
  story = project.create_story(name: 'Test story', description: ('Test description ' * 500))
164
164
 
165
- story.must_be_instance_of TrackerApi::Resources::Story
166
- story.id.wont_be_nil
167
- story.id.must_be :>, 0
168
- story.description.must_equal ('Test description ' * 500)
165
+ _(story).must_be_instance_of TrackerApi::Resources::Story
166
+ _(_(story.id)).wont_be_nil
167
+ _(story.id).must_be :>, 0
168
+ _(story.description).must_equal ('Test description ' * 500)
169
169
  end
170
170
  end
171
171
  end
@@ -186,9 +186,9 @@ describe TrackerApi::Resources::Project do
186
186
  VCR.use_cassette('get project activity', record: :new_episodes) do
187
187
  activity = project.activity
188
188
 
189
- activity.wont_be_empty
189
+ _(activity).wont_be_empty
190
190
  event = activity.first
191
- event.must_be_instance_of TrackerApi::Resources::Activity
191
+ _(event).must_be_instance_of TrackerApi::Resources::Activity
192
192
  end
193
193
  end
194
194
  end
@@ -201,11 +201,23 @@ describe TrackerApi::Resources::Project do
201
201
  project = client.project(pt_user[:project_id])
202
202
  search_container = project.search('name:"story to test search"')
203
203
 
204
- search_container.wont_be_nil
205
- search_container.must_be_instance_of TrackerApi::Resources::SearchResultContainer
206
- search_container.epics.must_be_instance_of TrackerApi::Resources::EpicsSearchResult
207
- search_container.stories.must_be_instance_of TrackerApi::Resources::StoriesSearchResult
208
- search_container.stories.stories.first[:id].must_equal 143444685
204
+ _(search_container).wont_be_nil
205
+ _(search_container).must_be_instance_of TrackerApi::Resources::SearchResultContainer
206
+ _(search_container.epics).must_be_instance_of TrackerApi::Resources::EpicsSearchResult
207
+ _(search_container.stories).must_be_instance_of TrackerApi::Resources::StoriesSearchResult
208
+ _(search_container.stories.stories.first[:id]).must_equal 143444685
209
+ end
210
+ end
211
+ end
212
+
213
+ describe '.releases' do
214
+ it 'gets all of the releases for the project' do
215
+ VCR.use_cassette('get releases', record: :new_episodes) do
216
+ releases = project.releases
217
+
218
+ _(releases).wont_be_empty
219
+ _(releases.size).must_equal 3
220
+ _(releases.first).must_be_instance_of TrackerApi::Resources::Release
209
221
  end
210
222
  end
211
223
  end