pivotal-tracker-api 0.2.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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