teamcity-rest-client 0.1.1 → 0.2.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
@@ -4,9 +4,76 @@ require 'set'
4
4
 
5
5
  module TeamcityRestClient
6
6
 
7
- Project = Struct.new(:teamcity, :name, :id, :href) do
8
- def build_types
9
- teamcity.build_types.find_all { |bt| bt.project_id == id }
7
+ class Filter
8
+ end
9
+
10
+ class IncludeAllFilter
11
+ def retain? thing
12
+ true
13
+ end
14
+ def misses
15
+ []
16
+ end
17
+ end
18
+
19
+ class ExcludeNoneFilter
20
+ def retain? thing
21
+ true
22
+ end
23
+ def misses
24
+ []
25
+ end
26
+ end
27
+
28
+ class IncludeFilter
29
+ def initialize to_retain
30
+ @misses = [to_retain].flatten
31
+ end
32
+
33
+ def retain? build_type
34
+ @misses.delete(build_type.id) || @misses.delete(build_type.name) ? true : false
35
+ end
36
+
37
+ def misses
38
+ @misses
39
+ end
40
+ end
41
+
42
+ class ExcludeFilter
43
+ def initialize to_exclude
44
+ @misses = [to_exclude].flatten
45
+ end
46
+
47
+ def retain? build_type
48
+ @misses.delete(build_type.id) || @misses.delete(build_type.name) ? false : true
49
+ end
50
+
51
+ def misses
52
+ @misses
53
+ end
54
+ end
55
+
56
+ class Project
57
+
58
+ attr_reader :teamcity, :name, :id, :href
59
+
60
+ def initialize teamcity, name, id, href
61
+ @teamcity, @name, @id, @href = teamcity, name, id, href
62
+ end
63
+
64
+ def build_types filter = {}
65
+ including = filter.has_key?(:include) ? IncludeFilter.new(filter.delete(:include)) : IncludeAllFilter.new
66
+ excluding = filter.has_key?(:exclude) ? ExcludeFilter.new(filter.delete(:exclude)) : ExcludeNoneFilter.new
67
+ raise "Unsupported filter options #{filter}" unless filter.empty?
68
+ build_types_for_project = teamcity.build_types.find_all { |bt| bt.project_id == id }
69
+ filtered_build_types = build_types_for_project.find_all { |bt| including.retain?(bt) && excluding.retain?(bt) }
70
+ raise "Failed to find a match for build type(s) #{including.misses}" if not including.misses.empty?
71
+ raise "Failed to find a match for build type(s) #{excluding.misses}" if not excluding.misses.empty?
72
+ filtered_build_types
73
+ end
74
+
75
+ def latest_builds filter = {}
76
+ build_types(filter).collect(&:latest_build)
10
77
  end
11
78
 
12
79
  def builds
@@ -15,25 +82,40 @@ module TeamcityRestClient
15
82
  end
16
83
  end
17
84
 
18
- BuildType = Struct.new(:id, :name, :href, :project_name, :project_id, :web_url)
85
+ BuildType = Struct.new(:teamcity, :id, :name, :href, :project_name, :project_id, :web_url) do
86
+ # httpAuth/app/rest/builds?buildType=id:bt107&count=1
87
+ def latest_build
88
+ teamcity.builds(:buildType => "id:#{id}", :count => 1)[0]
89
+ end
90
+ end
19
91
 
20
- Build = Struct.new(:id, :number, :status, :build_type_id, :start_date, :href, :web_url) do
92
+ Build = Struct.new(:teamcity, :id, :number, :status, :build_type_id, :start_date, :href, :web_url) do
21
93
  def success?
22
94
  status == :SUCCESS
23
95
  end
24
96
  end
97
+
98
+ class Authentication
99
+ def query_string_for params
100
+ pairs = []
101
+ params.each_pair { |k,v| pairs << "#{k}=#{v}" }
102
+ pairs.join("&")
103
+ end
104
+ end
25
105
 
26
- class HttpBasicAuthentication
106
+ class HttpBasicAuthentication < Authentication
27
107
  def initialize host, port, user, password
28
108
  @host, @port, @user, @password = host, port, user, password
29
109
  end
30
110
 
31
- def get path
32
- open(url(path), :http_basic_authentication => [@user, @password]).read
111
+ def get path, params = {}
112
+ open(url(path, params), :http_basic_authentication => [@user, @password]).read
33
113
  end
34
114
 
35
- def url path
36
- "http://#{@host}:#{@port}/httpAuth#{path}"
115
+ def url path, params = {}
116
+ auth_path = path.start_with?("/httpAuth/") ? path : "/httpAuth#{path}"
117
+ query_string = !params.empty? ? "?#{query_string_for(params)}" : ""
118
+ "http://#{@host}:#{@port}#{auth_path}#{query_string}"
37
119
  end
38
120
 
39
121
  def to_s
@@ -41,17 +123,18 @@ module TeamcityRestClient
41
123
  end
42
124
  end
43
125
 
44
- class Open
126
+ class Open < Authentication
45
127
  def initialize host, port
46
128
  @host, @port = host, port
47
129
  end
48
130
 
49
- def get path
50
- open(url(path)).read
131
+ def get path, params = {}
132
+ open(url(path, params)).read
51
133
  end
52
134
 
53
- def url path
54
- "http://#{@host}:#{@port}#{path}"
135
+ def url path, params = {}
136
+ query_string = !params.empty? ? "?#{query_string_for(params)}" : ""
137
+ "http://#{@host}:#{@port}#{path}#{query_string}"
55
138
  end
56
139
 
57
140
  def to_s
@@ -61,9 +144,14 @@ module TeamcityRestClient
61
144
  end
62
145
 
63
146
  class REXML::Element
64
- def att name
147
+ def av name
65
148
  attribute(name).value
66
149
  end
150
+
151
+ def av_or name, otherwise
152
+ att = attribute(name)
153
+ att ? att.value : otherwise
154
+ end
67
155
  end
68
156
 
69
157
  class Teamcity
@@ -88,24 +176,24 @@ class Teamcity
88
176
 
89
177
  def projects
90
178
  doc(get('/app/rest/projects')).elements.collect('//project') do |e|
91
- TeamcityRestClient::Project.new(self, e.att("name"), e.att("id"), url(e.att("href")))
179
+ TeamcityRestClient::Project.new(self, e.av("name"), e.av("id"), url(e.av("href")))
92
180
  end
93
181
  end
94
182
 
95
183
  def build_types
96
184
  doc(get('/app/rest/buildTypes')).elements.collect('//buildType') do |e|
97
- TeamcityRestClient::BuildType.new(e.att("id"), e.att("name"), url(e.att("href")), e.att('projectName'), e.att('projectId'), e.att('webUrl'))
185
+ TeamcityRestClient::BuildType.new(self, e.av("id"), e.av("name"), url(e.av("href")), e.av('projectName'), e.av('projectId'), e.av('webUrl'))
98
186
  end
99
187
  end
100
188
 
101
- def builds
102
- doc(get('/app/rest/builds').gsub(/&buildTypeId/,'&amp;buildTypeId')).elements.collect('//build') do |e|
103
- TeamcityRestClient::Build.new(e.att('id'), e.att('number'), e.att('status').to_sym, e.att('buildTypeId'), e.att('startDate'), url(e.att('href')), e.att('webUrl'))
189
+ def builds options = {}
190
+ doc(get('/app/rest/builds', options).gsub(/&buildTypeId/,'&amp;buildTypeId')).elements.collect('//build') do |e|
191
+ TeamcityRestClient::Build.new(self, e.av('id'), e.av('number'), e.av('status').to_sym, e.av('buildTypeId'), e.av_or('startDate', ''), url(e.av('href')), e.av('webUrl'))
104
192
  end
105
193
  end
106
194
 
107
195
  def to_s
108
- "Teamcity @ http://#{host}:#{port}"
196
+ "Teamcity @ #{url("/")}"
109
197
  end
110
198
 
111
199
  private
@@ -113,8 +201,8 @@ class Teamcity
113
201
  REXML::Document.new string
114
202
  end
115
203
 
116
- def get path
117
- result = @authentication.get(path)
204
+ def get path, params = {}
205
+ result = @authentication.get(path, params)
118
206
  raise "Teamcity returned html, perhaps you need to use authentication??" if result =~ /.*<html.*<\/html>.*/im
119
207
  result
120
208
  end
@@ -2,18 +2,132 @@ require_relative 'spec_helper'
2
2
 
3
3
  module TeamcityRestClient
4
4
 
5
+ describe "filters" do
6
+ before :each do
7
+ @build_type_a = stub('build type a', :id => "bt1", :name => "a" )
8
+ @build_type_b = stub('build type b', :id => "bt2", :name => "b" )
9
+ @build_type_c = stub('build type c', :id => "bt3", :name => "c" )
10
+ end
11
+
12
+ describe IncludeAllFilter do
13
+ before :each do
14
+ @filter = IncludeAllFilter.new
15
+ end
16
+
17
+ it "should retain everything and have no misses" do
18
+ @filter.retain?(@build_type_a).should be_true
19
+ @filter.retain?(@build_type_b).should be_true
20
+ @filter.retain?(@build_type_c).should be_true
21
+ @filter.misses.should be_empty
22
+ end
23
+ end
24
+
25
+ describe ExcludeNoneFilter do
26
+ before :each do
27
+ @filter = ExcludeNoneFilter.new
28
+ end
29
+
30
+ it "should retain everything have no misses" do
31
+ @filter.retain?(@build_type_a).should be_true
32
+ @filter.retain?(@build_type_b).should be_true
33
+ @filter.retain?(@build_type_c).should be_true
34
+ @filter.misses.should be_empty
35
+ end
36
+ end
37
+
38
+ describe IncludeFilter do
39
+ describe "including 1 thing" do
40
+ before :each do
41
+ @filter = IncludeFilter.new "a"
42
+ end
43
+
44
+ it "should retain when there is a match by name" do
45
+ @filter.retain?(@build_type_a).should be_true
46
+ end
47
+
48
+ it "should not retain when there is not a match" do
49
+ @filter.retain?(@build_type_b).should be_false
50
+ end
51
+ end
52
+
53
+ describe "include many things" do
54
+ before :each do
55
+ @filter = IncludeFilter.new ["a", "bt3", "non-existant"]
56
+ end
57
+
58
+ it "should retain when there is a match by name" do
59
+ @filter.retain?(@build_type_a).should be_true
60
+ end
61
+
62
+ it "should retain when there is a match by id" do
63
+ @filter.retain?(@build_type_c).should be_true
64
+ end
65
+
66
+ it "should not retain when there is not a match" do
67
+ @filter.retain?(@build_type_b).should be_false
68
+ end
69
+
70
+ it "should be able to report things that didnt match" do
71
+ @filter.retain?(@build_type_a)
72
+ @filter.misses.should == ["bt3", "non-existant"]
73
+ end
74
+ end
75
+ end
76
+
77
+ describe ExcludeFilter do
78
+ describe "excluding 1 thing" do
79
+ before :each do
80
+ @filter = ExcludeFilter.new "a"
81
+ end
82
+
83
+ it "should not retain when there is a match by name" do
84
+ @filter.retain?(@build_type_a).should be_false
85
+ end
86
+
87
+ it "should retain when there is not a match" do
88
+ @filter.retain?(@build_type_b).should be_true
89
+ end
90
+ end
91
+
92
+ describe "exclude many things" do
93
+ before :each do
94
+ @filter = ExcludeFilter.new ["a", "bt3", "non-existant"]
95
+ end
96
+
97
+ it "should not retain there is a match by name" do
98
+ @filter.retain?(@build_type_a).should be_false
99
+ end
100
+
101
+ it "should not retain there is a match by id" do
102
+ @filter.retain?(@build_type_c).should be_false
103
+ end
104
+
105
+ it "should retain when there is not a match" do
106
+ @filter.retain?(@build_type_b).should be_true
107
+ end
108
+
109
+ it "should be able to report things that didnt match" do
110
+ @filter.retain?(@build_type_a)
111
+ @filter.misses.should == ["bt3", "non-existant"]
112
+ end
113
+ end
114
+ end
115
+ end
116
+
5
117
  describe Project do
6
118
  before :each do
7
119
  @bt11 = stub('bt11', :id => "bt11", :name => "project1-build1", :project_id => "project1")
8
120
  @bt12 = stub('bt12', :id => "bt12", :name => "project1-build2", :project_id => "project1")
121
+ @bt13 = stub('bt13', :id => "bt13", :name => "project1-build3", :project_id => "project1")
9
122
  @bt21 = stub('bt21', :id => "bt21", :name => "project2-build1", :project_id => "project2")
10
123
 
11
124
  @bt11_1 = stub('bt11_1', :id => "1", :build_type_id => "bt11")
12
125
  @bt11_2 = stub('bt11_2', :id => "2", :build_type_id => "bt11")
13
126
  @bt12_33 = stub('bt12_33', :id => "33", :build_type_id => "bt12")
127
+ @bt13_44 = stub('bt13_44', :id => "44", :build_type_id => "bt13")
14
128
  @bt21_666 = stub('bt21_666', :id => "666", :build_type_id => "bt21")
15
129
 
16
- @tc = stub('teamcity', :build_types => [@bt11, @bt12, @bt21], :builds => [@bt11_1, @bt11_2, @bt12_33, @bt21_666])
130
+ @tc = stub('teamcity', :build_types => [@bt11, @bt12, @bt13, @bt21], :builds => [@bt11_1, @bt11_2, @bt12_33, @bt13_44, @bt21_666])
17
131
  @project1 = Project.new @tc, "Project 1", "project1", "http://www.example.com"
18
132
  end
19
133
 
@@ -23,17 +137,99 @@ module TeamcityRestClient
23
137
  end
24
138
 
25
139
  it "should have only those for project 1" do
26
- @build_types.should == [@bt11, @bt12]
140
+ @build_types.should == [@bt11, @bt12, @bt13]
27
141
  end
28
142
  end
29
-
143
+
144
+ describe "asking it for it's build types with filtering" do
145
+ describe "include" do
146
+ it "should match by single project name" do
147
+ @project1.build_types({ :include => "project1-build2" }).should == [@bt12]
148
+ end
149
+ it "should match by single project id" do
150
+ @project1.build_types({ :include => "bt11" }).should == [@bt11]
151
+ end
152
+ it "should match by multiple project id and name" do
153
+ @project1.build_types({ :include => ["bt11","project1-build2"] }).should == [@bt11, @bt12]
154
+ end
155
+ end
156
+
157
+ describe "exclude" do
158
+ it "should match by single project name" do
159
+ @project1.build_types({ :exclude => "project1-build2" }).should == [@bt11, @bt13]
160
+ end
161
+ it "should match by single project id" do
162
+ @project1.build_types({ :exclude => "bt11" }).should == [@bt12, @bt13]
163
+ end
164
+ it "should match by multiple project id and name" do
165
+ @project1.build_types({ :exclude => ["bt11","project1-build2"] }).should == [@bt13]
166
+ end
167
+ end
168
+
169
+ describe "include and exclude" do
170
+ it "should allow both, but its a bit pointless" do
171
+ @project1.build_types({ :include => ["bt11","project1-build2"], :exclude => ["bt11"]}).should == [@bt12]
172
+ end
173
+ end
174
+
175
+ describe "when an include fails to match as incorrectly typed" do
176
+ it "should raise exception" do
177
+ lambda { @project1.build_types({ :include => ["bt11", "nonsense1", "nonsense2"]}) }.should raise_error 'Failed to find a match for build type(s) ["nonsense1", "nonsense2"]'
178
+ end
179
+ end
180
+
181
+ describe "when an exclude fails to match as incorrectly typed" do
182
+ it "should raise exception" do
183
+ lambda { @project1.build_types({ :exclude => ["bt11", "nonsense1", "nonsense2"]}) }.should raise_error 'Failed to find a match for build type(s) ["nonsense1", "nonsense2"]'
184
+ end
185
+ end
186
+ end
187
+
30
188
  describe "asking it for it's builds" do
31
189
  before :each do
32
190
  @builds = @project1.builds
33
191
  end
34
192
 
35
193
  it "should have only builds for project 1" do
36
- @builds.should == [@bt11_1, @bt11_2, @bt12_33]
194
+ @builds.should == [@bt11_1, @bt11_2, @bt12_33, @bt13_44]
195
+ end
196
+ end
197
+
198
+ describe "latest_builds" do
199
+ before :each do
200
+ @bt11.stub(:latest_build).and_return(@bt11_2)
201
+ @bt12.stub(:latest_build).and_return(@bt12_33)
202
+ @bt13.stub(:latest_build).and_return(@bt13_44)
203
+ end
204
+
205
+ describe "for all builds in project" do
206
+ before :each do
207
+ @latest_builds = @project1.latest_builds
208
+ end
209
+
210
+ it "should get latest" do
211
+ @latest_builds.should == [@bt11_2, @bt12_33, @bt13_44]
212
+ end
213
+ end
214
+
215
+ describe "with an include filter specified" do
216
+ before :each do
217
+ @latest_builds = @project1.latest_builds :include => @bt11.id
218
+ end
219
+
220
+ it "should get latest only for that filter" do
221
+ @latest_builds.should == [@bt11_2]
222
+ end
223
+ end
224
+
225
+ describe "with an exclude filter specified" do
226
+ before :each do
227
+ @latest_builds = @project1.latest_builds :exclude => @bt11.id
228
+ end
229
+
230
+ it "should get latest only for that filter" do
231
+ @latest_builds.should == [@bt12_33, @bt13_44]
232
+ end
37
233
  end
38
234
  end
39
235
  end
@@ -49,12 +245,23 @@ module TeamcityRestClient
49
245
  it "should add /httpAuth to path" do
50
246
  @auth.url("/something").should == "http://auth.example.com:2233/httpAuth/something"
51
247
  end
248
+
249
+ it "should not add /httpAuth to path when already there" do
250
+ @auth.url("/httpAuth/something").should == "http://auth.example.com:2233/httpAuth/something"
251
+ end
252
+
253
+ it "should create query string from params" do
254
+ @auth.url("/overhere", {:id => "1", :name => 'betty'}).should == "http://auth.example.com:2233/httpAuth/overhere?id=1&name=betty"
255
+ end
52
256
  end
53
257
 
54
258
  describe "get" do
55
259
  it "should call open with http basic auth options" do
56
- @auth.should_receive(:open).with("http://auth.example.com:2233/httpAuth/somethingElse", :http_basic_authentication=>[@user, @password]).and_return(@io)
57
- @auth.get("/somethingElse")
260
+ path, options = "/something", {:id => 1}
261
+ url = "http://localhost:1324"
262
+ @auth.should_receive(:url).with(path, options).and_return url
263
+ @auth.should_receive(:open).with(url, :http_basic_authentication=>[@user, @password]).and_return(@io)
264
+ @auth.get(path, options)
58
265
  end
59
266
  end
60
267
  end
@@ -70,16 +277,40 @@ module TeamcityRestClient
70
277
  it "should create valid url" do
71
278
  @auth.url("/something").should == "http://auth.example.com:2233/something"
72
279
  end
280
+
281
+ it "should create query string from params" do
282
+ @auth.url("/overhere", {:id => "2", :name => 'boo'}).should == "http://auth.example.com:2233/overhere?id=2&name=boo"
283
+ end
73
284
  end
74
285
 
75
286
  describe "get" do
76
287
  it "should call open with no auth options" do
77
- @auth.should_receive(:open).with("http://auth.example.com:2233/somethingElse").and_return(@io)
78
- @auth.get("/somethingElse")
288
+ path, options = "/something", {:id => 1}
289
+ url = "http://localhost:1324"
290
+ @auth.should_receive(:url).with(path, options).and_return url
291
+ @auth.should_receive(:open).with(url).and_return(@io)
292
+ @auth.get(path, options)
293
+ end
294
+ end
295
+ end
296
+
297
+ describe BuildType do
298
+ before :each do
299
+ @tc = mock('teamcity')
300
+ @id, @name, @href, @project_name, @project_id, @web_url = "bt123", "build 123", "project 1", "project1", "http://www.example.com/something"
301
+ @build_type = BuildType.new @tc, @id, @name, @href, @project_name, @project_id, @web_url
302
+ end
303
+
304
+ describe "latest_build" do
305
+ before :each do
306
+ @build = mock('build')
307
+ @tc.should_receive(:builds).with(:buildType => "id:bt123", :count => 1).and_return [@build]
308
+ end
309
+ it "should ask teamcity" do
310
+ @build_type.latest_build.should == @build
79
311
  end
80
312
  end
81
313
  end
82
-
83
314
  end
84
315
 
85
316
  describe Teamcity do
@@ -97,7 +328,7 @@ describe Teamcity do
97
328
  @tc = Teamcity.new @host, @port, @user, @password
98
329
  end
99
330
 
100
- it "should create HttpBasicAuthetication" do
331
+ it "should create HttpBasicAuthentication" do
101
332
  @tc.authentication.should === @authentication
102
333
  end
103
334
  end
@@ -162,7 +393,7 @@ describe Teamcity do
162
393
  </html>
163
394
  HTML
164
395
 
165
- @authentication.should_receive(:get).with("/app/rest/buildTypes").and_return(fail_html)
396
+ @authentication.stub(:get).and_return(fail_html)
166
397
  @tc = Teamcity.new @host, @port
167
398
  end
168
399
 
@@ -173,8 +404,8 @@ HTML
173
404
 
174
405
  describe "parsing xml feeds" do
175
406
  before :each do
176
- @host, @port = "tc.example.com", 1234
177
- @authentication = TeamcityRestClient::Open.new @host, @port
407
+ @host, @port, @user, @password = "tc.example.com", 1234, "user", "password"
408
+ @authentication = TeamcityRestClient::HttpBasicAuthentication.new @host, @port, @user, @password
178
409
  end
179
410
 
180
411
  describe "projects" do
@@ -182,13 +413,13 @@ HTML
182
413
  xml = <<XML
183
414
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
184
415
  <projects>
185
- <project name="Amazon API client" id="project54" href="/app/rest/projects/id:project54"/>
186
- <project name="Apache Ant" id="project28" href="/app/rest/projects/id:project28"/>
416
+ <project name="Amazon API client" id="project54" href="/httpAuth/app/rest/projects/id:project54"/>
417
+ <project name="Apache Ant" id="project28" href="/httpAuth/app/rest/projects/id:project28"/>
187
418
  </projects>
188
419
  XML
189
- @authentication.should_receive(:get).with("/app/rest/projects").and_return(xml)
190
- TeamcityRestClient::Open.should_receive(:new).and_return(@authentication)
191
- @tc = Teamcity.new @host, @port
420
+ @authentication.should_receive(:get).with("/app/rest/projects", {}).and_return(xml)
421
+ TeamcityRestClient::HttpBasicAuthentication.should_receive(:new).and_return(@authentication)
422
+ @tc = Teamcity.new @host, @port, @user, @password
192
423
  @projects = @tc.projects
193
424
  end
194
425
 
@@ -200,14 +431,14 @@ XML
200
431
  amazon = @projects[0]
201
432
  amazon.name.should == "Amazon API client"
202
433
  amazon.id.should == "project54"
203
- amazon.href.should == "http://tc.example.com:1234/app/rest/projects/id:project54"
434
+ amazon.href.should == "http://tc.example.com:1234/httpAuth/app/rest/projects/id:project54"
204
435
  end
205
436
 
206
437
  it "should have ant project" do
207
438
  ant = @projects[1]
208
439
  ant.name.should == "Apache Ant"
209
440
  ant.id.should == "project28"
210
- ant.href.should == "http://tc.example.com:1234/app/rest/projects/id:project28"
441
+ ant.href.should == "http://tc.example.com:1234/httpAuth/app/rest/projects/id:project28"
211
442
  end
212
443
  end
213
444
 
@@ -216,15 +447,15 @@ XML
216
447
  xml = <<XML
217
448
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
218
449
  <buildTypes>
219
- <buildType id="bt297" name="Build" href="/app/rest/buildTypes/id:bt297"
450
+ <buildType id="bt297" name="Build" href="/httpAuth/app/rest/buildTypes/id:bt297"
220
451
  projectName="Amazon API client" projectId="project54" webUrl="http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt297"/>
221
- <buildType id="bt296" name="Download missing jar" href="/app/rest/buildTypes/id:bt296"
452
+ <buildType id="bt296" name="Download missing jar" href="/httpAuth/app/rest/buildTypes/id:bt296"
222
453
  projectName="Amazon API client" projectId="project54" webUrl="http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt296"/>
223
454
  </buildTypes>
224
455
  XML
225
- @authentication.should_receive(:get).with("/app/rest/buildTypes").and_return(xml)
226
- TeamcityRestClient::Open.should_receive(:new).and_return(@authentication)
227
- @tc = Teamcity.new @host, @port
456
+ @authentication.should_receive(:get).with("/app/rest/buildTypes", {}).and_return(xml)
457
+ TeamcityRestClient::HttpBasicAuthentication.should_receive(:new).and_return(@authentication)
458
+ @tc = Teamcity.new @host, @port, @user, @password
228
459
  @build_types = @tc.build_types
229
460
  end
230
461
 
@@ -236,7 +467,7 @@ XML
236
467
  bt297 = @build_types[0]
237
468
  bt297.id.should == "bt297"
238
469
  bt297.name.should == "Build"
239
- bt297.href.should == "http://tc.example.com:1234/app/rest/buildTypes/id:bt297"
470
+ bt297.href.should == "http://tc.example.com:1234/httpAuth/app/rest/buildTypes/id:bt297"
240
471
  bt297.project_name.should == "Amazon API client"
241
472
  bt297.project_id.should == "project54"
242
473
  bt297.web_url.should == "http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt297"
@@ -246,7 +477,7 @@ XML
246
477
  bt296 = @build_types[1]
247
478
  bt296.id.should == "bt296"
248
479
  bt296.name.should == "Download missing jar"
249
- bt296.href.should == "http://tc.example.com:1234/app/rest/buildTypes/id:bt296"
480
+ bt296.href.should == "http://tc.example.com:1234/httpAuth/app/rest/buildTypes/id:bt296"
250
481
  bt296.project_name.should == "Amazon API client"
251
482
  bt296.project_id.should == "project54"
252
483
  bt296.web_url.should == "http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt296"
@@ -254,49 +485,104 @@ XML
254
485
  end
255
486
 
256
487
  describe "builds" do
257
- before :each do
258
- xml = <<XML
488
+ describe "with options specified" do
489
+ before :each do
490
+ xml = <<XML
259
491
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
260
492
  <builds nextHref="/app/rest/builds?count=100&amp;start=100" count="100">
261
- <build id="56264" number="126" status="FAILURE" buildTypeId="bt212" startDate="20111021T123714+0400" href="/app/rest/builds/id:56264"
262
- webUrl="http://teamcity.jetbrains.com/viewLog.html?buildId=56264&buildTypeId=bt212"/>
263
- <build id="56262" number="568" status="SUCCESS" buildTypeId="bt213" startDate="20111021T120639+0400" href="/app/rest/builds/id:56262"
264
- webUrl="http://teamcity.jetbrains.com/viewLog.html?buildId=56262&buildTypeId=bt213"/>
493
+ <build id="56264" number="126" status="FAILURE" buildTypeId="bt212" href="/httpAuth/app/rest/builds/id:56264"
494
+ webUrl="http://teamcity.jetbrains.com/viewLog.html?buildId=56264&buildTypeId=bt212"/>
265
495
  </builds>
266
496
  XML
267
- @authentication.should_receive(:get).with("/app/rest/builds").and_return(xml)
268
- TeamcityRestClient::Open.should_receive(:new).and_return(@authentication)
269
- @tc = Teamcity.new @host, @port
270
- @builds = @tc.builds
271
- end
272
-
273
- it "should have 2" do
274
- @builds.length.should == 2
497
+ @options = {:buildType => "id:bt212", :count => 1}
498
+ @authentication.should_receive(:get).with("/app/rest/builds", @options).and_return(xml)
499
+ TeamcityRestClient::HttpBasicAuthentication.should_receive(:new).and_return(@authentication)
500
+ @tc = Teamcity.new @host, @port, @user, @password
501
+ @builds = @tc.builds @options
502
+ end
503
+
504
+ it "should have only 1 build as a result" do
505
+ @builds.length.should == 1
506
+ end
275
507
  end
276
508
 
277
- it "should have build 56264" do
278
- build = @builds[0]
279
- build.id.should == "56264"
280
- build.number.should == "126"
281
- build.status.should == :FAILURE
282
- build.success?.should == false
283
- build.build_type_id.should == "bt212"
284
- build.start_date.should == "20111021T123714+0400"
285
- build.href.should == "http://tc.example.com:1234/app/rest/builds/id:56264"
286
- build.web_url.should == "http://teamcity.jetbrains.com/viewLog.html?buildId=56264&buildTypeId=bt212"
509
+ describe "TeamCity Enterprise 5.1.2" do
510
+ before :each do
511
+ xml = <<XML
512
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
513
+ <builds nextHref="/app/rest/builds?count=100&amp;start=100" count="100">
514
+ <build id="56264" number="126" status="FAILURE" buildTypeId="bt212" href="/httpAuth/app/rest/builds/id:56264"
515
+ webUrl="http://teamcity.jetbrains.com/viewLog.html?buildId=56264&buildTypeId=bt212"/>
516
+ </builds>
517
+ XML
518
+ @authentication.should_receive(:get).with("/app/rest/builds", {}).and_return(xml)
519
+ TeamcityRestClient::HttpBasicAuthentication.should_receive(:new).and_return(@authentication)
520
+ @tc = Teamcity.new @host, @port, @user, @password
521
+ @builds = @tc.builds
522
+ end
523
+
524
+ it "should have 1" do
525
+ @builds.length.should == 1
526
+ end
527
+
528
+ it "should have build 56264" do
529
+ build = @builds[0]
530
+ build.id.should == "56264"
531
+ build.number.should == "126"
532
+ build.status.should == :FAILURE
533
+ build.success?.should == false
534
+ build.build_type_id.should == "bt212"
535
+ build.start_date.should == ""
536
+ build.href.should == "http://tc.example.com:1234/httpAuth/app/rest/builds/id:56264"
537
+ build.web_url.should == "http://teamcity.jetbrains.com/viewLog.html?buildId=56264&buildTypeId=bt212"
538
+ end
287
539
  end
288
540
 
289
- it "should have build 56262" do
290
- build = @builds[1]
291
- build.id.should == "56262"
292
- build.number.should == "568"
293
- build.status.should == :SUCCESS
294
- build.success?.should == true
295
- build.build_type_id.should == "bt213"
296
- build.start_date.should == "20111021T120639+0400"
297
- build.href.should == "http://tc.example.com:1234/app/rest/builds/id:56262"
298
- build.web_url.should == "http://teamcity.jetbrains.com/viewLog.html?buildId=56262&buildTypeId=bt213"
299
- end
541
+ describe "TeamCity Enterprise 6.5.4" do
542
+ before :each do
543
+ xml = <<XML
544
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
545
+ <builds nextHref="/app/rest/builds?count=100&amp;start=100" count="100">
546
+ <build id="56264" number="126" status="FAILURE" buildTypeId="bt212" startDate="20111021T123714+0400" href="/app/rest/builds/id:56264"
547
+ webUrl="http://teamcity.jetbrains.com/viewLog.html?buildId=56264&buildTypeId=bt212"/>
548
+ <build id="56262" number="568" status="SUCCESS" buildTypeId="bt213" startDate="20111021T120639+0400" href="/app/rest/builds/id:56262"
549
+ webUrl="http://teamcity.jetbrains.com/viewLog.html?buildId=56262&buildTypeId=bt213"/>
550
+ </builds>
551
+ XML
552
+ @authentication.should_receive(:get).with("/app/rest/builds", {}).and_return(xml)
553
+ TeamcityRestClient::HttpBasicAuthentication.should_receive(:new).and_return(@authentication)
554
+ @tc = Teamcity.new @host, @port, @user, @password
555
+ @builds = @tc.builds
556
+ end
557
+
558
+ it "should have 2" do
559
+ @builds.length.should == 2
560
+ end
561
+
562
+ it "should have build 56264" do
563
+ build = @builds[0]
564
+ build.id.should == "56264"
565
+ build.number.should == "126"
566
+ build.status.should == :FAILURE
567
+ build.success?.should == false
568
+ build.build_type_id.should == "bt212"
569
+ build.start_date.should == "20111021T123714+0400"
570
+ build.href.should == "http://tc.example.com:1234/httpAuth/app/rest/builds/id:56264"
571
+ build.web_url.should == "http://teamcity.jetbrains.com/viewLog.html?buildId=56264&buildTypeId=bt212"
572
+ end
573
+
574
+ it "should have build 56262" do
575
+ build = @builds[1]
576
+ build.id.should == "56262"
577
+ build.number.should == "568"
578
+ build.status.should == :SUCCESS
579
+ build.success?.should == true
580
+ build.build_type_id.should == "bt213"
581
+ build.start_date.should == "20111021T120639+0400"
582
+ build.href.should == "http://tc.example.com:1234/httpAuth/app/rest/builds/id:56262"
583
+ build.web_url.should == "http://teamcity.jetbrains.com/viewLog.html?buildId=56262&buildTypeId=bt213"
584
+ end
585
+ end
300
586
  end
301
587
  end
302
588
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "teamcity-rest-client"
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["simon"]
12
- s.date = "2011-10-24"
12
+ s.date = "2011-10-27"
13
13
  s.description = "Teamcity rest api client (readonly)"
14
14
  s.email = "simojenki@gmail.com"
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teamcity-rest-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-24 00:00:00.000000000Z
12
+ date: 2011-10-27 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2159395860 !ruby/object:Gem::Requirement
16
+ requirement: &2159724440 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.3.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2159395860
24
+ version_requirements: *2159724440
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bundler
27
- requirement: &2159395380 !ruby/object:Gem::Requirement
27
+ requirement: &2159723960 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.0.0
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2159395380
35
+ version_requirements: *2159723960
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: jeweler
38
- requirement: &2159394900 !ruby/object:Gem::Requirement
38
+ requirement: &2159723480 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.6.4
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2159394900
46
+ version_requirements: *2159723480
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rcov
49
- requirement: &2159394420 !ruby/object:Gem::Requirement
49
+ requirement: &2159723000 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2159394420
57
+ version_requirements: *2159723000
58
58
  description: Teamcity rest api client (readonly)
59
59
  email: simojenki@gmail.com
60
60
  executables: []
@@ -94,7 +94,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
94
94
  version: '0'
95
95
  segments:
96
96
  - 0
97
- hash: 2223201661142505741
97
+ hash: -677859045905772882
98
98
  required_rubygems_version: !ruby/object:Gem::Requirement
99
99
  none: false
100
100
  requirements: