pivit 0.1.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 (42) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +30 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +94 -0
  6. data/Rakefile +1 -0
  7. data/lib/pivit.rb +20 -0
  8. data/lib/pivit/authentication.rb +22 -0
  9. data/lib/pivit/client.rb +40 -0
  10. data/lib/pivit/client/activity.rb +34 -0
  11. data/lib/pivit/client/iteration.rb +88 -0
  12. data/lib/pivit/client/membership.rb +92 -0
  13. data/lib/pivit/client/note.rb +47 -0
  14. data/lib/pivit/client/project.rb +58 -0
  15. data/lib/pivit/client/story.rb +177 -0
  16. data/lib/pivit/client/task.rb +112 -0
  17. data/lib/pivit/configuration.rb +29 -0
  18. data/lib/pivit/connection.rb +24 -0
  19. data/lib/pivit/error.rb +6 -0
  20. data/lib/pivit/request.rb +56 -0
  21. data/lib/pivit/version.rb +3 -0
  22. data/pivit.gemspec +37 -0
  23. data/spec/fixtures/authentications.yml.sample +11 -0
  24. data/spec/fixtures/stubs/iteration.xml +77 -0
  25. data/spec/fixtures/stubs/membership.xml +15 -0
  26. data/spec/fixtures/stubs/note.xml +7 -0
  27. data/spec/fixtures/stubs/project/project.xml +29 -0
  28. data/spec/fixtures/stubs/story/delete_story.xml +13 -0
  29. data/spec/fixtures/stubs/task.xml +8 -0
  30. data/spec/fixtures/stubs/task_update.xml +8 -0
  31. data/spec/fixtures/test.png +0 -0
  32. data/spec/pivit/client/activity_spec.rb +26 -0
  33. data/spec/pivit/client/iteration_spec.rb +104 -0
  34. data/spec/pivit/client/membership_spec.rb +91 -0
  35. data/spec/pivit/client/note_spec.rb +48 -0
  36. data/spec/pivit/client/project_spec.rb +64 -0
  37. data/spec/pivit/client/story_spec.rb +156 -0
  38. data/spec/pivit/client/task_spec.rb +124 -0
  39. data/spec/pivit/client_spec.rb +47 -0
  40. data/spec/pivit/configuration_spec.rb +29 -0
  41. data/spec/spec_helper.rb +54 -0
  42. metadata +314 -0
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+
3
+ # note Spec
4
+ describe Pivit::Client::Note do
5
+ before do
6
+ Pivit.reset!
7
+ end
8
+
9
+ let!(:pivit) { Pivit::Client.new(:token=> ENV["TOKEN"]) }
10
+
11
+ describe ".notes", :vcr => {:cassette_name => "note/notes"} do
12
+ let(:current_response) { pivit.notes(ENV["PROJECT"], ENV["STORY"]) }
13
+
14
+ it "return an array of notes" do
15
+ current_response.should be_a(Array)
16
+ end
17
+
18
+ it "return the notes" do
19
+ current_response.should_not be_nil
20
+ end
21
+
22
+ it "returns the text of the note" do
23
+ current_response.each{ |x| x.should respond_to(:text) }
24
+ end
25
+ end
26
+
27
+ describe ".create_note", :type => :webmock do
28
+ let(:current_response) { pivit.create_note(ENV["PROJECT"], ENV["STORY"], ENV["NOTE"]) }
29
+
30
+ it "returns the note that was created" do
31
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/795721/stories?note%5Btext%5D=This%20is%20some%20note%20text").
32
+ to_return(:status => 200,
33
+ :body => File.open(File.expand_path("../../../fixtures/stubs/note.xml", __FILE__)),
34
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
35
+
36
+ current_response.should respond_to(:text)
37
+ end
38
+
39
+ it "be a hashie" do
40
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/795721/stories?note%5Btext%5D=This%20is%20some%20note%20text").
41
+ to_return(:status => 200,
42
+ :body => File.open(File.expand_path("../../../fixtures/stubs/note.xml", __FILE__)),
43
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
44
+
45
+ current_response.should be_a(Hashie::Mash)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,64 @@
1
+ require "spec_helper"
2
+
3
+ # Client Spec
4
+ describe Pivit::Client do
5
+ before do
6
+ Pivit.reset!
7
+ end
8
+
9
+ describe ".project", :vcr do
10
+ let!(:pivit) { Pivit::Client.new(:token => ENV["TOKEN"]) }
11
+ let(:current_response) { pivit.project(ENV["PROJECT"]) }
12
+
13
+ it "should return the project response" do
14
+ current_response.should_not be_nil
15
+ current_response.should respond_to(:name)
16
+ end
17
+ end
18
+
19
+ describe ".projects", :vcr => {:cassette_name => "project/projects"} do
20
+ let!(:pivit) { Pivit::Client.new(:token => ENV["TOKEN"]) }
21
+ let(:current_response) { pivit.projects }
22
+
23
+ it "should return an array of projects" do
24
+ current_response.should be_a(Array)
25
+ current_response.first.should respond_to(:account)
26
+ end
27
+
28
+ it "should return the projects" do
29
+ current_response.should_not be_nil
30
+ end
31
+ end
32
+
33
+ describe ".create_project", :type => :webmock do
34
+ let!(:pivit) { Pivit::Client.new(:token => ENV["TOKEN"]) }
35
+ let(:current_response) { pivit.create_project({:name => "Awesome Test Project", :iteration_length => 2, :point_scale => "0,1,2,3,4"}) }
36
+
37
+ it "returns the project that was created" do
38
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects?project%5Biteration_length%5D=2&project%5Bname%5D=Awesome%20Test%20Project&project%5Bpoint_scale%5D=0,1,2,3,4").
39
+ to_return(:status => 200,
40
+ :body => File.open(File.expand_path("../../../fixtures/stubs/project/project.xml", __FILE__)),
41
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
42
+
43
+ current_response.should respond_to(:name)
44
+ end
45
+
46
+ it "returns the project that was created with the attributes provided" do
47
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects?project%5Biteration_length%5D=2&project%5Bname%5D=Awesome%20Test%20Project&project%5Bpoint_scale%5D=0,1,2,3,4").
48
+ to_return(:status => 200,
49
+ :body => File.open(File.expand_path("../../../fixtures/stubs/project/project.xml", __FILE__)),
50
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
51
+
52
+ current_response.name.should == "Cardassian War Plans"
53
+ end
54
+
55
+ it "should be a hashie" do
56
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects?project%5Biteration_length%5D=2&project%5Bname%5D=Awesome%20Test%20Project&project%5Bpoint_scale%5D=0,1,2,3,4").
57
+ to_return(:status => 200,
58
+ :body => File.open(File.expand_path("../../../fixtures/stubs/project/project.xml", __FILE__)),
59
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
60
+
61
+ current_response.should be_a(Hashie::Mash)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,156 @@
1
+ require "spec_helper"
2
+
3
+ # Story Spec
4
+ describe Pivit::Client::Story do
5
+ before do
6
+ Pivit.reset!
7
+ end
8
+
9
+ let!(:pivit) { Pivit::Client.new(:token=> ENV["TOKEN"]) }
10
+
11
+ describe ".story", :vcr do
12
+ let(:current_response) { pivit.story(ENV["PROJECT"], ENV["STORY"]) }
13
+
14
+ it "should return the story response" do
15
+ current_response.should_not be_nil
16
+ current_response.should respond_to(:name)
17
+ end
18
+ end
19
+
20
+ describe ".stories", :vcr => {:cassette_name => "story/stories"} do
21
+ let(:current_response) { pivit.stories(ENV["PROJECT"]) }
22
+
23
+ it "should return an array of stories" do
24
+ current_response.should be_a(Array)
25
+ current_response.first.should respond_to(:current_state)
26
+ end
27
+
28
+ it "should return the stories" do
29
+ current_response.should_not be_nil
30
+ end
31
+ end
32
+
33
+ describe ".create_story", :vcr => {:cassette_name => "story/create_story"} do
34
+ let(:current_response) {
35
+ pivit.create_story(ENV["PROJECT"],
36
+ {
37
+ :name => "Awesome Test story",
38
+ :story_type =>"feature"
39
+ })
40
+ }
41
+
42
+ it "returns the story that was created" do
43
+ current_response.should respond_to(:name)
44
+ end
45
+
46
+ it "should be a hashie" do
47
+ current_response.should be_a(Hashie::Mash)
48
+ end
49
+ end
50
+
51
+ describe ".update_story", :vcr => {:cassette_name => "story/update_story"} do
52
+ let(:name) { "awesome new name" }
53
+ let(:current_response) {
54
+ pivit.update_story(ENV["PROJECT"],
55
+ ENV["STORY"],
56
+ {
57
+ :name => name
58
+ })
59
+ }
60
+
61
+ it "returns the story that was update" do
62
+ current_response.should respond_to(:name)
63
+ end
64
+
65
+ it "updates the attributes specified" do
66
+ current_response.name.should == name
67
+ end
68
+
69
+ it "should be a hashie" do
70
+ current_response.should be_a(Hashie::Mash)
71
+ end
72
+ end
73
+
74
+ describe ".delete_story", :type => :webmock do
75
+ let(:current_response) { pivit.delete_story(ENV["PROJECT"], ENV["STORY"]) }
76
+
77
+ it "returns the story that was deleted" do
78
+ stub_request(:delete, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617").
79
+ to_return(:status => 200,
80
+ :body => File.open(File.expand_path("../../../fixtures/stubs/story/delete_story.xml", __FILE__)),
81
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
82
+
83
+ current_response.id.should == ENV["STORY"].to_i
84
+ end
85
+
86
+ it "should be a hashie" do
87
+ stub_request(:delete, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617").
88
+ to_return(:status => 200,
89
+ :body => File.open(File.expand_path("../../../fixtures/stubs/story/delete_story.xml", __FILE__)),
90
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
91
+
92
+ current_response.should be_a(Hashie::Mash)
93
+ end
94
+ end
95
+
96
+ describe ".move_story_before", :type => :webmock do
97
+ let(:current_response) { pivit.move_story_before(ENV["PROJECT"], ENV["STORY"], ENV["STORY_B"]) }
98
+
99
+ it "returns the story that was moved" do
100
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/moves?move%5Bmove%5D=before&move%5Btarget%5D=47998079").
101
+ to_return(:status => 200,
102
+ :body => File.open(File.expand_path("../../../fixtures/stubs/story/delete_story.xml", __FILE__)),
103
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
104
+
105
+ current_response.id.should == ENV["STORY"].to_i
106
+ end
107
+
108
+ it "should be a hashie" do
109
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/moves?move%5Bmove%5D=before&move%5Btarget%5D=47998079").
110
+ to_return(:status => 200,
111
+ :body => File.open(File.expand_path("../../../fixtures/stubs/story/delete_story.xml", __FILE__)),
112
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
113
+
114
+ current_response.should be_a(Hashie::Mash)
115
+ end
116
+ end
117
+
118
+ describe ".move_story_after", :type => :webmock do
119
+ let(:current_response) { pivit.move_story_after(ENV["PROJECT"], ENV["STORY"], ENV["STORY_B"]) }
120
+
121
+ it "returns the story that was moved" do
122
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/moves?move%5Bmove%5D=after&move%5Btarget%5D=47998079").
123
+ to_return(:status => 200,
124
+ :body => File.open(File.expand_path("../../../fixtures/stubs/story/delete_story.xml", __FILE__)),
125
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
126
+
127
+ current_response.id.should == ENV["STORY"].to_i
128
+ end
129
+
130
+ it "should be a hashie" do
131
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/moves?move%5Bmove%5D=after&move%5Btarget%5D=47998079").
132
+ to_return(:status => 200,
133
+ :body => File.open(File.expand_path("../../../fixtures/stubs/story/delete_story.xml", __FILE__)),
134
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
135
+
136
+ current_response.should be_a(Hashie::Mash)
137
+ end
138
+ end
139
+
140
+ describe ".add_attachment", :vcr => {:cassette_name => "story/attachment"} do
141
+ let(:current_response) {
142
+ pivit.add_attachment(
143
+ ENV["PROJECT"],
144
+ ENV["STORY"],
145
+ File.path(File.expand_path(ENV["FILE"], __FILE__)))
146
+ }
147
+
148
+ it "adds the attachment to the story" do
149
+ current_response.should_not be_nil
150
+ end
151
+
152
+ it "returns the status is pending" do
153
+ current_response.status.should == "Pending"
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,124 @@
1
+ require "spec_helper"
2
+
3
+ # Task Spec
4
+ describe Pivit::Client::Task do
5
+ before do
6
+ Pivit.reset!
7
+ end
8
+
9
+ let!(:pivit) { Pivit::Client.new(:token=> ENV["TOKEN"]) }
10
+
11
+ describe ".task", :vcr => {:cassette_name => "task/task"} do
12
+ let(:current_response) { pivit.task(ENV["PROJECT"], ENV["STORY"], ENV["TASK"]) }
13
+
14
+ it "return the task response" do
15
+ current_response.should_not be_nil
16
+ end
17
+
18
+ it "responds to description" do
19
+ current_response.should respond_to(:description)
20
+ end
21
+ end
22
+
23
+ describe ".tasks", :vcr => {:cassette_name => "task/tasks"} do
24
+ let(:current_response) { pivit.tasks(ENV["PROJECT"], ENV["STORY"]) }
25
+
26
+ it "should return an array of tasks" do
27
+ current_response.should be_a(Array)
28
+ end
29
+
30
+ it "responds to description" do
31
+ current_response.each{|x| x.should respond_to(:description) }
32
+ end
33
+
34
+ it "should return the tasks" do
35
+ current_response.should_not be_nil
36
+ end
37
+ end
38
+
39
+ describe ".create_task", :type => :webmock do
40
+ let(:description) { "find shields" }
41
+ let(:current_response) { pivit.create_task(ENV["PROJECT"], ENV["STORY"], { :description => description })}
42
+
43
+ it "returns the task that was created" do
44
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/tasks?task%5Bdescription%5D=find%20shields").
45
+ to_return(:status => 200,
46
+ :body => File.open(File.expand_path("../../../fixtures/stubs/task.xml", __FILE__)),
47
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
48
+
49
+ current_response.should respond_to(:description)
50
+ end
51
+
52
+ it "returns the description specified" do
53
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/tasks?task%5Bdescription%5D=find%20shields").
54
+ to_return(:status => 200,
55
+ :body => File.open(File.expand_path("../../../fixtures/stubs/task.xml", __FILE__)),
56
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
57
+
58
+ current_response.description.should == description
59
+ end
60
+
61
+ it "should be a hashie" do
62
+ stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/tasks?task%5Bdescription%5D=find%20shields").
63
+ to_return(:status => 200,
64
+ :body => File.open(File.expand_path("../../../fixtures/stubs/task.xml", __FILE__)),
65
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
66
+
67
+ current_response.should be_a(Hashie::Mash)
68
+ end
69
+ end
70
+
71
+ describe ".update_task", :type => :webmock do
72
+ let(:description) { "awesome new description" }
73
+ let(:current_response) { pivit.update_task(ENV["PROJECT"], ENV["STORY"], ENV["TASK"], { :description => description })}
74
+
75
+ it "returns the task that was update" do
76
+ stub_request(:put, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/tasks/14216257?task%5Bdescription%5D=awesome%20new%20description").
77
+ to_return(:status => 200,
78
+ :body => File.open(File.expand_path("../../../fixtures/stubs/task_update.xml", __FILE__)),
79
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
80
+
81
+ current_response.should respond_to(:description)
82
+ end
83
+
84
+ it "updates the attributes specified" do
85
+ stub_request(:put, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/tasks/14216257?task%5Bdescription%5D=awesome%20new%20description").
86
+ to_return(:status => 200,
87
+ :body => File.open(File.expand_path("../../../fixtures/stubs/task_update.xml", __FILE__)),
88
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
89
+
90
+ current_response.description.should == description
91
+ end
92
+
93
+ it "should be a hashie" do
94
+ stub_request(:put, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/tasks/14216257?task%5Bdescription%5D=awesome%20new%20description").
95
+ to_return(:status => 200,
96
+ :body => File.open(File.expand_path("../../../fixtures/stubs/task_update.xml", __FILE__)),
97
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
98
+
99
+ current_response.should be_a(Hashie::Mash)
100
+ end
101
+ end
102
+
103
+ describe ".delete_task", :type => :webmock do
104
+ let(:current_response) { pivit.delete_task(ENV["PROJECT"], ENV["STORY"], ENV["TASK"]) }
105
+
106
+ it "returns the task that was deleted" do
107
+ stub_request(:delete, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/tasks/14216257").
108
+ to_return(:status => 200,
109
+ :body => File.open(File.expand_path("../../../fixtures/stubs/task.xml", __FILE__)),
110
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
111
+
112
+ current_response.id.should == ENV["TASK"].to_i
113
+ end
114
+
115
+ it "should be a hashie" do
116
+ stub_request(:delete, "https://www.pivotaltracker.com/services/v3/projects/795721/stories/48859617/tasks/14216257").
117
+ to_return(:status => 200,
118
+ :body => File.open(File.expand_path("../../../fixtures/stubs/task.xml", __FILE__)),
119
+ :headers => {'Accept' => 'application/xml', 'Content-type' => 'application/xml',})
120
+
121
+ current_response.should be_a(Hashie::Mash)
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ # Client Spec
4
+ describe Pivit::Client do
5
+ before do
6
+ Pivit.reset!
7
+ end
8
+
9
+ describe "#initialize", :vcr => {:cassette_name => "client/initialize"} do
10
+ it "can be initialized" do
11
+ Pivit::Client.new(:username => ENV["USERNAME"], :password => ENV["PASSWORD"]).class.should == Pivit::Client
12
+ end
13
+
14
+ it "is aliased within itself" do
15
+ Pivit.new(:username => ENV["USERNAME"], :password => ENV["PASSWORD"]).class.should == Pivit::Client
16
+ end
17
+
18
+ it "works with basic username and password" do
19
+ Pivit::Client.new(:username => ENV["USERNAME"], :password => ENV["PASSWORD"])
20
+ .should_not
21
+ raise_exception
22
+ end
23
+
24
+ it "works with token" do
25
+ Pivit::Client.new(:token=> ENV["TOKEN"])
26
+ .should_not
27
+ raise_exception
28
+ end
29
+
30
+ it "can be configured to use a different ssl option via options" do
31
+ client = Pivit::Client.new(:token => ENV["TOKEN"], :ssl => false )
32
+ client.ssl.should == false
33
+ end
34
+
35
+ it "raises an exception if the incorrect options are used" do
36
+ lambda{ Pivit::Client.new(:broke => "broken") }.should raise_exception
37
+ end
38
+
39
+ context "authenticated" do
40
+ let!(:client) { Pivit::Client.new(:username => ENV["USERNAME"], :password => ENV["PASSWORD"]) }
41
+
42
+ it "does not generate an endpoint with username and password" do
43
+ client.api_endpoint.should_not include("#{ENV["USERNAME"]}:#{ENV["PASSWORD"]}")
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ # Configuration Spec
4
+ describe Pivit::Client do
5
+ describe "configuration" do
6
+ # SSL
7
+ describe "with a ssl", :vcr do
8
+ let(:ssl) { false }
9
+ let(:client) {
10
+ Pivit::Client.new(:username => ENV["USERNAME"], :password => ENV["PASSWORD"])
11
+ }
12
+
13
+ before do
14
+ Pivit.reset!
15
+ Pivit.configure do |c|
16
+ c.ssl = ssl
17
+ end
18
+ end
19
+
20
+ it "sets the ssl for the client" do
21
+ client.ssl.should == ssl
22
+ end
23
+
24
+ it "builds an endpoint with the ssl set to false" do
25
+ client.api_endpoint.should include("http://")
26
+ end
27
+ end
28
+ end
29
+ end