jiralicious 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.gitignore +2 -1
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +5 -0
  5. data/README.md +32 -4
  6. data/jiralicious.gemspec +7 -5
  7. data/lib/jiralicious.rb +10 -3
  8. data/lib/jiralicious/base.rb +114 -0
  9. data/lib/jiralicious/configuration.rb +13 -2
  10. data/lib/jiralicious/cookie_session.rb +5 -5
  11. data/lib/jiralicious/custom_field_option.rb +27 -0
  12. data/lib/jiralicious/field.rb +39 -0
  13. data/lib/jiralicious/issue.rb +111 -26
  14. data/lib/jiralicious/issue/comment.rb +62 -0
  15. data/lib/jiralicious/issue/fields.rb +93 -0
  16. data/lib/jiralicious/issue/transitions.rb +92 -0
  17. data/lib/jiralicious/issue/watchers.rb +47 -0
  18. data/lib/jiralicious/parsers/field_parser.rb +2 -2
  19. data/lib/jiralicious/project.rb +44 -0
  20. data/lib/jiralicious/search.rb +4 -1
  21. data/lib/jiralicious/search_result.rb +4 -0
  22. data/lib/jiralicious/version.rb +1 -1
  23. data/spec/basic_session_spec.rb +4 -4
  24. data/spec/comment_spec.rb +64 -0
  25. data/spec/configuration_spec.rb +9 -0
  26. data/spec/fixtures/comment.json +30 -0
  27. data/spec/fixtures/comment_single.json +29 -0
  28. data/spec/fixtures/issue.json +89 -93
  29. data/spec/fixtures/issue_2.json +30 -0
  30. data/spec/fixtures/issue_create.json +5 -0
  31. data/spec/fixtures/issue_createmeta.json +34 -0
  32. data/spec/fixtures/issue_editmeta.json +22 -0
  33. data/spec/fixtures/issue_update.json +164 -0
  34. data/spec/fixtures/jira.yml +7 -0
  35. data/spec/fixtures/project.json +87 -0
  36. data/spec/fixtures/project_issue_list.json +20 -0
  37. data/spec/fixtures/projects.json +22 -0
  38. data/spec/fixtures/search.json +9 -9
  39. data/spec/fixtures/test.json +24 -0
  40. data/spec/fixtures/transitions.json +61 -61
  41. data/spec/fixtures/watchers.json +17 -0
  42. data/spec/issue_spec.rb +255 -21
  43. data/spec/project_spec.rb +55 -0
  44. data/spec/search_result_spec.rb +20 -8
  45. data/spec/search_spec.rb +6 -6
  46. data/spec/support/http.rb +55 -2
  47. data/spec/watchers_spec.rb +43 -0
  48. metadata +154 -100
  49. data/.rvmrc +0 -1
  50. 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
@@ -34,8 +34,8 @@ module Jiralicious
34
34
 
35
35
  def normalize(name)
36
36
  name.gsub(/(\w+)([A-Z].*)/, '\1_\2').
37
- gsub(/\W/, "_").
38
- downcase
37
+ gsub(/\W/, "_").
38
+ downcase
39
39
  end
40
40
 
41
41
  def mashify(data)
@@ -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
@@ -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|
@@ -13,5 +13,9 @@ module Jiralicious
13
13
  Jiralicious::Issue.find(issue["key"])
14
14
  end
15
15
  end
16
+
17
+ def issues_raw
18
+ @issues
19
+ end
16
20
  end
17
21
  end
@@ -1,3 +1,3 @@
1
1
  module Jiralicious
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -2,10 +2,10 @@
2
2
  require "spec_helper"
3
3
 
4
4
  describe "performing a request" do
5
- before :each do
6
- FakeWeb.register_uri(:get,
7
- Jiralicious.uri + '/ok',
8
- :status => "200")
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