teamcity-rest-client 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -23,6 +23,41 @@ module TeamcityRestClient
23
23
  end
24
24
  end
25
25
 
26
+ class HttpBasicAuthentication
27
+ def initialize host, port, user, password
28
+ @host, @port, @user, @password = host, port, user, password
29
+ end
30
+
31
+ def get path
32
+ open(url(path), :http_basic_authentication => [@user, @password]).read
33
+ end
34
+
35
+ def url path
36
+ "http://#{@host}:#{@port}/httpAuth#{path}"
37
+ end
38
+
39
+ def to_s
40
+ "HttpBasicAuthentication #{@user}:#{@password}"
41
+ end
42
+ end
43
+
44
+ class Open
45
+ def initialize host, port
46
+ @host, @port = host, port
47
+ end
48
+
49
+ def get path
50
+ open(url(path)).read
51
+ end
52
+
53
+ def url path
54
+ "http://#{@host}:#{@port}#{path}"
55
+ end
56
+
57
+ def to_s
58
+ "No Authentication"
59
+ end
60
+ end
26
61
  end
27
62
 
28
63
  class REXML::Element
@@ -33,10 +68,15 @@ end
33
68
 
34
69
  class Teamcity
35
70
 
36
- attr_reader :host, :port, :user, :password
71
+ attr_reader :host, :port, :authentication
37
72
 
38
73
  def initialize host, port, user = nil, password = nil
39
- @host, @port, @user, @password = host, port, user, password
74
+ @host, @port = host, port
75
+ if user != nil && password != nil
76
+ @authentication = TeamcityRestClient::HttpBasicAuthentication.new host, port, user, password
77
+ else
78
+ @authentication = TeamcityRestClient::Open.new host, port
79
+ end
40
80
  end
41
81
 
42
82
  def project spec
@@ -47,37 +87,39 @@ class Teamcity
47
87
  end
48
88
 
49
89
  def projects
50
- doc(get(url('/app/rest/projects'))).elements.collect('//project') do |e|
90
+ doc(get('/app/rest/projects')).elements.collect('//project') do |e|
51
91
  TeamcityRestClient::Project.new(self, e.att("name"), e.att("id"), url(e.att("href")))
52
92
  end
53
93
  end
54
94
 
55
95
  def build_types
56
- doc(get(url('/app/rest/buildTypes'))).elements.collect('//buildType') do |e|
96
+ doc(get('/app/rest/buildTypes')).elements.collect('//buildType') do |e|
57
97
  TeamcityRestClient::BuildType.new(e.att("id"), e.att("name"), url(e.att("href")), e.att('projectName'), e.att('projectId'), e.att('webUrl'))
58
98
  end
59
99
  end
60
100
 
61
101
  def builds
62
- doc(get(url('/app/rest/builds')).gsub(/&buildTypeId/,'&buildTypeId')).elements.collect('//build') do |e|
102
+ doc(get('/app/rest/builds').gsub(/&buildTypeId/,'&buildTypeId')).elements.collect('//build') do |e|
63
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'))
64
104
  end
65
105
  end
66
-
67
- def url path
68
- if user != nil && password != nil
69
- "http://#{user}:#{password}@#{host}:#{port}#{path}"
70
- else
71
- "http://#{host}:#{port}#{path}"
72
- end
73
- end
74
106
 
107
+ def to_s
108
+ "Teamcity @ http://#{host}:#{port}"
109
+ end
110
+
75
111
  private
76
112
  def doc string
77
113
  REXML::Document.new string
78
114
  end
115
+
116
+ def get path
117
+ result = @authentication.get(path)
118
+ raise "Teamcity returned html, perhaps you need to use authentication??" if result =~ /.*<html.*<\/html>.*/im
119
+ result
120
+ end
79
121
 
80
- def get url
81
- open(url).read
122
+ def url path
123
+ @authentication.url(path)
82
124
  end
83
- end
125
+ end
data/spec/spec_helper.rb CHANGED
@@ -10,3 +10,7 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
10
10
  RSpec.configure do |config|
11
11
 
12
12
  end
13
+
14
+ def sample_xml name
15
+ File.open("#{File.dirname(__FILE__)}/samples/#{name}.xml").read
16
+ end
@@ -1,51 +1,117 @@
1
1
  require_relative 'spec_helper'
2
2
 
3
- describe TeamcityRestClient::Project do
4
- before :each do
5
- @bt11 = stub('bt11', :id => "bt11", :name => "project1-build1", :project_id => "project1")
6
- @bt12 = stub('bt12', :id => "bt12", :name => "project1-build2", :project_id => "project1")
7
- @bt21 = stub('bt21', :id => "bt21", :name => "project2-build1", :project_id => "project2")
3
+ module TeamcityRestClient
4
+
5
+ describe Project do
6
+ before :each do
7
+ @bt11 = stub('bt11', :id => "bt11", :name => "project1-build1", :project_id => "project1")
8
+ @bt12 = stub('bt12', :id => "bt12", :name => "project1-build2", :project_id => "project1")
9
+ @bt21 = stub('bt21', :id => "bt21", :name => "project2-build1", :project_id => "project2")
8
10
 
9
- @bt11_1 = stub('bt11_1', :id => "1", :build_type_id => "bt11")
10
- @bt11_2 = stub('bt11_2', :id => "2", :build_type_id => "bt11")
11
- @bt12_33 = stub('bt12_33', :id => "33", :build_type_id => "bt12")
12
- @bt21_666 = stub('bt21_666', :id => "666", :build_type_id => "bt21")
11
+ @bt11_1 = stub('bt11_1', :id => "1", :build_type_id => "bt11")
12
+ @bt11_2 = stub('bt11_2', :id => "2", :build_type_id => "bt11")
13
+ @bt12_33 = stub('bt12_33', :id => "33", :build_type_id => "bt12")
14
+ @bt21_666 = stub('bt21_666', :id => "666", :build_type_id => "bt21")
13
15
 
14
- @tc = stub('teamcity', :build_types => [@bt11, @bt12, @bt21], :builds => [@bt11_1, @bt11_2, @bt12_33, @bt21_666])
15
- @project1 = TeamcityRestClient::Project.new @tc, "Project 1", "project1", "http://www.example.com"
16
- end
16
+ @tc = stub('teamcity', :build_types => [@bt11, @bt12, @bt21], :builds => [@bt11_1, @bt11_2, @bt12_33, @bt21_666])
17
+ @project1 = Project.new @tc, "Project 1", "project1", "http://www.example.com"
18
+ end
17
19
 
18
- describe "asking it for it's build types" do
20
+ describe "asking it for it's build types" do
21
+ before :each do
22
+ @build_types = @project1.build_types
23
+ end
24
+
25
+ it "should have only those for project 1" do
26
+ @build_types.should == [@bt11, @bt12]
27
+ end
28
+ end
29
+
30
+ describe "asking it for it's builds" do
31
+ before :each do
32
+ @builds = @project1.builds
33
+ end
34
+
35
+ it "should have only builds for project 1" do
36
+ @builds.should == [@bt11_1, @bt11_2, @bt12_33]
37
+ end
38
+ end
39
+ end
40
+
41
+ describe HttpBasicAuthentication do
19
42
  before :each do
20
- @build_types = @project1.build_types
43
+ @host, @port, @user, @password = "auth.example.com", 2233, "john", "wayne"
44
+ @auth = HttpBasicAuthentication.new @host, @port, @user, @password
45
+ @io = stub(:read => "<xml/>")
21
46
  end
22
47
 
23
- it "should have only those for project 1" do
24
- @build_types.should == [@bt11, @bt12]
48
+ describe "url" do
49
+ it "should add /httpAuth to path" do
50
+ @auth.url("/something").should == "http://auth.example.com:2233/httpAuth/something"
51
+ end
52
+ end
53
+
54
+ describe "get" do
55
+ 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")
58
+ end
25
59
  end
26
60
  end
27
61
 
28
- describe "asking it for it's builds" do
62
+ describe Open do
29
63
  before :each do
30
- @builds = @project1.builds
64
+ @host, @port = "auth.example.com", 2233
65
+ @auth = Open.new @host, @port
66
+ @io = stub(:read => "<xml/>")
31
67
  end
32
68
 
33
- it "should have only builds for project 1" do
34
- @builds.should == [@bt11_1, @bt11_2, @bt12_33]
69
+ describe "url" do
70
+ it "should create valid url" do
71
+ @auth.url("/something").should == "http://auth.example.com:2233/something"
72
+ end
73
+ end
74
+
75
+ describe "get" do
76
+ 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")
79
+ end
35
80
  end
36
81
  end
82
+
37
83
  end
38
84
 
39
85
  describe Teamcity do
40
- describe "using basic http authentication" do
86
+ before :all do
87
+ @sample_projects_xml = sample_xml "projects"
88
+ @sample_builds_xml = sample_xml "builds"
89
+ @sample_build_types_xml = sample_xml "buildTypes"
90
+ end
91
+
92
+ describe "specifying username and password" do
41
93
  before :each do
42
- @user = "bob"
43
- @password = "marley"
44
- @tc = Teamcity.new "authtc.example.com", 9999, @user, @password
94
+ @host, @port, @user, @password = "authtc.example.com", 8877, "bob", "marley"
95
+ @authentication = mock('authentication')
96
+ TeamcityRestClient::HttpBasicAuthentication.should_receive(:new).with(@host, @port, @user, @password).and_return(@authentication)
97
+ @tc = Teamcity.new @host, @port, @user, @password
45
98
  end
46
99
 
47
- it "should create a valid url to /something" do
48
- @tc.url("/something").should == "http://bob:marley@authtc.example.com:9999/something"
100
+ it "should create HttpBasicAuthetication" do
101
+ @tc.authentication.should === @authentication
102
+ end
103
+ end
104
+
105
+ describe "specifying no username and password" do
106
+ before :each do
107
+ @host, @port = "authtc.example.com", 8877
108
+ @authentication = mock('authentication')
109
+ TeamcityRestClient::Open.should_receive(:new).with(@host, @port).and_return(@authentication)
110
+ @tc = Teamcity.new @host, @port
111
+ end
112
+
113
+ it "should create HttpBasicAuthetication" do
114
+ @tc.authentication.should === @authentication
49
115
  end
50
116
  end
51
117
 
@@ -83,9 +149,32 @@ describe Teamcity do
83
149
  end
84
150
  end
85
151
 
152
+ describe "when authentication fails" do
153
+ before :each do
154
+ @host, @port = "fail.example.com", 1234
155
+ @authentication = TeamcityRestClient::Open.new @host, @port
156
+ TeamcityRestClient::Open.should_receive(:new).and_return(@authentication)
157
+ fail_html = <<HTML
158
+
159
+ <!DOCTYPE html>
160
+ <html id="htmlId">
161
+ something
162
+ </html>
163
+ HTML
164
+
165
+ @authentication.should_receive(:get).with("/app/rest/buildTypes").and_return(fail_html)
166
+ @tc = Teamcity.new @host, @port
167
+ end
168
+
169
+ it "should raise an error" do
170
+ lambda { @tc.build_types }.should raise_error "Teamcity returned html, perhaps you need to use authentication??"
171
+ end
172
+ end
173
+
86
174
  describe "parsing xml feeds" do
87
175
  before :each do
88
- @tc = Teamcity.new "tc.example.com", 1234
176
+ @host, @port = "tc.example.com", 1234
177
+ @authentication = TeamcityRestClient::Open.new @host, @port
89
178
  end
90
179
 
91
180
  describe "projects" do
@@ -97,7 +186,9 @@ describe Teamcity do
97
186
  <project name="Apache Ant" id="project28" href="/app/rest/projects/id:project28"/>
98
187
  </projects>
99
188
  XML
100
- @tc.should_receive(:open).with("http://tc.example.com:1234/app/rest/projects").and_return(stub(:read => 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
101
192
  @projects = @tc.projects
102
193
  end
103
194
 
@@ -131,7 +222,9 @@ XML
131
222
  projectName="Amazon API client" projectId="project54" webUrl="http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt296"/>
132
223
  </buildTypes>
133
224
  XML
134
- @tc.should_receive(:open).with("http://tc.example.com:1234/app/rest/buildTypes").and_return(stub(:read => 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
135
228
  @build_types = @tc.build_types
136
229
  end
137
230
 
@@ -171,7 +264,9 @@ XML
171
264
  webUrl="http://teamcity.jetbrains.com/viewLog.html?buildId=56262&buildTypeId=bt213"/>
172
265
  </builds>
173
266
  XML
174
- @tc.should_receive(:open).with("http://tc.example.com:1234/app/rest/builds").and_return(stub(:read => 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
175
270
  @builds = @tc.builds
176
271
  end
177
272
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "teamcity-rest-client"
8
- s.version = "0.1.0"
8
+ s.version = "0.1.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["simon"]
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.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-10-24 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2158820600 !ruby/object:Gem::Requirement
16
+ requirement: &2159395860 !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: *2158820600
24
+ version_requirements: *2159395860
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bundler
27
- requirement: &2158820120 !ruby/object:Gem::Requirement
27
+ requirement: &2159395380 !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: *2158820120
35
+ version_requirements: *2159395380
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: jeweler
38
- requirement: &2158819640 !ruby/object:Gem::Requirement
38
+ requirement: &2159394900 !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: *2158819640
46
+ version_requirements: *2159394900
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rcov
49
- requirement: &2158819160 !ruby/object:Gem::Requirement
49
+ requirement: &2159394420 !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: *2158819160
57
+ version_requirements: *2159394420
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: 667469090941014696
97
+ hash: 2223201661142505741
98
98
  required_rubygems_version: !ruby/object:Gem::Requirement
99
99
  none: false
100
100
  requirements: