jiralicious 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/README.md +32 -4
- data/jiralicious.gemspec +7 -5
- data/lib/jiralicious.rb +10 -3
- data/lib/jiralicious/base.rb +114 -0
- data/lib/jiralicious/configuration.rb +13 -2
- data/lib/jiralicious/cookie_session.rb +5 -5
- data/lib/jiralicious/custom_field_option.rb +27 -0
- data/lib/jiralicious/field.rb +39 -0
- data/lib/jiralicious/issue.rb +111 -26
- data/lib/jiralicious/issue/comment.rb +62 -0
- data/lib/jiralicious/issue/fields.rb +93 -0
- data/lib/jiralicious/issue/transitions.rb +92 -0
- data/lib/jiralicious/issue/watchers.rb +47 -0
- data/lib/jiralicious/parsers/field_parser.rb +2 -2
- data/lib/jiralicious/project.rb +44 -0
- data/lib/jiralicious/search.rb +4 -1
- data/lib/jiralicious/search_result.rb +4 -0
- data/lib/jiralicious/version.rb +1 -1
- data/spec/basic_session_spec.rb +4 -4
- data/spec/comment_spec.rb +64 -0
- data/spec/configuration_spec.rb +9 -0
- data/spec/fixtures/comment.json +30 -0
- data/spec/fixtures/comment_single.json +29 -0
- data/spec/fixtures/issue.json +89 -93
- data/spec/fixtures/issue_2.json +30 -0
- data/spec/fixtures/issue_create.json +5 -0
- data/spec/fixtures/issue_createmeta.json +34 -0
- data/spec/fixtures/issue_editmeta.json +22 -0
- data/spec/fixtures/issue_update.json +164 -0
- data/spec/fixtures/jira.yml +7 -0
- data/spec/fixtures/project.json +87 -0
- data/spec/fixtures/project_issue_list.json +20 -0
- data/spec/fixtures/projects.json +22 -0
- data/spec/fixtures/search.json +9 -9
- data/spec/fixtures/test.json +24 -0
- data/spec/fixtures/transitions.json +61 -61
- data/spec/fixtures/watchers.json +17 -0
- data/spec/issue_spec.rb +255 -21
- data/spec/project_spec.rb +55 -0
- data/spec/search_result_spec.rb +20 -8
- data/spec/search_spec.rb +6 -6
- data/spec/support/http.rb +55 -2
- data/spec/watchers_spec.rb +43 -0
- metadata +154 -100
- data/.rvmrc +0 -1
- data/spec/cookie_session_spec.rb +0 -268
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Jiralicious
|
3
|
+
class Issue
|
4
|
+
class Comment < Jiralicious::Base
|
5
|
+
|
6
|
+
attr_accessor :jira_key
|
7
|
+
|
8
|
+
def initialize(decoded_json = nil, default = nil, &blk)
|
9
|
+
if (decoded_json != nil)
|
10
|
+
properties_from_hash(decoded_json)
|
11
|
+
super(decoded_json)
|
12
|
+
parse!(decoded_json)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def find_by_key(key, options = {})
|
18
|
+
response = fetch({:parent => parent_name, :parent_key => key})
|
19
|
+
a = new(response)
|
20
|
+
a.jira_key = key
|
21
|
+
return a
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_by_key_and_id(key, id, options = {})
|
25
|
+
response = fetch({:parent => parent_name, :parent_key => key, :key => id})
|
26
|
+
a = new(response)
|
27
|
+
a.jira_key = key
|
28
|
+
return a
|
29
|
+
end
|
30
|
+
|
31
|
+
def add(comment, key)
|
32
|
+
fetch({:method => :post, :body => comment, :parent => parent_name, :parent_key => key})
|
33
|
+
end
|
34
|
+
|
35
|
+
def edit(comment, key, id)
|
36
|
+
fetch({:method => :put, :key => id, :body => comment, :parent => parent_name, :parent_key => key})
|
37
|
+
end
|
38
|
+
|
39
|
+
def remove(key, id)
|
40
|
+
fetch({:method => :delete, :body_to_params => true, :key => id, :parent => parent_name, :parent_key => key})
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_by_id(id, options = {})
|
46
|
+
self.class.find_by_key_and_id(@jira_key, id)
|
47
|
+
end
|
48
|
+
|
49
|
+
def add(comment)
|
50
|
+
self.class.add(comment, @jira_key)
|
51
|
+
end
|
52
|
+
|
53
|
+
def edit(comment)
|
54
|
+
self.class.edit(comment, @jira_key, self.id)
|
55
|
+
end
|
56
|
+
|
57
|
+
def remove(id = self.id)
|
58
|
+
self.class.remove(@jira_key, id)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Jiralicious
|
3
|
+
class Issue
|
4
|
+
class Fields
|
5
|
+
attr_accessor :fields_update
|
6
|
+
attr_accessor :fields_current
|
7
|
+
|
8
|
+
def initialize(fc = nil)
|
9
|
+
@fields_current = (fc == nil) ? Hash.new : fc
|
10
|
+
@fields_update = Hash.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def count
|
14
|
+
return @fields_update.count
|
15
|
+
end
|
16
|
+
|
17
|
+
def length
|
18
|
+
return @fields_update.length
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_comment(comment)
|
22
|
+
if !(@fields_update['comment'].type == Array)
|
23
|
+
@fields_update['comment'] = Array.new
|
24
|
+
end
|
25
|
+
@fields_update['comment'].push({"add" => {"body" => comment}})
|
26
|
+
end
|
27
|
+
|
28
|
+
def append_s(field, value)
|
29
|
+
if (@fields_update[field] == nil)
|
30
|
+
@fields_update[field] = @fields_current[field] unless @fields_current.nil?
|
31
|
+
@fields_update[field] ||= ""
|
32
|
+
end
|
33
|
+
@fields_update[field] += " " + value.to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def append_a(field, value)
|
37
|
+
@fields_update[field] = @fields_current[field] if (@fields_update[field] == nil)
|
38
|
+
@fields_update[field] = Array.new if !(@fields_update[field].is_a? Array)
|
39
|
+
if value.is_a? String
|
40
|
+
@fields_update[field].push(value)
|
41
|
+
else
|
42
|
+
@fields_update[field] = @fields_update[field].concat(value)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def append_h(field, hash)
|
47
|
+
@fields_update[field] = @fields_current[field] if (@fields_update[field] == nil)
|
48
|
+
@fields_update[field] = Hash.new if !(@fields_update[field].is_a? Hash)
|
49
|
+
@fields_update[field].merge!(hash)
|
50
|
+
end
|
51
|
+
|
52
|
+
def set(field, value)
|
53
|
+
@fields_update[field] = value
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_name(field, value)
|
57
|
+
@fields_update[field] = {"name" => value}
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_id(field, value)
|
61
|
+
@fields_update[field] = {"id" => value}
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_current(fc)
|
65
|
+
@fields_current = fc if fc.type == Hash
|
66
|
+
end
|
67
|
+
|
68
|
+
def current
|
69
|
+
return @fields_current
|
70
|
+
end
|
71
|
+
|
72
|
+
def updated
|
73
|
+
return @fields_update
|
74
|
+
end
|
75
|
+
|
76
|
+
def format_for_update
|
77
|
+
up = Hash.new
|
78
|
+
@fields_update.each do |k, v|
|
79
|
+
if k == "comment"
|
80
|
+
up[k] = v
|
81
|
+
else
|
82
|
+
up[k] = [{"set" => v}]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
return {"update" => up}
|
86
|
+
end
|
87
|
+
|
88
|
+
def format_for_create
|
89
|
+
return {"fields" => @fields_update}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# To change this template, choose Tools | Templates
|
2
|
+
# and open the template in the editor.
|
3
|
+
module Jiralicious
|
4
|
+
class Issue
|
5
|
+
class Transitions < Jiralicious::Base
|
6
|
+
|
7
|
+
attr_accessor :meta
|
8
|
+
|
9
|
+
def initialize(decoded_json, default = nil, &blk)
|
10
|
+
@loaded = false
|
11
|
+
@meta = nil
|
12
|
+
if decoded_json.is_a? Hash
|
13
|
+
properties_from_hash(decoded_json)
|
14
|
+
super(decoded_json)
|
15
|
+
parse!(decoded_json)
|
16
|
+
@loaded = true
|
17
|
+
else
|
18
|
+
self.class.property :jira_key
|
19
|
+
self.jira_key = default
|
20
|
+
decoded_json.each do |list|
|
21
|
+
self.class.property :"id_#{list['id']}"
|
22
|
+
self.merge!({"id_#{list['id']}" => self.class.new(list)})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
|
29
|
+
def find(key, options = {})
|
30
|
+
response = fetch({:parent => parent_name, :parent_key => key})
|
31
|
+
response.parsed_response['transitions'].each do |t|
|
32
|
+
t['jira_key'] = key
|
33
|
+
end
|
34
|
+
a = new(response.parsed_response['transitions'], key)
|
35
|
+
return a
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_by_key_and_id(key, id, options = {})
|
39
|
+
response = fetch({:key => id, :parent => parent_name, :parent_key => key})
|
40
|
+
response.parsed_response['jira_key'] = key
|
41
|
+
a = new(response.parsed_response['transitions'])
|
42
|
+
return a
|
43
|
+
end
|
44
|
+
|
45
|
+
def go(key, id, options = {})
|
46
|
+
transition = {"transition" => {"id" => id}}
|
47
|
+
if options[:comment].is_a? String
|
48
|
+
transition.merge!({"update" => {"comment" => [{"add" => {"body" => options[:comment].to_s}}]}})
|
49
|
+
elsif options[:comment].is_a? Jiralicious::Issue::Fields
|
50
|
+
transition.merge!(options[:comment].format_for_update)
|
51
|
+
elsif options[:comment].is_a? Hash
|
52
|
+
transition.merge!({"update" => options[:comment]})
|
53
|
+
end
|
54
|
+
if options[:fields].is_a? Jiralicious::Issue::Fields
|
55
|
+
transition.merge!(options[:fields].format_for_create)
|
56
|
+
elsif options[:fields].is_a? Hash
|
57
|
+
transition.merge!({"fields" => options[:fields]})
|
58
|
+
end
|
59
|
+
fetch({:method => :post, :parent => parent_name, :parent_key => key, :body => transition})
|
60
|
+
end
|
61
|
+
|
62
|
+
def meta(key, id, options = {})
|
63
|
+
response = fetch({:method => :get, :parent => parent_name, :parent_key => key, :body_to_params => true,
|
64
|
+
:body => {"transitionId" => id, "expand" => "transitions.fields"}})
|
65
|
+
response.parsed_response['transitions'].each do |t|
|
66
|
+
t['jira_key'] = key
|
67
|
+
end
|
68
|
+
a = (options[:return].nil?) ? new(response.parsed_response['transitions'], key) : response
|
69
|
+
return a
|
70
|
+
end
|
71
|
+
|
72
|
+
alias :find_all :find
|
73
|
+
end
|
74
|
+
|
75
|
+
def all
|
76
|
+
self.class.all(self.jira_key) if self.jira_key
|
77
|
+
end
|
78
|
+
|
79
|
+
def go(options = {})
|
80
|
+
self.class.go(self.jira_key, self.id, options)
|
81
|
+
end
|
82
|
+
|
83
|
+
def meta
|
84
|
+
if @meta.nil?
|
85
|
+
l = self.class.meta(self.jira_key, self.id, {:return => true})
|
86
|
+
@meta = Field.new(l.parsed_response['transitions'].first)
|
87
|
+
end
|
88
|
+
@meta
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# To change this template, choose Tools | Templates
|
2
|
+
# and open the template in the editor.
|
3
|
+
module Jiralicious
|
4
|
+
class Issue
|
5
|
+
class Watchers < Jiralicious::Base
|
6
|
+
|
7
|
+
attr_accessor :jira_key
|
8
|
+
|
9
|
+
def initialize(decoded_json = nil, default = nil, &blk)
|
10
|
+
if (decoded_json != nil)
|
11
|
+
properties_from_hash(decoded_json)
|
12
|
+
super(decoded_json)
|
13
|
+
parse!(decoded_json)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def find_by_key(key)
|
19
|
+
response = fetch({:parent => parent_name, :parent_key => key})
|
20
|
+
a = new(response)
|
21
|
+
a.jira_key = key
|
22
|
+
return a
|
23
|
+
end
|
24
|
+
|
25
|
+
def add(name, key)
|
26
|
+
fetch({:method => :post, :body => name, :body_override => true, :parent => parent_name, :parent_key => key})
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove(name, key)
|
30
|
+
fetch({:method => :delete, :body_to_params => true, :body => {:username => name}, :parent => parent_name, :parent_key => key})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def find
|
35
|
+
self.class.find_by_key(@jira_key)
|
36
|
+
end
|
37
|
+
|
38
|
+
def add(name)
|
39
|
+
self.class.add(name, @jira_key)
|
40
|
+
end
|
41
|
+
|
42
|
+
def remove(name)
|
43
|
+
self.class.remove(name, @jira_key)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# To change this template, choose Tools | Templates
|
2
|
+
# and open the template in the editor.
|
3
|
+
module Jiralicious
|
4
|
+
class Project < Jiralicious::Base
|
5
|
+
|
6
|
+
attr_accessor :issues
|
7
|
+
|
8
|
+
### Initialization ###
|
9
|
+
def initialize(decoded_json, default = nil, &blk)
|
10
|
+
@loaded = false
|
11
|
+
if decoded_json.is_a? Hash
|
12
|
+
properties_from_hash(decoded_json)
|
13
|
+
super(decoded_json)
|
14
|
+
parse!(decoded_json)
|
15
|
+
@loaded = true
|
16
|
+
else
|
17
|
+
decoded_json.each do |list|
|
18
|
+
self.class.property :"#{list['key']}"
|
19
|
+
self.merge!({list['key'] => self.class.find(list['key'])})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def issue_list(key)
|
26
|
+
response = Jiralicious.search("project=#{key}", {:fields => ["id", "key"]})
|
27
|
+
i_out = Issue.new
|
28
|
+
response.issues_raw.each do |issue|
|
29
|
+
i_out.class.property :"#{issue["key"].gsub("-", "_")}"
|
30
|
+
t = Issue.new
|
31
|
+
i_out[issue["key"].gsub("-", "_")] = t.load(issue, true)
|
32
|
+
end
|
33
|
+
i_out
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def issues
|
38
|
+
if @issues == nil
|
39
|
+
@issues = self.class.issue_list(self.key)
|
40
|
+
end
|
41
|
+
return @issues
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/jiralicious/search.rb
CHANGED
@@ -3,11 +3,14 @@ module Jiralicious
|
|
3
3
|
def search(jql, options = {})
|
4
4
|
options[:start_at] ||= 0
|
5
5
|
options[:max_results] ||= 50
|
6
|
+
options[:fields] = [options[:fields]] if options[:fields].is_a? String
|
7
|
+
options[:fields] ||= ["*navigable"]
|
6
8
|
|
7
9
|
request_body = {
|
8
10
|
:jql => jql,
|
9
11
|
:startAt => options[:start_at],
|
10
|
-
:maxResults => options[:max_results]
|
12
|
+
:maxResults => options[:max_results],
|
13
|
+
:fields => options[:fields]
|
11
14
|
}.to_json
|
12
15
|
|
13
16
|
handler = Proc.new do |response|
|
data/lib/jiralicious/version.rb
CHANGED
data/spec/basic_session_spec.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
|
4
4
|
describe "performing a request" do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
before :each do
|
6
|
+
FakeWeb.register_uri(:get,
|
7
|
+
Jiralicious.uri + '/ok',
|
8
|
+
:status => "200")
|
9
9
|
end
|
10
10
|
|
11
11
|
let(:session) { Jiralicious::BasicSession.new }
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "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.auth_type = :cookie
|
12
|
+
config.api_version = "latest"
|
13
|
+
end
|
14
|
+
|
15
|
+
FakeWeb.register_uri(:get,
|
16
|
+
"#{Jiralicious.rest_path}/issue/EX-1/comment/",
|
17
|
+
:status => "200",
|
18
|
+
:body => comment_json)
|
19
|
+
FakeWeb.register_uri(:post,
|
20
|
+
"#{Jiralicious.rest_path}/issue/EX-1/comment/",
|
21
|
+
:status => "201",
|
22
|
+
:body => comment_json)
|
23
|
+
FakeWeb.register_uri(:get,
|
24
|
+
"#{Jiralicious.rest_path}/issue/EX-1/comment/10000",
|
25
|
+
:status => "200",
|
26
|
+
:body => comment_single_json)
|
27
|
+
FakeWeb.register_uri(:put,
|
28
|
+
"#{Jiralicious.rest_path}/issue/EX-1/comment/10000",
|
29
|
+
:status => "200",
|
30
|
+
:body => comment_single_json)
|
31
|
+
FakeWeb.register_uri(:delete,
|
32
|
+
"#{Jiralicious.rest_path}/issue/EX-1/comment/10000",
|
33
|
+
:status => "204")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "finds by isusse key" do
|
37
|
+
comments = Jiralicious::Issue::Comment.find_by_key("EX-1")
|
38
|
+
comments.should be_instance_of(Jiralicious::Issue::Comment)
|
39
|
+
comments.comments.count.should == 1
|
40
|
+
comments.comments[0]['id'].should == "10000"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "finds by isusse key and comment id" do
|
44
|
+
comments = Jiralicious::Issue::Comment.find_by_key_and_id("EX-1", "10000")
|
45
|
+
comments.should be_instance_of(Jiralicious::Issue::Comment)
|
46
|
+
comments.id.should == "10000"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "posts a new comment" do
|
50
|
+
response = Jiralicious::Issue::Comment.add({:body => "this is a test"}, "EX-1")
|
51
|
+
response.class.should == HTTParty::Response
|
52
|
+
response.parsed_response['comments'][0]['id'].to_f.should > 0
|
53
|
+
end
|
54
|
+
|
55
|
+
it "updates a comment" do
|
56
|
+
response = Jiralicious::Issue::Comment.edit("this is a test", "EX-1", "10000")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "deletes a comment" do
|
60
|
+
comment = Jiralicious::Issue::Comment.find_by_key_and_id("EX-1", "10000")
|
61
|
+
response = comment.remove
|
62
|
+
response.response.class.should == Net::HTTPNoContent
|
63
|
+
end
|
64
|
+
end
|