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,81 @@
1
+ # state enumerated string
2
+ # — State the story transitioned to. This field is read only.
3
+ # Valid enumeration values: accepted, delivered, finished, started, rejected, planned, unstarted, unscheduled
4
+ #
5
+ # story_id int
6
+ # — ID of the story. This field is read only.
7
+ #
8
+ # project_id int
9
+ # — ID of the project. This field is read only.
10
+ #
11
+ # project_version int
12
+ # — The activity version of the story transition. This field is read only.
13
+ #
14
+ # occurred_at datetime
15
+ # — Time of the transition. This field is read only.
16
+ #
17
+ # performed_by_id int
18
+ # — ID of the person who performed the story transition. This field is read only.
19
+ #
20
+ # kind string
21
+ # — The type of this object: story_transition. This field is read only.
22
+
23
+ module PivotalAPI
24
+ class StoryTransition < Base
25
+
26
+ attr_accessor :state, :story_id, :project_id, :project_version, :occurred_at, :performed_by_id, :kind
27
+
28
+ class << self
29
+
30
+ def from_json(json)
31
+ return nil unless json
32
+ if json.is_a?(Array)
33
+ parse_json_story_transitions(json)
34
+ else
35
+ parse_json_story_transition(json)
36
+ end
37
+ end
38
+
39
+ def parse_json_story_transitions(json_story_transitions)
40
+ transitions = []
41
+ json_story_transitions.each do |transition|
42
+ transitions << parse_json_story_transition(transition)
43
+ end
44
+ transitions
45
+ end
46
+
47
+ def parse_json_story_transition(json_story_transition)
48
+ new({
49
+ state: json_story_transition[:state],
50
+ story_id: json_story_transition[:story_id].to_i,
51
+ project_id: json_story_transition[:project_id].to_i,
52
+ project_version: json_story_transition[:project_version].to_i,
53
+ occurred_at: (DateTime.parse(json_story_transition[:occurred_at]) if json_story_transition[:occurred_at]),
54
+ performed_by_id: json_story_transition[:performed_by_id].to_i,
55
+ kind: json_story_transition[:kind]
56
+ })
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+ class StoryTransitions < StoryTransition
64
+
65
+ class << self
66
+
67
+ def from_json(json)
68
+ return nil unless json
69
+ parse_json_story_transitions(json)
70
+ end
71
+
72
+ def parse_json_story_transitions(story_transitions)
73
+ transitions = []
74
+ story_transitions.each { |transition| transitions << parse_json_story_transition(transition) }
75
+ transitions
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,61 @@
1
+ require 'cgi'
2
+
3
+ module PivotalAPI
4
+ module Extensions
5
+ module String
6
+ module QueryParams
7
+
8
+ def append_pivotal_params(params, replace=true)
9
+ return self if params.nil?
10
+
11
+ resulting_url = if replace then self else "" end
12
+
13
+ if self.rindex("?").nil?
14
+ resulting_url += "?"
15
+ replace(resulting_url)
16
+ end
17
+
18
+ case params
19
+ when Array
20
+ resulting_url += params_from_array(params)
21
+ when Hash
22
+ resulting_url += params_from_hash(params)
23
+ else
24
+ resulting_url += "#{params}"
25
+ end
26
+
27
+ if replace then replace(resulting_url) else resulting_url end
28
+ end
29
+
30
+ protected
31
+
32
+ def params_from_hash(hash)
33
+ q_params = ""
34
+ hash.each do |k,v|
35
+ case v
36
+ when Array
37
+ q_params += if q_params.length == 0 then "#{k}=" else "&#{k}=" end
38
+ q_params += params_from_array(v)
39
+ when Hash
40
+ q_params += if q_params.length == 0 then "#{k}=" else "&#{k}=" end
41
+ v.each { |kk,vv|
42
+ q_params += if v.keys.first == kk then "#{kk}%3A" else "%20#{kk}%3A" end
43
+ q_params += append_pivotal_params(vv, false)
44
+ }
45
+ else
46
+ q_params += if q_params.length == 0 then "#{k}=#{v}" else "&#{k}=#{v}" end
47
+ end
48
+ end
49
+ q_params
50
+ end
51
+
52
+ def params_from_array(array)
53
+ q_params = ""
54
+ array.each { |vv| q_params += if array.index(vv) == 0 then "#{vv}" else ",#{vv}" end }
55
+ q_params
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,21 +1,65 @@
1
- module Scorer
1
+ # PROPERTIES
2
+ # id int
3
+ # — Database id of the task. This field is read only. This field is always returned.
4
+ #
5
+ # story_id int
6
+ # — The id of the story to which the task is connected. This field is read only.
7
+ #
8
+ # description string[1000]
9
+ # Required On Create — Content of the task. This field is required on create.
10
+ #
11
+ # complete boolean
12
+ # — Flag showing the completion of the task.
13
+ #
14
+ # position int
15
+ # — Offset from the top of the task list. Positions start counting from 1 for the first task on a story.
16
+ #
17
+ # created_at datetime
18
+ # — Creation time. This field is read only.
19
+ #
20
+ # updated_at datetime
21
+ # — Time of last update. This field is read only.
22
+ #
23
+ # kind string
24
+ # — The type of this object: task. This field is read only.
25
+
26
+ module PivotalAPI
2
27
  class Task < Base
3
28
 
4
29
  attr_accessor :project_id, :story_id, :id, :description, :position, :complete, :created_at
5
30
 
6
- def self.parse_tasks(tasks, story)
7
- parsed_tasks = []
8
- tasks.each do |task|
9
- parsed_tasks << new({
10
- id: task[:id].to_i,
11
- description: task[:description],
12
- complete: task[:complete],
13
- created_at: DateTime.parse(task[:created_at].to_s).to_s,
14
- story_id: story[:id]
15
- })
16
- end if tasks
31
+ def self.from_json(json)
32
+ return nil unless json
33
+ parse_task(json)
34
+ end
35
+
36
+ protected
37
+
38
+ def self.parse_task(task)
39
+ new({
40
+ id: task[:id].to_i,
41
+ description: task[:description],
42
+ complete: task[:complete],
43
+ created_at: DateTime.parse(task[:created_at].to_s),
44
+ story_id: task[:id]
45
+ })
46
+ end
47
+ end
48
+
49
+ class Tasks < Task
50
+
51
+ def self.from_json(json)
52
+ return nil unless json
53
+ parse_tasks(json)
54
+ end
17
55
 
56
+ protected
57
+
58
+ def self.parse_tasks(tasks)
59
+ parsed_tasks = []
60
+ tasks.each { |task| parsed_tasks << parse_task(task) }
18
61
  parsed_tasks
19
62
  end
63
+
20
64
  end
21
65
  end
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: pivotal-tracker-api 0.2.3 ruby lib
5
+ # stub: pivotal-tracker-api 1.0.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "pivotal-tracker-api"
9
- s.version = "0.2.3"
9
+ s.version = "1.0.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["jfox"]
14
- s.date = "2016-01-22"
14
+ s.date = "2016-08-23"
15
15
  s.description = "A ruby gem to communicate with the Picotal Tracker API v5"
16
16
  s.email = "atljeremy@me.com"
17
17
  s.extra_rdoc_files = [
@@ -36,19 +36,35 @@ Gem::Specification.new do |s|
36
36
  "VERSION",
37
37
  "lib/pivotal-tracker-api.rb",
38
38
  "lib/pivotal-tracker-api/activity.rb",
39
- "lib/pivotal-tracker-api/attachment.rb",
39
+ "lib/pivotal-tracker-api/analytics.rb",
40
40
  "lib/pivotal-tracker-api/base.rb",
41
41
  "lib/pivotal-tracker-api/client.rb",
42
42
  "lib/pivotal-tracker-api/comment.rb",
43
+ "lib/pivotal-tracker-api/core_ext/string.rb",
44
+ "lib/pivotal-tracker-api/cycle_time_details.rb",
45
+ "lib/pivotal-tracker-api/file_attachment.rb",
43
46
  "lib/pivotal-tracker-api/iteration.rb",
47
+ "lib/pivotal-tracker-api/label.rb",
48
+ "lib/pivotal-tracker-api/me.rb",
44
49
  "lib/pivotal-tracker-api/person.rb",
45
- "lib/pivotal-tracker-api/pivotal_service.rb",
46
50
  "lib/pivotal-tracker-api/project.rb",
51
+ "lib/pivotal-tracker-api/service.rb",
47
52
  "lib/pivotal-tracker-api/story.rb",
53
+ "lib/pivotal-tracker-api/story_transition.rb",
54
+ "lib/pivotal-tracker-api/string_extensions.rb",
48
55
  "lib/pivotal-tracker-api/task.rb",
49
56
  "pivotal-tracker-api.gemspec",
50
57
  "test/helper.rb",
51
- "test/test_pivotal-tracker-api.rb"
58
+ "test/test_activity.rb",
59
+ "test/test_analytics.rb",
60
+ "test/test_cycle_time_details.rb",
61
+ "test/test_iteration.rb",
62
+ "test/test_label.rb",
63
+ "test/test_me.rb",
64
+ "test/test_service.rb",
65
+ "test/test_story.rb",
66
+ "test/test_story_transition.rb",
67
+ "test/test_string_extensions.rb"
52
68
  ]
53
69
  s.homepage = "http://github.com/atljeremy/pivotal-tracker-api"
54
70
  s.licenses = ["MIT"]
@@ -60,26 +76,23 @@ Gem::Specification.new do |s|
60
76
 
61
77
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
62
78
  s.add_runtime_dependency(%q<rest-client>, ["~> 1.7"])
63
- s.add_development_dependency(%q<shoulda>, [">= 0"])
79
+ s.add_runtime_dependency(%q<business_time>, ["~> 0.7.6"])
64
80
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
65
81
  s.add_development_dependency(%q<bundler>, ["~> 1.0"])
66
- s.add_development_dependency(%q<jeweler>, ["~> 1.8.7"])
67
- s.add_development_dependency(%q<simplecov>, [">= 0"])
82
+ s.add_development_dependency(%q<jeweler>, ["~> 2.1"])
68
83
  else
69
84
  s.add_dependency(%q<rest-client>, ["~> 1.7"])
70
- s.add_dependency(%q<shoulda>, [">= 0"])
85
+ s.add_dependency(%q<business_time>, ["~> 0.7.6"])
71
86
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
72
87
  s.add_dependency(%q<bundler>, ["~> 1.0"])
73
- s.add_dependency(%q<jeweler>, ["~> 1.8.7"])
74
- s.add_dependency(%q<simplecov>, [">= 0"])
88
+ s.add_dependency(%q<jeweler>, ["~> 2.1"])
75
89
  end
76
90
  else
77
91
  s.add_dependency(%q<rest-client>, ["~> 1.7"])
78
- s.add_dependency(%q<shoulda>, [">= 0"])
92
+ s.add_dependency(%q<business_time>, ["~> 0.7.6"])
79
93
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
80
94
  s.add_dependency(%q<bundler>, ["~> 1.0"])
81
- s.add_dependency(%q<jeweler>, ["~> 1.8.7"])
82
- s.add_dependency(%q<simplecov>, [">= 0"])
95
+ s.add_dependency(%q<jeweler>, ["~> 2.1"])
83
96
  end
84
97
  end
85
98
 
@@ -8,6 +8,7 @@ rescue Bundler::BundlerError => e
8
8
  exit e.status_code
9
9
  end
10
10
  require 'test/unit'
11
+ require 'mocha/test_unit'
11
12
  require 'shoulda'
12
13
 
13
14
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
@@ -0,0 +1,79 @@
1
+ require 'helper'
2
+
3
+ class TestActivity < Test::Unit::TestCase
4
+
5
+ context "A PivotalAPI::Activity" do
6
+
7
+ setup do
8
+ @activity = PivotalAPI::Activity.from_json([{
9
+ project_id: 1,
10
+ occurred_at: "2016-08-17T11:03:53-04:00",
11
+ highlight: "some-string",
12
+ primary_resources: [{foo: "bar"}],
13
+ changes: [{abc: "123"}],
14
+ guid: "123abc",
15
+ kind: "some-kind",
16
+ performed_by_id: 2,
17
+ performed_by: {
18
+ id: 2,
19
+ name: "John Appleseed",
20
+ initials: "JA",
21
+ email: "john@email.com",
22
+ username: "johnapple"
23
+ },
24
+ message: "some message",
25
+ project_version: 3
26
+ }])
27
+ end
28
+
29
+ should "have a valid project_id" do
30
+ assert_equal(1, @activity[0].project_id)
31
+ end
32
+
33
+ should "have a valid occurred_at date" do
34
+ assert_equal(DateTime.parse("2016-08-17T11:03:53-04:00"), @activity[0].occurred_at)
35
+ end
36
+
37
+ should "have a valid highlight" do
38
+ assert_equal("some-string", @activity[0].highlight)
39
+ end
40
+
41
+ should "have valid primary_resources" do
42
+ assert_equal("bar", @activity[0].primary_resources[0][:foo])
43
+ end
44
+
45
+ should "have valid changes" do
46
+ assert_equal("123", @activity[0].changes[0][:abc])
47
+ end
48
+
49
+ should "have a valid guid" do
50
+ assert_equal("123abc", @activity[0].guid)
51
+ end
52
+
53
+ should "have a valid kind" do
54
+ assert_equal("some-kind", @activity[0].kind)
55
+ end
56
+
57
+ should "have a valid performed_by_id" do
58
+ assert_equal(2, @activity[0].performed_by_id)
59
+ end
60
+
61
+ should "have a valid performed_by person" do
62
+ person = @activity[0].performed_by
63
+ assert_equal(2, person.id)
64
+ assert_equal("John Appleseed", person.name)
65
+ assert_equal("JA", person.initials)
66
+ assert_equal("john@email.com", person.email)
67
+ assert_equal("johnapple", person.username)
68
+ end
69
+
70
+ should "have a valid message" do
71
+ assert_equal("some message", @activity[0].message)
72
+ end
73
+
74
+ should "have a valid project_version" do
75
+ assert_equal(3, @activity[0].project_version)
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,38 @@
1
+ require 'helper'
2
+
3
+ class TestAnalytics < Test::Unit::TestCase
4
+
5
+ context "A PivotalAPI::Analytics" do
6
+
7
+ setup do
8
+ @analytics = PivotalAPI::Analytics.from_json({
9
+ stories_accepted: 5,
10
+ bugs_created: 2,
11
+ cycle_time: 343434,
12
+ rejection_rate: 33.8,
13
+ kind: "some-kind"
14
+ })
15
+ end
16
+
17
+ should "have a valid stories_accepted count" do
18
+ assert_equal(5, @analytics.stories_accepted)
19
+ end
20
+
21
+ should "have a valid bugs_created count" do
22
+ assert_equal(2, @analytics.bugs_created)
23
+ end
24
+
25
+ should "have a valid cycle_time" do
26
+ assert_equal(343434, @analytics.cycle_time)
27
+ end
28
+
29
+ should "have a valid rejection_rate" do
30
+ assert_equal(33.8, @analytics.rejection_rate)
31
+ end
32
+
33
+ should "have a valid kind" do
34
+ assert_equal("some-kind", @analytics.kind)
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,69 @@
1
+ require 'helper'
2
+
3
+ class TestAnalytics < Test::Unit::TestCase
4
+
5
+
6
+ context "A PivotalAPI::CycleTimeDetails" do
7
+
8
+ setup do
9
+ @cycle_time_details = PivotalAPI::CycleTimeDetails.from_json({
10
+ total_cycle_time: 12345,
11
+ started_time: 1111111111,
12
+ started_count: 2,
13
+ finished_time: 2222222222,
14
+ finished_count: 3,
15
+ delivered_time: 3333333333,
16
+ delivered_count: 4,
17
+ rejected_time: 4444444444,
18
+ rejected_count: 5,
19
+ story_id: 33,
20
+ kind: "some-kind"
21
+ })
22
+ end
23
+
24
+ should "have a valid total_cycle_time" do
25
+ assert_equal(12345, @cycle_time_details.total_cycle_time)
26
+ end
27
+
28
+ should "have a valid started_time" do
29
+ assert_equal(1111111111, @cycle_time_details.started_time)
30
+ end
31
+
32
+ should "have a valid started_count" do
33
+ assert_equal(2, @cycle_time_details.started_count)
34
+ end
35
+
36
+ should "have a valid finished_time" do
37
+ assert_equal(2222222222, @cycle_time_details.finished_time)
38
+ end
39
+
40
+ should "have a valid finished_count" do
41
+ assert_equal(3, @cycle_time_details.finished_count)
42
+ end
43
+
44
+ should "have a valid delivered_time" do
45
+ assert_equal(3333333333, @cycle_time_details.delivered_time)
46
+ end
47
+
48
+ should "have a valid delivered_count" do
49
+ assert_equal(4, @cycle_time_details.delivered_count)
50
+ end
51
+
52
+ should "have a valid rejected_time" do
53
+ assert_equal(4444444444, @cycle_time_details.rejected_time)
54
+ end
55
+
56
+ should "have a valid rejected_count" do
57
+ assert_equal(5, @cycle_time_details.rejected_count)
58
+ end
59
+
60
+ should "have a valid story_id" do
61
+ assert_equal(33, @cycle_time_details.story_id)
62
+ end
63
+
64
+ should "have a valid kind" do
65
+ assert_equal("some-kind", @cycle_time_details.kind)
66
+ end
67
+
68
+ end
69
+ end