lrd-pivotal-tracker 0.5.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,248 @@
1
+ require 'spec_helper'
2
+
3
+ describe PivotalTracker::Story do
4
+ before do
5
+ PivotalTracker::Client.token = TOKEN
6
+ @project = PivotalTracker::Project.find(PROJECT_ID)
7
+ end
8
+
9
+ context ".all" do
10
+ it "should return all stories" do
11
+ @project.stories.all.should be_a(Array)
12
+ @project.stories.all.first.should be_a(PivotalTracker::Story)
13
+ end
14
+
15
+ it "should allow filtering" do
16
+ @project.stories.all(:story_type => ['bug']).should be_a(Array)
17
+ @project.stories.all(:story_type => ['feature']).should be_a(Array)
18
+ end
19
+
20
+ it "should cache stories" do
21
+ count = @project.stories.all.count
22
+ @project.stories.all.count.should == count
23
+ bugs_count = @project.stories.all(:story_type => ['bug']).count
24
+ bugs_count.should_not == count
25
+ @project.stories.all(:story_type => ['bug']).count.should == bugs_count
26
+ end
27
+
28
+ end
29
+
30
+ context ".find" do
31
+ it "should return the matching story" do
32
+ @project.stories.find(ATTACHMENT_STORY).should be_a(PivotalTracker::Story)
33
+ end
34
+ end
35
+
36
+ context ".create" do
37
+ it "should return the created story" do
38
+ @project.stories.create(:name => 'Create Stuff').should be_a(PivotalTracker::Story)
39
+ end
40
+
41
+ context "on failure" do
42
+ before do
43
+ FakeWeb.register_uri(:post, "#{PivotalTracker::Client.api_url}/projects/#{@project.id}/stories",
44
+ :body => %{<?xml version="1.0" encoding="UTF-8"?>
45
+ <errors>
46
+ <error>error#1 message</error>
47
+ <error>error#2 message</error>
48
+ </errors>%},
49
+ :status => "422")
50
+ end
51
+
52
+ it "should not raise an exception" do
53
+ expect { @project.stories.create }.to_not raise_error(Exception)
54
+ end
55
+
56
+ it "should report errors encountered" do
57
+ story = @project.stories.create :name => "Invalid story"
58
+ story.errors.messages.should =~ ["error#1 message", "error#2 message"]
59
+ end
60
+ end
61
+ end
62
+
63
+ context ".attachments" do
64
+ it "should return an array of attachments" do
65
+ @story = @project.stories.find(ATTACHMENT_STORY)
66
+ @story.attachments.should be_a(Array)
67
+ @story.attachments.first.should be_a(PivotalTracker::Attachment)
68
+ end
69
+ end
70
+
71
+ context ".move" do
72
+ let(:project_id) { @project.id }
73
+ let(:top_story_id) {ATTACHMENT_STORY}
74
+ let(:bottom_story_id) {UPLOAD_STORY}
75
+ let(:top_story) { @project.stories.find(top_story_id) }
76
+ let(:bottom_story) { @project.stories.find(bottom_story_id) }
77
+
78
+ it "should return the moved story when moved before" do
79
+ expected_uri = "#{PivotalTracker::Client.api_url}/projects/#{project_id}/stories/#{top_story_id}/moves?move\[move\]=before&move\[target\]=#{bottom_story_id}"
80
+ FakeWeb.register_uri(:post, expected_uri, :body => %{<story><id type="integer">#{top_story_id}</id></story>})
81
+ @moved_story = top_story.move(:before, bottom_story)
82
+ @moved_story.should be_a(PivotalTracker::Story)
83
+ @moved_story.id.should be(top_story_id)
84
+ end
85
+
86
+ it "should return the moved story when moved after" do
87
+ expected_uri = "#{PivotalTracker::Client.api_url}/projects/#{project_id}/stories/#{bottom_story_id}/moves?move\[move\]=after&move\[target\]=#{top_story_id}"
88
+ FakeWeb.register_uri(:post, expected_uri, :body => %{<story><id type="integer">#{bottom_story_id}</id></story>})
89
+ @moved_story = bottom_story.move(:after, top_story)
90
+ @moved_story.should be_a(PivotalTracker::Story)
91
+ @moved_story.id.should be(bottom_story_id)
92
+ end
93
+
94
+ it "should raise an error when trying to move in an invalid position" do
95
+ expect { top_story.move(:next_to, bottom_story) }.to raise_error(ArgumentError)
96
+ end
97
+ end
98
+
99
+ context ".move_to_project" do
100
+ let(:expected_uri) {"#{PivotalTracker::Client.api_url}/projects/#{project_id}/stories/#{story_id}"}
101
+ let(:project_id) { @project.id }
102
+ let(:movable_story) { @project.stories.find(ATTACHMENT_STORY) }
103
+ let(:story_id) { movable_story.id }
104
+ let(:target_project) { PivotalTracker::Project.new(:id => 103014) }
105
+
106
+ before do
107
+ FakeWeb.register_uri(:put, expected_uri, :body => %{<?xml version="1.0" encoding="UTF-8"?>
108
+ <story>
109
+ <project_id type="integer">#{target_project.id}</project_id>
110
+ </story>})
111
+ end
112
+
113
+ it "should return an updated story from the target project when passed a PivotalTracker::Story" do
114
+ target_story = PivotalTracker::Story.new(:project_id => target_project.id)
115
+ response = movable_story.move_to_project(target_story)
116
+ response.should_not be_nil
117
+ response.project_id.should == target_story.project_id
118
+ end
119
+
120
+ it "should return an updated story from the target project when passed a PivotalTracker::Project" do
121
+ response = movable_story.move_to_project(target_project)
122
+ response.project_id.should == target_project.id
123
+ end
124
+
125
+ it "should return an updated story from the target project when passed a String" do
126
+ response = movable_story.move_to_project(target_project.id.to_s)
127
+ response.project_id.should == target_project.id
128
+ end
129
+
130
+ it "should return an updated story from the target project when passed an Integer"do
131
+ response = movable_story.move_to_project(target_project.id.to_i)
132
+ response.project_id.should == target_project.id
133
+ end
134
+ end
135
+
136
+ context ".new" do
137
+
138
+ def story_for(attrs)
139
+ story = @project.stories.new(attrs)
140
+ @story = Crack::XML.parse(story.send(:to_xml))['story']
141
+ end
142
+
143
+ describe "attributes that are not sent to the tracker" do
144
+
145
+ it "should include id" do
146
+ story_for(:id => 10)["id"].should be_nil
147
+ end
148
+
149
+ it "should include url" do
150
+ story_for(:url => "somewhere")["url"].should be_nil
151
+ end
152
+
153
+ end
154
+
155
+ describe "attributes that are sent to the tracker" do
156
+
157
+ it "should include name" do
158
+ story_for(:name => "A user should...")["name"].should == "A user should..."
159
+ end
160
+
161
+ it "should include description" do
162
+ story_for(:description => "desc...")["description"].should == "desc..."
163
+ end
164
+
165
+ it "should include story_type" do
166
+ story_for(:story_type => "feature")["story_type"].should == "feature"
167
+ end
168
+
169
+ it "should include estimate" do
170
+ story_for(:estimate => 5)["estimate"].should == "5"
171
+ end
172
+
173
+ it "should include current_state" do
174
+ story_for(:current_state => "accepted")["current_state"].should == "accepted"
175
+ end
176
+
177
+ it "should include requested_by" do
178
+ story_for(:requested_by => "Joe Doe")["requested_by"].should == "Joe Doe"
179
+ end
180
+
181
+ it "should include owned_by" do
182
+ story_for(:owned_by => "Joe Doe")["owned_by"].should == "Joe Doe"
183
+ end
184
+
185
+ it "should include labels" do
186
+ story_for(:labels => "abc")["labels"].should == "abc"
187
+ end
188
+
189
+ describe "should include other_id" do
190
+ it "when passed a string" do
191
+ story_for(:other_id => "aa10bb")["other_id"].should == "aa10bb"
192
+ end
193
+ it "when passed an integer" do
194
+ story_for(:other_id => 10)["other_id"].should == "10"
195
+ end
196
+ end
197
+
198
+ it "should include integration_id" do
199
+ story_for(:integration_id => 1000)["integration_id"].should == '1000'
200
+ end
201
+
202
+ it "should not include integration_id if it doesn't exist" do
203
+ story_for(:other_id => 1000).keys.should_not include("integration_id")
204
+ end
205
+
206
+ it "should not include other_id if it doesn't exist" do
207
+ story_for(:project_id => 1000).keys.should_not include("other_id")
208
+ end
209
+
210
+ # the tracker returns 422 when this is included, even if it is not used
211
+ # it "should include jira_id" do
212
+ # story_for(:jira_id => 10)["jira_id"].should == "10"
213
+ # end
214
+ #
215
+ # it "should include jira_url" do
216
+ # story_for(:jira_url => "somewhere")["jira_url"].should == "somewhere"
217
+ # end
218
+
219
+ context "date attributes" do
220
+ before do
221
+ @datestring = "1984-09-20T10:23:00+00:00"
222
+ @date = DateTime.new(1984, 9, 20, 10, 23, 0, 0)
223
+ end
224
+
225
+ [:created_at, :accepted_at].each do |date_attribute|
226
+ it "should include #{date_attribute} date when given a string" do
227
+ story_for(:created_at => @date.to_s)["created_at"].should == @datestring
228
+ end
229
+
230
+ it "should include #{date_attribute} date when given a Time" do
231
+ story_for(:created_at => Time.parse(@date.to_s).utc)["created_at"].should == @datestring
232
+ end
233
+
234
+ it "should include #{date_attribute} date when given a DateTime" do
235
+ story_for(:created_at => @date)["created_at"].should == @datestring
236
+ end
237
+
238
+ it "should include #{date_attribute} date when given a Date" do
239
+ # Dates don't have time zones, but the time will be in local time, so we convert the date to create the expectation
240
+ story_for(:created_at => Date.new(1984, 9, 20))["created_at"].should == DateTime.new(1984, 9, 20).to_s
241
+ end
242
+ end
243
+ end
244
+ end
245
+
246
+ end
247
+
248
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe PivotalTracker::Task do
4
+ before do
5
+ PivotalTracker::Client.token = TOKEN
6
+ @project = PivotalTracker::Project.find(PROJECT_ID)
7
+ @story = @project.stories.find(ATTACHMENT_STORY)
8
+ end
9
+
10
+ context ".all" do
11
+ it "should return an array of tasks" do
12
+ @story.tasks.all.should be_a(Array)
13
+ @story.tasks.all.first.should be_a(PivotalTracker::Task)
14
+ end
15
+ end
16
+
17
+ context ".find" do
18
+ it "should return a given task" do
19
+ @story.tasks.find(TASK_ID).should be_a(PivotalTracker::Task)
20
+ end
21
+ end
22
+
23
+ context ".create" do
24
+ it "should return the created task" do
25
+ @story.tasks.create(:description => 'Test task')
26
+ end
27
+ end
28
+
29
+ context '.update' do
30
+ it "should return the updated task" do
31
+ @story.tasks.find(TASK_ID).update(:description => 'Test task').description.should == 'Test task'
32
+ end
33
+ end
34
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,38 @@
1
+ require 'bundler'
2
+ require 'fileutils'
3
+ require 'crack'
4
+
5
+ Bundler.require(:default, :runtime, :test)
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+
9
+ require 'pivotal_tracker'
10
+ require 'rspec'
11
+ require 'rspec/autorun'
12
+
13
+ PROJECT_ID = ENV['PROJECT_ID'] || 833075
14
+ PAGE_PROJECT_ID = ENV['PAGE_PROJECT_ID'] || 10606
15
+ ATTACHMENT_STORY = 51345231
16
+ UPLOAD_STORY = 51345285
17
+ MEMBER = 3129903
18
+ TASK_ID = 15030357
19
+ TOKEN = 'c894469f31a343c1f94017752a2a496f'
20
+
21
+ PivotalTracker::Client.token = TOKEN
22
+
23
+ # Requires supporting files with custom matchers and macros, etc,
24
+ # in ./support/ and its subdirectories.
25
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
26
+
27
+
28
+ RSpec.configure do |config|
29
+ # setup VCR to record all external requests with a single casette
30
+ # works for everything but features
31
+ config.around :each do |example|
32
+ VCR.use_cassette("default_vcr_cassette") { example.call }
33
+ end
34
+
35
+ config.before :each do
36
+ PivotalTracker::Client.clear_connections
37
+ end
38
+ end
@@ -0,0 +1,10 @@
1
+ require 'vcr'
2
+
3
+ VCR.configure do |c|
4
+ c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
5
+ c.hook_into :fakeweb
6
+ c.debug_logger = File.open(File.join(File.dirname(__FILE__), '..', '..', 'log/vcr_debug.log'), 'w')
7
+ c.default_cassette_options = { :record => :new_episodes }
8
+ c.allow_http_connections_when_no_cassette = true
9
+ c.configure_rspec_metadata!
10
+ end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lrd-pivotal-tracker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.14
5
+ platform: ruby
6
+ authors:
7
+ - Justin Smestad
8
+ - Josh Nichols
9
+ - Terence Lee
10
+ - Judson Lester
11
+ - Hannah Howard
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+ date: 2012-11-25 00:00:00.000000000 Z
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: rest-client
19
+ requirement: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "~>"
22
+ - !ruby/object:Gem::Version
23
+ version: 1.6.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: 1.6.0
31
+ - !ruby/object:Gem::Dependency
32
+ name: nokogiri
33
+ requirement: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: 1.5.5
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 1.5.5
45
+ - !ruby/object:Gem::Dependency
46
+ name: happymapper
47
+ requirement: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 0.3.2
52
+ type: :runtime
53
+ prerelease: false
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 0.3.2
59
+ - !ruby/object:Gem::Dependency
60
+ name: nokogiri-happymapper
61
+ requirement: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: 0.5.4
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.5.4
73
+ - !ruby/object:Gem::Dependency
74
+ name: builder
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ type: :runtime
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ - !ruby/object:Gem::Dependency
88
+ name: crack
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ type: :runtime
95
+ prerelease: false
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ description: Ruby wrapper for Pivotal Tracker API, no frameworks required. Simply
102
+ Ruby.
103
+ email: hannah@lrdesign.com
104
+ executables: []
105
+ extensions: []
106
+ extra_rdoc_files:
107
+ - LICENSE
108
+ - README.rdoc
109
+ files:
110
+ - Gemfile
111
+ - Gemfile.lock
112
+ - LICENSE
113
+ - README.rdoc
114
+ - Rakefile
115
+ - VERSION
116
+ - lib/pivotal-tracker.rb
117
+ - lib/pivotal-tracker/activity.rb
118
+ - lib/pivotal-tracker/attachment.rb
119
+ - lib/pivotal-tracker/author.rb
120
+ - lib/pivotal-tracker/client.rb
121
+ - lib/pivotal-tracker/extensions.rb
122
+ - lib/pivotal-tracker/iteration.rb
123
+ - lib/pivotal-tracker/membership.rb
124
+ - lib/pivotal-tracker/note.rb
125
+ - lib/pivotal-tracker/project.rb
126
+ - lib/pivotal-tracker/proxy.rb
127
+ - lib/pivotal-tracker/story.rb
128
+ - lib/pivotal-tracker/task.rb
129
+ - lib/pivotal-tracker/validation.rb
130
+ - lib/pivotal_tracker.rb
131
+ - lrd-pivotal-tracker.gemspec
132
+ - spec/fixtures/vcr_cassettes/default_vcr_cassette.yml
133
+ - spec/pivotal-tracker/activity_spec.rb
134
+ - spec/pivotal-tracker/attachment_spec.rb
135
+ - spec/pivotal-tracker/client_spec.rb
136
+ - spec/pivotal-tracker/iteration_spec.rb
137
+ - spec/pivotal-tracker/membership_spec.rb
138
+ - spec/pivotal-tracker/note_spec.rb
139
+ - spec/pivotal-tracker/project_spec.rb
140
+ - spec/pivotal-tracker/story_spec.rb
141
+ - spec/pivotal-tracker/task_spec.rb
142
+ - spec/spec.opts
143
+ - spec/spec_helper.rb
144
+ - spec/support/vcr_config.rb
145
+ homepage: http://git.lrdesign.com/lrd/lrd-pivotal-tracker
146
+ licenses:
147
+ - MIT
148
+ metadata: {}
149
+ post_install_message:
150
+ rdoc_options: []
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ requirements: []
164
+ rubyforge_project:
165
+ rubygems_version: 2.4.8
166
+ signing_key:
167
+ specification_version: 4
168
+ summary: Ruby wrapper for the Pivotal Tracker API
169
+ test_files: []