jiralicious 0.0.6
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/.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
|