jiralicious 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.rdoc +21 -0
- data/Rakefile +16 -0
- data/jiralicious.gemspec +27 -0
- data/lib/jiralicious.rb +27 -0
- data/lib/jiralicious/configuration.rb +35 -0
- data/lib/jiralicious/errors.rb +17 -0
- data/lib/jiralicious/issue.rb +56 -0
- data/lib/jiralicious/parsers/field_parser.rb +43 -0
- data/lib/jiralicious/search.rb +26 -0
- data/lib/jiralicious/search_result.rb +17 -0
- data/lib/jiralicious/session.rb +100 -0
- data/lib/jiralicious/version.rb +3 -0
- data/spec/configuration_spec.rb +29 -0
- data/spec/field_parser_spec.rb +72 -0
- data/spec/fixtures/issue.json +167 -0
- data/spec/fixtures/search.json +11 -0
- data/spec/fixtures/transitions.json +65 -0
- data/spec/issue_spec.rb +96 -0
- data/spec/jiralicious_spec.rb +16 -0
- data/spec/search_result_spec.rb +42 -0
- data/spec/search_spec.rb +43 -0
- data/spec/session_spec.rb +278 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/configuration.rb +10 -0
- data/spec/support/http.rb +34 -0
- metadata +144 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
describe Jiralicious do
|
5
|
+
it "creates a session on load" do
|
6
|
+
Jiralicious.session.should_not be_nil
|
7
|
+
end
|
8
|
+
|
9
|
+
it "creates a rest path" do
|
10
|
+
Jiralicious.configure do |config|
|
11
|
+
config.uri = "http://localhost:8080"
|
12
|
+
config.api_version = "2.0"
|
13
|
+
end
|
14
|
+
Jiralicious.rest_path.should == 'http://localhost:8080/rest/api/2.0'
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
describe Jiralicious::SearchResult do
|
5
|
+
before :each do
|
6
|
+
FakeWeb.register_uri(:get,
|
7
|
+
"#{Jiralicious.rest_path}/issue/HSP-1",
|
8
|
+
:status => "200",
|
9
|
+
:body => issue_json)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:search_data) {
|
13
|
+
{
|
14
|
+
"startAt" => 0,
|
15
|
+
"maxResults" => 50,
|
16
|
+
"total" => 1,
|
17
|
+
"issues" => [{
|
18
|
+
"self" => "http://www.example.com/jira/rest/api/2.0/jira/rest/api/2.0/issue/HSP-1",
|
19
|
+
"key" => "HSP-1"
|
20
|
+
}]
|
21
|
+
}
|
22
|
+
}
|
23
|
+
let(:search_result) { Jiralicious::SearchResult.new(search_data) }
|
24
|
+
|
25
|
+
it "assigns an array to back the search results" do
|
26
|
+
search_result.instance_variable_get('@issues').
|
27
|
+
should == [ {"self" => "http://www.example.com/jira/rest/api/2.0/jira/rest/api/2.0/issue/HSP-1",
|
28
|
+
"key" => "HSP-1"} ]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "knows it's offset" do
|
32
|
+
search_result.offset.should == 0
|
33
|
+
end
|
34
|
+
|
35
|
+
it "knows how many results are returned from the web service" do
|
36
|
+
search_result.num_results.should == 1
|
37
|
+
end
|
38
|
+
|
39
|
+
it "fetches issues" do
|
40
|
+
search_result.issues.first.should be_instance_of(Jiralicious::Issue)
|
41
|
+
end
|
42
|
+
end
|
data/spec/search_spec.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
describe Jiralicious, "search", do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
Jiralicious.configure do |config|
|
8
|
+
config.username = "jstewart"
|
9
|
+
config.password = "topsecret"
|
10
|
+
config.uri = "http://localhost"
|
11
|
+
config.api_version = "latest"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when successful" do
|
16
|
+
before :each do
|
17
|
+
FakeWeb.register_uri(:post,
|
18
|
+
"#{Jiralicious.rest_path}/search",
|
19
|
+
:status => "200",
|
20
|
+
:body => search_json)
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
it "instantiates a search result" do
|
25
|
+
results = Jiralicious.search("key = HSP-1")
|
26
|
+
results.should be_instance_of(Jiralicious::SearchResult)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "When there's a problem with the query" do
|
31
|
+
before :each do
|
32
|
+
FakeWeb.register_uri(:post,
|
33
|
+
"#{Jiralicious.rest_path}/search",
|
34
|
+
:status => "400")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises an exception" do
|
38
|
+
lambda {
|
39
|
+
results = Jiralicious.search("key = HSP-1")
|
40
|
+
}.should raise_error(Jiralicious::JqlError)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,278 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
describe Jiralicious::Session, "when logging in" do
|
5
|
+
context "successfully" do
|
6
|
+
before :each do
|
7
|
+
register_login
|
8
|
+
@session = Jiralicious::Session.new
|
9
|
+
@session.login
|
10
|
+
end
|
11
|
+
|
12
|
+
it "is alive" do
|
13
|
+
@session.should be_alive
|
14
|
+
end
|
15
|
+
|
16
|
+
it "populates the session and login info" do
|
17
|
+
@session.session.should == {
|
18
|
+
"name" => "JSESSIONID",
|
19
|
+
"value" => "12345678901234567890"
|
20
|
+
}
|
21
|
+
@session.login_info.should == {
|
22
|
+
"failedLoginCount" => 10,
|
23
|
+
"loginCount" => 127,
|
24
|
+
"lastFailedLoginTime" => "2011-07-25T06:31:07.556-0500",
|
25
|
+
"previousLoginTime" => "2011-07-25T06:31:07.556-0500"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with an invalid login" do
|
31
|
+
before :each do
|
32
|
+
FakeWeb.register_uri(:post,
|
33
|
+
Jiralicious.uri + '/rest/auth/latest/session',
|
34
|
+
:status => ["401", "Not Authorized"])
|
35
|
+
@session = Jiralicious::Session.new
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raises the correct exception" do
|
39
|
+
lambda { @session.login }.
|
40
|
+
should raise_error(Jiralicious::InvalidLogin)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "is not alive" do
|
44
|
+
begin; @session.login; rescue Jiralicious::InvalidLogin; end
|
45
|
+
@session.should_not be_alive
|
46
|
+
end
|
47
|
+
|
48
|
+
it "clears the session and login info" do
|
49
|
+
@session.login_info = "GARBAGE"
|
50
|
+
@session.session = "GARBAGE"
|
51
|
+
begin; @session.login; rescue Jiralicious::InvalidLogin; end
|
52
|
+
@session.login_info.should be_nil
|
53
|
+
@session.session.should be_nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when CAPTCHA is required" do
|
58
|
+
before :each do
|
59
|
+
FakeWeb.register_uri(:post,
|
60
|
+
Jiralicious.uri + '/rest/auth/latest/session',
|
61
|
+
:status => ["403", "Captcha Required"])
|
62
|
+
@session = Jiralicious::Session.new
|
63
|
+
end
|
64
|
+
|
65
|
+
it "raises an exception" do
|
66
|
+
lambda { @session.login }.
|
67
|
+
should raise_error(Jiralicious::CaptchaRequired)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "clears the session and login info" do
|
71
|
+
@session.login_info = "GARBAGE"
|
72
|
+
@session.session = "GARBAGE"
|
73
|
+
begin; @session.login; rescue Jiralicious::CaptchaRequired; end
|
74
|
+
@session.login_info.should be_nil
|
75
|
+
@session.session.should be_nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "with any other HTTP error" do
|
80
|
+
before :each do
|
81
|
+
FakeWeb.register_uri(:post,
|
82
|
+
Jiralicious.uri + '/rest/auth/latest/session',
|
83
|
+
:status => ["500", "Internal Server Error"])
|
84
|
+
@session = Jiralicious::Session.new
|
85
|
+
end
|
86
|
+
|
87
|
+
it "raises an exception" do
|
88
|
+
lambda { @session.login }.
|
89
|
+
should raise_error(Jiralicious::JiraError)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "clears the session and login info" do
|
93
|
+
@session.login_info = "GARBAGE"
|
94
|
+
@session.session = "GARBAGE"
|
95
|
+
begin; @session.login; rescue Jiralicious::JiraError; end
|
96
|
+
@session.login_info.should be_nil
|
97
|
+
@session.session.should be_nil
|
98
|
+
end
|
99
|
+
|
100
|
+
it "gives the Net::HTTP reason for failure" do
|
101
|
+
begin
|
102
|
+
@session.login
|
103
|
+
rescue Jiralicious::JiraError => e
|
104
|
+
e.message.should == "Internal Server Error"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe Jiralicious::Session, "when logging out" do
|
111
|
+
before :each do
|
112
|
+
register_login
|
113
|
+
@session = Jiralicious::Session.new
|
114
|
+
@session.login
|
115
|
+
@session.should be_alive
|
116
|
+
FakeWeb.register_uri(:delete,
|
117
|
+
Jiralicious.uri + '/rest/auth/latest/session',
|
118
|
+
:status => "204")
|
119
|
+
@session.logout
|
120
|
+
end
|
121
|
+
|
122
|
+
it "is not alive" do
|
123
|
+
@session.should_not be_alive
|
124
|
+
end
|
125
|
+
|
126
|
+
it "clears the session and login info" do
|
127
|
+
@session.session.should be_nil
|
128
|
+
@session.login_info.should be_nil
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when not logged in" do
|
132
|
+
before :each do
|
133
|
+
@session = Jiralicious::Session.new
|
134
|
+
FakeWeb.register_uri(:delete,
|
135
|
+
Jiralicious.uri + '/rest/auth/latest/session',
|
136
|
+
:status => ["401", "Not Authorized"])
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should raise the correct error" do
|
140
|
+
lambda { @session.logout }.should raise_error(Jiralicious::NotLoggedIn)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "with any other HTTP error" do
|
145
|
+
before :each do
|
146
|
+
@session = Jiralicious::Session.new
|
147
|
+
FakeWeb.register_uri(:delete,
|
148
|
+
Jiralicious.uri + '/rest/auth/latest/session',
|
149
|
+
:status => ["500", "Internal Server Error"])
|
150
|
+
end
|
151
|
+
|
152
|
+
it "raises an exception" do
|
153
|
+
lambda { @session.logout }.
|
154
|
+
should raise_error(Jiralicious::JiraError)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "gives the Net::HTTP reason for failure" do
|
158
|
+
begin
|
159
|
+
@session.logout
|
160
|
+
rescue Jiralicious::JiraError => e
|
161
|
+
e.message.should == "Internal Server Error"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe Jiralicious::Session, "performing a request" do
|
168
|
+
include ConfigurationHelper
|
169
|
+
include LoginHelper
|
170
|
+
|
171
|
+
before :each do
|
172
|
+
FakeWeb.register_uri(:get,
|
173
|
+
Jiralicious.uri + '/fake/uri',
|
174
|
+
:status => "200")
|
175
|
+
end
|
176
|
+
|
177
|
+
context "when login is required" do
|
178
|
+
before :each do
|
179
|
+
@session = Jiralicious::Session.new
|
180
|
+
@session.stub!(:require_login?).and_return(true)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "attempts to log in beforehand" do
|
184
|
+
@session.should_receive(:login)
|
185
|
+
@session.perform_request do
|
186
|
+
Jiralicious::Session.get('/fake/uri')
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "when login is not required" do
|
192
|
+
before :each do
|
193
|
+
@session = Jiralicious::Session.new
|
194
|
+
@session.stub!(:require_login?).and_return(false)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "doesn't try to log in before making the request" do
|
198
|
+
@session.should_receive(:login).never
|
199
|
+
@session.perform_request do
|
200
|
+
Jiralicious::Session.get('/fake/uri')
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe "performing a request with a successful response" do
|
207
|
+
before :each do
|
208
|
+
FakeWeb.register_uri(:get,
|
209
|
+
Jiralicious.uri + '/ok',
|
210
|
+
:status => "200")
|
211
|
+
FakeWeb.register_uri(:post,
|
212
|
+
Jiralicious.uri + '/created',
|
213
|
+
:status => "201")
|
214
|
+
FakeWeb.register_uri(:delete,
|
215
|
+
Jiralicious.uri + '/nocontent',
|
216
|
+
:status => "204")
|
217
|
+
|
218
|
+
register_login
|
219
|
+
end
|
220
|
+
|
221
|
+
let(:session) { Jiralicious::Session.new }
|
222
|
+
|
223
|
+
it "returns the response on ok" do
|
224
|
+
r = session.perform_request { Jiralicious::Session.get('/ok') }
|
225
|
+
r.class.should == HTTParty::Response
|
226
|
+
end
|
227
|
+
|
228
|
+
it "returns the response on created" do
|
229
|
+
r = session.perform_request { Jiralicious::Session.post('/created') }
|
230
|
+
r.class.should == HTTParty::Response
|
231
|
+
end
|
232
|
+
|
233
|
+
it "returns the response on no content" do
|
234
|
+
r = session.perform_request { Jiralicious::Session.delete('/nocontent') }
|
235
|
+
r.class.should == HTTParty::Response
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe "performing a request with an unsuccessful response" do
|
240
|
+
before :each do
|
241
|
+
FakeWeb.register_uri(:get,
|
242
|
+
Jiralicious.uri + '/cookie_expired',
|
243
|
+
[
|
244
|
+
{:status => "401", :body => "Cookie Expired"},
|
245
|
+
{:status => "200"}
|
246
|
+
])
|
247
|
+
FakeWeb.register_uri(:get,
|
248
|
+
Jiralicious.uri + '/captcha_needed',
|
249
|
+
:status => "401",
|
250
|
+
"X-Seraph-LoginReason" => "AUTHENTICATION_DENIED")
|
251
|
+
register_login
|
252
|
+
end
|
253
|
+
|
254
|
+
let(:session) { Jiralicious::Session.new }
|
255
|
+
|
256
|
+
it "retries the login when the cookie expires" do
|
257
|
+
session.should_receive(:login).twice
|
258
|
+
session.perform_request { Jiralicious::Session.get('/cookie_expired') }
|
259
|
+
end
|
260
|
+
|
261
|
+
it "raises an exception when retried and failed" do
|
262
|
+
FakeWeb.register_uri(:get,
|
263
|
+
Jiralicious.uri + '/cookie_expired',
|
264
|
+
[
|
265
|
+
{:status => "401", :body => "Cookie Expired"},
|
266
|
+
{:status => "401", :body => "Cookie Expired"}
|
267
|
+
])
|
268
|
+
lambda {
|
269
|
+
session.perform_request { Jiralicious::Session.get('/cookie_expired') }
|
270
|
+
}.should raise_error(Jiralicious::CookieExpired)
|
271
|
+
end
|
272
|
+
|
273
|
+
it "raises an exception when the captcha is required" do
|
274
|
+
lambda {
|
275
|
+
session.perform_request { Jiralicious::Session.get('/captcha_needed') }
|
276
|
+
}.should raise_error(Jiralicious::CaptchaRequired)
|
277
|
+
end
|
278
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'fakeweb'
|
5
|
+
require 'jiralicious'
|
6
|
+
|
7
|
+
FakeWeb.allow_net_connect = false
|
8
|
+
|
9
|
+
# Requires supporting files with custom matchers and macros, etc,
|
10
|
+
# in ./support/ and its subdirectories.
|
11
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.include ConfigurationHelper
|
15
|
+
config.include LoginHelper
|
16
|
+
config.include JsonResponse
|
17
|
+
|
18
|
+
config.before(:each) do
|
19
|
+
configure_jiralicious
|
20
|
+
register_login
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module LoginHelper
|
2
|
+
def register_login
|
3
|
+
response = %Q|
|
4
|
+
{
|
5
|
+
"session": {
|
6
|
+
"name": "JSESSIONID",
|
7
|
+
"value": "12345678901234567890"
|
8
|
+
},
|
9
|
+
"loginInfo": {
|
10
|
+
"failedLoginCount": 10,
|
11
|
+
"loginCount": 127,
|
12
|
+
"lastFailedLoginTime": "2011-07-25T06:31:07.556-0500",
|
13
|
+
"previousLoginTime": "2011-07-25T06:31:07.556-0500"
|
14
|
+
}
|
15
|
+
}|
|
16
|
+
FakeWeb.register_uri(:post,
|
17
|
+
Jiralicious.uri + '/rest/auth/latest/session',
|
18
|
+
:body => response)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module JsonResponse
|
23
|
+
def issue_json
|
24
|
+
File.new(File.expand_path('issue.json', File.dirname(__FILE__) + '/../fixtures')).read
|
25
|
+
end
|
26
|
+
|
27
|
+
def search_json
|
28
|
+
File.new(File.expand_path('search.json', File.dirname(__FILE__) + '/../fixtures')).read
|
29
|
+
end
|
30
|
+
|
31
|
+
def transitions_json
|
32
|
+
File.new(File.expand_path('transitions.json', File.dirname(__FILE__) + '/../fixtures')).read
|
33
|
+
end
|
34
|
+
end
|