pivotal-tracker-api 0.2.3 → 1.0.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -2
  3. data/Gemfile.lock +65 -47
  4. data/README.md +7 -7
  5. data/VERSION +1 -1
  6. data/lib/pivotal-tracker-api.rb +10 -2
  7. data/lib/pivotal-tracker-api/activity.rb +52 -18
  8. data/lib/pivotal-tracker-api/analytics.rb +23 -0
  9. data/lib/pivotal-tracker-api/base.rb +14 -2
  10. data/lib/pivotal-tracker-api/client.rb +43 -21
  11. data/lib/pivotal-tracker-api/comment.rb +76 -27
  12. data/lib/pivotal-tracker-api/core_ext/string.rb +3 -0
  13. data/lib/pivotal-tracker-api/cycle_time_details.rb +43 -0
  14. data/lib/pivotal-tracker-api/file_attachment.rb +56 -0
  15. data/lib/pivotal-tracker-api/iteration.rb +73 -11
  16. data/lib/pivotal-tracker-api/label.rb +32 -0
  17. data/lib/pivotal-tracker-api/me.rb +16 -0
  18. data/lib/pivotal-tracker-api/person.rb +13 -9
  19. data/lib/pivotal-tracker-api/project.rb +76 -23
  20. data/lib/pivotal-tracker-api/service.rb +202 -0
  21. data/lib/pivotal-tracker-api/story.rb +173 -132
  22. data/lib/pivotal-tracker-api/story_transition.rb +81 -0
  23. data/lib/pivotal-tracker-api/string_extensions.rb +61 -0
  24. data/lib/pivotal-tracker-api/task.rb +56 -12
  25. data/pivotal-tracker-api.gemspec +28 -15
  26. data/test/helper.rb +1 -0
  27. data/test/test_activity.rb +79 -0
  28. data/test/test_analytics.rb +38 -0
  29. data/test/test_cycle_time_details.rb +69 -0
  30. data/test/test_iteration.rb +182 -0
  31. data/test/test_label.rb +29 -0
  32. data/test/test_me.rb +52 -0
  33. data/test/test_service.rb +67 -0
  34. data/test/test_story.rb +557 -0
  35. data/test/test_story_transition.rb +80 -0
  36. data/test/test_string_extensions.rb +37 -0
  37. metadata +29 -27
  38. data/lib/pivotal-tracker-api/attachment.rb +0 -28
  39. data/lib/pivotal-tracker-api/pivotal_service.rb +0 -141
  40. data/test/test_pivotal-tracker-api.rb +0 -7
@@ -0,0 +1,80 @@
1
+ require 'helper'
2
+
3
+ class TestStoryTransition < Test::Unit::TestCase
4
+ should "parse a valid json object into an instance of StoryTransition" do
5
+ transition = PivotalAPI::StoryTransition.from_json({
6
+ state: "started",
7
+ story_id: 1,
8
+ project_id: 2,
9
+ project_version: 3,
10
+ occurred_at: "2016-08-09T18:55:58Z",
11
+ performed_by_id: 4,
12
+ kind: "some-kind"
13
+ })
14
+
15
+ assert_equal(1, transition.story_id)
16
+ assert_equal(2, transition.project_id)
17
+ assert_equal(3, transition.project_version)
18
+ assert_equal(4, transition.performed_by_id)
19
+ assert_equal("started", transition.state)
20
+ assert_equal(DateTime.parse("2016-08-09T18:55:58Z"), transition.occurred_at)
21
+ assert_equal("some-kind", transition.kind)
22
+ end
23
+
24
+ should "parse a valid json array into an arrary of StoryTransition instances" do
25
+ transitions = PivotalAPI::StoryTransition.from_json([{
26
+ state: "started",
27
+ story_id: 1,
28
+ project_id: 2,
29
+ project_version: 3,
30
+ occurred_at: "2016-08-09T18:55:58Z",
31
+ performed_by_id: 4,
32
+ kind: "some-kind"
33
+ },
34
+ {
35
+ state: "finished",
36
+ story_id: 5,
37
+ project_id: 6,
38
+ project_version: 7,
39
+ occurred_at: "2016-08-09T18:55:58Z",
40
+ performed_by_id: 8,
41
+ kind: "some-kind"
42
+ },
43
+ {
44
+ state: "accepted",
45
+ story_id: 9,
46
+ project_id: 10,
47
+ project_version: 11,
48
+ occurred_at: "2016-08-09T18:55:58Z",
49
+ performed_by_id: 12,
50
+ kind: "some-kind"
51
+ }
52
+ ])
53
+
54
+ assert_equal(3, transitions.count)
55
+
56
+ assert_equal(1, transitions[0].story_id)
57
+ assert_equal(2, transitions[0].project_id)
58
+ assert_equal(3, transitions[0].project_version)
59
+ assert_equal(4, transitions[0].performed_by_id)
60
+ assert_equal("started", transitions[0].state)
61
+ assert_equal(DateTime.parse("2016-08-09T18:55:58Z"), transitions[0].occurred_at)
62
+ assert_equal("some-kind", transitions[0].kind)
63
+
64
+ assert_equal(5, transitions[1].story_id)
65
+ assert_equal(6, transitions[1].project_id)
66
+ assert_equal(7, transitions[1].project_version)
67
+ assert_equal(8, transitions[1].performed_by_id)
68
+ assert_equal("finished", transitions[1].state)
69
+ assert_equal(DateTime.parse("2016-08-09T18:55:58Z"), transitions[1].occurred_at)
70
+ assert_equal("some-kind", transitions[1].kind)
71
+
72
+ assert_equal(9, transitions[2].story_id)
73
+ assert_equal(10, transitions[2].project_id)
74
+ assert_equal(11, transitions[2].project_version)
75
+ assert_equal(12, transitions[2].performed_by_id)
76
+ assert_equal("accepted", transitions[2].state)
77
+ assert_equal(DateTime.parse("2016-08-09T18:55:58Z"), transitions[2].occurred_at)
78
+ assert_equal("some-kind", transitions[2].kind)
79
+ end
80
+ end
@@ -0,0 +1,37 @@
1
+ require 'helper'
2
+
3
+ class TestActivity < Test::Unit::TestCase
4
+
5
+ context "Appending query params" do
6
+
7
+ should "should append limit, offset, and fields as expected" do
8
+ url = "/projects/12345/stories"
9
+ query_params = {
10
+ limit: 1,
11
+ offset: 2,
12
+ fields: PivotalAPI::Comment.fields
13
+ }
14
+ url.append_pivotal_params(query_params)
15
+ expected_url = "/projects/12345/stories?limit=1&offset=2"
16
+ expected_url += "&fields=person(name,id,initials,email,username,kind),text,updated_at,id," \
17
+ "created_at,story_id,file_attachments,google_attachment_ids,commit_identifier,commit_type,kind"
18
+ assert_equal(expected_url, url)
19
+ end
20
+
21
+ should "should append filters" do
22
+ url = "/projects/12345/stories"
23
+ query_params = {
24
+ limit: 1,
25
+ offset: 2,
26
+ filter: {
27
+ includedone: true,
28
+ id: [1,2,3,4,5]
29
+ }
30
+ }
31
+ url.append_pivotal_params(query_params)
32
+ expected_url = "/projects/12345/stories?limit=1&offset=2&filter=includedone%3Atrue%20id%3A1,2,3,4,5"
33
+ assert_equal(expected_url, url)
34
+ end
35
+
36
+ end
37
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pivotal-tracker-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jfox
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-22 00:00:00.000000000 Z
11
+ date: 2016-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.7'
27
27
  - !ruby/object:Gem::Dependency
28
- name: shoulda
28
+ name: business_time
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
33
+ version: 0.7.6
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 0.7.6
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rdoc
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,28 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.8.7
75
+ version: '2.1'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.8.7
83
- - !ruby/object:Gem::Dependency
84
- name: simplecov
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
82
+ version: '2.1'
97
83
  description: A ruby gem to communicate with the Picotal Tracker API v5
98
84
  email: atljeremy@me.com
99
85
  executables: []
@@ -119,19 +105,35 @@ files:
119
105
  - VERSION
120
106
  - lib/pivotal-tracker-api.rb
121
107
  - lib/pivotal-tracker-api/activity.rb
122
- - lib/pivotal-tracker-api/attachment.rb
108
+ - lib/pivotal-tracker-api/analytics.rb
123
109
  - lib/pivotal-tracker-api/base.rb
124
110
  - lib/pivotal-tracker-api/client.rb
125
111
  - lib/pivotal-tracker-api/comment.rb
112
+ - lib/pivotal-tracker-api/core_ext/string.rb
113
+ - lib/pivotal-tracker-api/cycle_time_details.rb
114
+ - lib/pivotal-tracker-api/file_attachment.rb
126
115
  - lib/pivotal-tracker-api/iteration.rb
116
+ - lib/pivotal-tracker-api/label.rb
117
+ - lib/pivotal-tracker-api/me.rb
127
118
  - lib/pivotal-tracker-api/person.rb
128
- - lib/pivotal-tracker-api/pivotal_service.rb
129
119
  - lib/pivotal-tracker-api/project.rb
120
+ - lib/pivotal-tracker-api/service.rb
130
121
  - lib/pivotal-tracker-api/story.rb
122
+ - lib/pivotal-tracker-api/story_transition.rb
123
+ - lib/pivotal-tracker-api/string_extensions.rb
131
124
  - lib/pivotal-tracker-api/task.rb
132
125
  - pivotal-tracker-api.gemspec
133
126
  - test/helper.rb
134
- - test/test_pivotal-tracker-api.rb
127
+ - test/test_activity.rb
128
+ - test/test_analytics.rb
129
+ - test/test_cycle_time_details.rb
130
+ - test/test_iteration.rb
131
+ - test/test_label.rb
132
+ - test/test_me.rb
133
+ - test/test_service.rb
134
+ - test/test_story.rb
135
+ - test/test_story_transition.rb
136
+ - test/test_string_extensions.rb
135
137
  homepage: http://github.com/atljeremy/pivotal-tracker-api
136
138
  licenses:
137
139
  - MIT
@@ -1,28 +0,0 @@
1
- module Scorer
2
- class Attachment < Base
3
-
4
- attr_accessor :filename, :id, :created_at, :uploaded_by, :big_url,
5
- :width, :height, :download_url, :thumbnail_url, :size, :content_type
6
-
7
- def self.parse_attachments(attachments)
8
- parsed_attachments = []
9
- attachments.each do |file|
10
- parsed_attachments << new({
11
- id: file[:id].to_i,
12
- filename: file[:filename],
13
- created_at: file[:created_at],
14
- uploaded_by: file[:uploaded_by],
15
- big_url: file[:big_url],
16
- width: file[:width],
17
- height: file[:height],
18
- download_url: file[:download_url],
19
- thumbnail_url: file[:thumbnail_url],
20
- size: file[:size],
21
- content_type: file[:content_type]
22
- })
23
- end if attachments
24
- parsed_attachments
25
- end
26
-
27
- end
28
- end
@@ -1,141 +0,0 @@
1
- require 'json'
2
-
3
- class PivotalService
4
-
5
- class << self
6
-
7
- def set_token(token)
8
- Scorer::Client.token = token
9
- end
10
-
11
- def all_projects(fields=[])
12
- api_url = append_fields('/projects', fields)
13
- response = Scorer::Client.get(api_url)
14
- json_projects = JSON.parse(response, {:symbolize_names => true})
15
- Scorer::Project.parse_json_projects(json_projects)
16
- end
17
-
18
- def one_project(id, fields=[])
19
- return @project if !@project.nil? && @project.id == id
20
-
21
- api_url = append_fields('/projects' + "/#{id}", fields)
22
- response = Scorer::Client.get(api_url)
23
- json_project = JSON.parse(response, {:symbolize_names => true})
24
- @project = Scorer::Project.parse_json_project(json_project)
25
- end
26
-
27
- def activity(project_id, story_id=0, limit=20)
28
- api_url = "/projects/#{project_id}/"
29
- api_url = api_url + "stories/#{story_id}/" if story_id > 0
30
- api_url = api_url + "activity?limit=#{limit}"
31
- response = Scorer::Client.get(api_url)
32
- json_activity = JSON.parse(response, {:symbolize_names => true})
33
- Scorer::Activity.parse_json_activity(json_activity, project_id)
34
- end
35
-
36
- def iterations(project_id, scope, fields=[], limit=1, offset=1)
37
- return @iterations if !@iterations.nil? && @iterations.last.project_id == project_id
38
-
39
- api_url = "/projects/#{project_id}/iterations?"
40
-
41
- if scope == 'current'
42
- api_url = append_scope(api_url, scope)
43
- elsif scope == 'done' || scope == 'backlog' || scope == 'current_backlog'
44
- api_url = append_limit_offset(api_url, limit, offset)
45
- api_url = append_scope(api_url, scope)
46
- else
47
- api_url = append_limit_offset(api_url, limit, offset)
48
- end
49
-
50
- api_url = append_fields(api_url, fields)
51
- response = Scorer::Client.get_with_caching(api_url)
52
- json_iterations = JSON.parse(response, {:symbolize_names => true})
53
- @iterations = []
54
- json_iterations.each do |iteration|
55
- @iterations << Scorer::Iteration.parse_json_iteration(iteration, (scope == 'done'))
56
- end
57
- @iterations
58
- end
59
-
60
- def all_stories(project_label, project, fields=[])
61
- api_url = append_fields('/projects' + "/#{project.id}/stories", fields)
62
- api_url = api_url + "&with_label=#{project_label}&with_state=unstarted&limit=100"
63
- response = Scorer::Client.get(api_url)
64
- json_stories = JSON.parse(response, {:symbolize_names => true})
65
- Scorer::Story.parse_json_stories(json_stories, project.id)
66
- end
67
-
68
- def one_story(project_label, project, fields=[])
69
- api_url = append_fields('/projects' + "/#{project.id}/stories", fields)
70
- api_url = api_url + "&with_label=#{project_label}&with_state=unstarted&limit=100"
71
- response = Scorer::Client.get(api_url)
72
- json_story = JSON.parse(response, {:symbolize_names => true})
73
- Scorer::Story.parse_json_story(json_story, project.id)
74
- end
75
-
76
- def stories(project, should_cache, ids=[], fields=[], include_done=false)
77
- @stories = Array.new
78
- api_url = append_fields('/projects' + "/#{project.id}/stories", fields)
79
- if api_url.rindex('?fields=')
80
- api_url = "#{api_url}&filter=includedone%3A#{include_done}%20id%3A"
81
- else
82
- api_url = "#{api_url}?filter=includedone%3A#{include_done}%20id%3A"
83
- end
84
- if ids.size == 1
85
- api_url = api_url + ids[0].to_s
86
- if should_cache
87
- response = Scorer::Client.get_with_caching(api_url)
88
- else
89
- response = Scorer::Client.get(api_url)
90
- end
91
- json_story = JSON.parse(response, {:symbolize_names => true})
92
- @stories << Scorer::Story.parse_json_story(json_story[0], project.id)
93
- else
94
- story_ids = ''
95
- ids.each do |id|
96
- story_ids = "#{story_ids}#{id}%2C"
97
- end
98
- api_url = api_url + story_ids
99
- if should_cache
100
- response = Scorer::Client.get_with_caching(api_url)
101
- else
102
- response = Scorer::Client.get(api_url)
103
- end
104
- json_stories = JSON.parse(response, {:symbolize_names => true})
105
- @stories = Scorer::Story.parse_json_stories(json_stories, project.id)
106
- end
107
- end
108
-
109
- def update_story(story_id, project_id, updates={})
110
- project = one_project(project_id, Scorer::Project.fields)
111
- api_url = '/projects' + "/#{project.id}/stories/#{story_id}"
112
- Scorer::Client.put(api_url, updates)
113
- end
114
-
115
- def comments(project_id, story, fields)
116
- api_url = append_fields('/projects' + "/#{project_id}/stories/#{story.id}/comments", fields)
117
- response = Scorer::Client.get_with_caching(api_url)
118
- json_comments = JSON.parse(response, {:symbolize_names => true})
119
- Scorer::Comment.parse_json_comments(json_comments, story)
120
- end
121
-
122
- private
123
-
124
- def append_fields(api_url, fields)
125
- url = api_url
126
- fields.each do |field|
127
- url = url.rindex('?fields=') ? url + ",#{field}" : url + "?fields=#{field}"
128
- end
129
- url
130
- end
131
-
132
- def append_scope(api_url, scope)
133
- api_url + "&scope=#{scope}"
134
- end
135
-
136
- def append_limit_offset(api_url, limit, offset)
137
- api_url + "&limit=#{limit}&offset=#{offset}"
138
- end
139
-
140
- end
141
- end
@@ -1,7 +0,0 @@
1
- require 'helper'
2
-
3
- class TestPivotalTrackerApi < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
-
6
- end
7
- end