jiralicious 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -0
- data/jiralicious.gemspec +0 -2
- data/lib/jiralicious.rb +4 -0
- data/lib/jiralicious/avatar.rb +101 -0
- data/lib/jiralicious/base.rb +53 -15
- data/lib/jiralicious/configuration.rb +30 -4
- data/lib/jiralicious/custom_field_option.rb +7 -3
- data/lib/jiralicious/errors.rb +10 -0
- data/lib/jiralicious/field.rb +23 -12
- data/lib/jiralicious/issue.rb +69 -11
- data/lib/jiralicious/issue/comment.rb +54 -12
- data/lib/jiralicious/issue/fields.rb +44 -3
- data/lib/jiralicious/issue/transitions.rb +42 -11
- data/lib/jiralicious/issue/watchers.rb +19 -2
- data/lib/jiralicious/parsers/field_parser.rb +12 -0
- data/lib/jiralicious/project.rb +7 -1
- data/lib/jiralicious/project/avatar.rb +126 -0
- data/lib/jiralicious/search.rb +9 -0
- data/lib/jiralicious/search_result.rb +15 -7
- data/lib/jiralicious/session.rb +5 -0
- data/lib/jiralicious/user.rb +154 -0
- data/lib/jiralicious/user/avatar.rb +130 -0
- data/lib/jiralicious/version.rb +1 -1
- data/spec/avatar_spec.rb +50 -0
- data/spec/basic_session_spec.rb +4 -0
- data/spec/comment_spec.rb +2 -2
- data/spec/fixtures/avatar.json +7 -0
- data/spec/fixtures/avatar_custom.json +16 -0
- data/spec/fixtures/avatar_list.json +16 -0
- data/spec/fixtures/avatar_temp.json +7 -0
- data/spec/fixtures/avatar_test.png +0 -0
- data/spec/fixtures/user.json +27 -0
- data/spec/fixtures/user_array.json +26 -0
- data/spec/fixtures/user_picker.json +18 -0
- data/spec/issue_spec.rb +10 -9
- data/spec/project_avatar_spec.rb +66 -0
- data/spec/project_spec.rb +2 -2
- data/spec/search_spec.rb +2 -1
- data/spec/support/http.rb +24 -0
- data/spec/user_avatar_spec.rb +66 -0
- data/spec/user_spec.rb +79 -0
- data/spec/watchers_spec.rb +2 -2
- metadata +30 -18
data/README.md
CHANGED
data/jiralicious.gemspec
CHANGED
@@ -17,8 +17,6 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.add_runtime_dependency 'hashie', '>= 1.1'
|
18
18
|
s.add_runtime_dependency 'json', '>= 1.6', '< 1.9.0'
|
19
19
|
s.add_development_dependency 'rspec', '~> 2.6'
|
20
|
-
s.add_development_dependency 'gemcutter'
|
21
|
-
|
22
20
|
s.add_development_dependency 'rake'
|
23
21
|
s.add_development_dependency 'fakeweb', '~> 1.3.0'
|
24
22
|
|
data/lib/jiralicious.rb
CHANGED
@@ -15,12 +15,16 @@ require 'jiralicious/issue/comment'
|
|
15
15
|
require 'jiralicious/issue/watchers'
|
16
16
|
require 'jiralicious/issue/transitions'
|
17
17
|
require 'jiralicious/project'
|
18
|
+
require 'jiralicious/project/avatar'
|
18
19
|
require 'jiralicious/search'
|
19
20
|
require 'jiralicious/search_result'
|
20
21
|
require 'jiralicious/session'
|
22
|
+
require 'jiralicious/user'
|
23
|
+
require 'jiralicious/user/avatar'
|
21
24
|
require 'jiralicious/basic_session'
|
22
25
|
require 'jiralicious/cookie_session'
|
23
26
|
require 'jiralicious/configuration'
|
27
|
+
require 'jiralicious/avatar'
|
24
28
|
|
25
29
|
##
|
26
30
|
# The Jiralicious module standard options and methods
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Jiralicious
|
3
|
+
##
|
4
|
+
# Avatars in the Project class.
|
5
|
+
#
|
6
|
+
class Avatar < Jiralicious::Base
|
7
|
+
|
8
|
+
##
|
9
|
+
# Initialization Method
|
10
|
+
#
|
11
|
+
# [Arguments]
|
12
|
+
# :decoded_json (optional) decoded json object
|
13
|
+
#
|
14
|
+
def initialize(decoded_json = nil)
|
15
|
+
@loaded = false
|
16
|
+
if !decoded_json.nil?
|
17
|
+
if decoded_json.is_a? Hash
|
18
|
+
decoded_json = properties_from_hash(decoded_json)
|
19
|
+
super(decoded_json)
|
20
|
+
parse!(decoded_json)
|
21
|
+
self.each do |k, v|
|
22
|
+
if v.is_a? Hash
|
23
|
+
self[k] = self.class.new(v)
|
24
|
+
elsif v.is_a? Array
|
25
|
+
v.each_index do |i|
|
26
|
+
if v[i].is_a? Hash
|
27
|
+
v[i] = self.class.new(v[i])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
self[k] = v
|
31
|
+
end
|
32
|
+
end
|
33
|
+
@loaded = true
|
34
|
+
else
|
35
|
+
i = 0;
|
36
|
+
decoded_json.each do |list|
|
37
|
+
if !list['id'].nil?
|
38
|
+
if numeric? list['id']
|
39
|
+
id = :"id_#{list['id']}"
|
40
|
+
else
|
41
|
+
id = :"#{list['id']}"
|
42
|
+
end
|
43
|
+
else
|
44
|
+
id = :"_#{i}"
|
45
|
+
i += 1
|
46
|
+
end
|
47
|
+
self.class.property id
|
48
|
+
self[id] = self.class.new(list)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class << self
|
55
|
+
|
56
|
+
##
|
57
|
+
# Gets a list of available avatars
|
58
|
+
#
|
59
|
+
# [Arguments]
|
60
|
+
# :key (required) avatar type = Project or User
|
61
|
+
#
|
62
|
+
def system(key, options = {})
|
63
|
+
response = fetch({:method => :get, :key => "#{key}/system", :body => options})
|
64
|
+
return self.new(response.parsed_response)
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Creates temporary avatar
|
69
|
+
#
|
70
|
+
# [Arguments]
|
71
|
+
# :key (required) avatar type = Project or User
|
72
|
+
#
|
73
|
+
# :filename (required) file to upload
|
74
|
+
#
|
75
|
+
# :size (required) size of the file
|
76
|
+
#
|
77
|
+
def temporary(key, options = {})
|
78
|
+
response = fetch({:method => :post, :key => "#{key}/temporary", :body => options})
|
79
|
+
return self.new(response.parsed_response)
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Updates the cropping on a temporary avatar
|
84
|
+
#
|
85
|
+
# [Arguments]
|
86
|
+
# :key (required) avatar type = Project or User
|
87
|
+
#
|
88
|
+
# :cropperWidth (optional) width of the image
|
89
|
+
#
|
90
|
+
# :cropperOffsetX (optional) X Offset on image
|
91
|
+
#
|
92
|
+
# :cropperOffsety (optional) Y Offset on image
|
93
|
+
#
|
94
|
+
# :needsCropping (optional) Boolean if needs cropping
|
95
|
+
#
|
96
|
+
def temporary_crop(key, options = {})
|
97
|
+
response = fetch({:method => :post, :key => "#{key}/temporaryCrop", :body => options})
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/jiralicious/base.rb
CHANGED
@@ -22,6 +22,9 @@ module Jiralicious
|
|
22
22
|
# Adds an underscore (_) before a numeric field.
|
23
23
|
# This ensures that numeric fields will be treated as strings.
|
24
24
|
#
|
25
|
+
# [Arguments]
|
26
|
+
# :hash (required) hash to be added to properties
|
27
|
+
#
|
25
28
|
def properties_from_hash(hash)
|
26
29
|
hash.inject({}) do |newhash, (k, v)|
|
27
30
|
k = k.gsub("-", "_")
|
@@ -34,8 +37,14 @@ module Jiralicious
|
|
34
37
|
|
35
38
|
class << self
|
36
39
|
##
|
37
|
-
# Finds the specified key in relation to the current class.
|
38
|
-
# inheritance and will create an error
|
40
|
+
# Finds the specified key in relation to the current class.
|
41
|
+
# This is based on the inheritance and will create an error
|
42
|
+
# if called from the Base Class directly.
|
43
|
+
#
|
44
|
+
# [Arguments]
|
45
|
+
# :key (required) object key to find
|
46
|
+
#
|
47
|
+
# :reload (required) is object reloading forced
|
39
48
|
#
|
40
49
|
def find(key, options = {})
|
41
50
|
response = fetch({:key => key})
|
@@ -47,9 +56,10 @@ module Jiralicious
|
|
47
56
|
end
|
48
57
|
|
49
58
|
##
|
50
|
-
# Searches for all objects of the inheritance class. This
|
51
|
-
# datasets and is not recommended
|
52
|
-
#
|
59
|
+
# Searches for all objects of the inheritance class. This
|
60
|
+
# method can create very large datasets and is not recommended
|
61
|
+
# for any request that could slow down either Jira or the
|
62
|
+
# Ruby application.
|
53
63
|
#
|
54
64
|
def find_all
|
55
65
|
response = fetch()
|
@@ -72,9 +82,27 @@ module Jiralicious
|
|
72
82
|
end
|
73
83
|
|
74
84
|
##
|
75
|
-
# uses the options to build the URI options necessary to handle the
|
76
|
-
# Some options are defaulted if not explicit while others
|
77
|
-
# under specific conditions.
|
85
|
+
# uses the options to build the URI options necessary to handle the
|
86
|
+
# request. Some options are defaulted if not explicit while others
|
87
|
+
# are only necessary under specific conditions.
|
88
|
+
#
|
89
|
+
#
|
90
|
+
# [Arguments]
|
91
|
+
# :key (optional) key of object to fetch
|
92
|
+
#
|
93
|
+
# :method (optional) limited to the standard request types default of :get
|
94
|
+
#
|
95
|
+
# :parent (optional) boolean will the parent object be used
|
96
|
+
#
|
97
|
+
# :parent_key (optional) parent's key (must set :parent to use)
|
98
|
+
#
|
99
|
+
# :body (optional) fields to be sent with the fetch
|
100
|
+
#
|
101
|
+
# :body_override (optional) corrects issues in :body if set
|
102
|
+
#
|
103
|
+
# :body_to_params (optional) forces body to be appended to URI
|
104
|
+
#
|
105
|
+
# :url (optional) overrides auto generated URI with custom URI
|
78
106
|
#
|
79
107
|
def fetch(options = {})
|
80
108
|
options[:method] = :get unless [:get, :post, :put, :delete].include?(options[:method])
|
@@ -88,7 +116,7 @@ module Jiralicious
|
|
88
116
|
options[:params_uri] = "?#{options[:body].to_params}" unless options[:body].nil? || options[:body].empty?
|
89
117
|
options[:body_uri] = nil
|
90
118
|
end
|
91
|
-
options[:url_uri] = options[:url].nil? ? "#{Jiralicious.rest_path}/#{options[:parent_uri]}#{endpoint_name}/#{options[:key]}#{options[:params_uri]}" : options[:url]
|
119
|
+
options[:url_uri] = options[:url].nil? ? "#{Jiralicious.rest_path}/#{options[:parent_uri]}#{endpoint_name}/#{options[:key]}#{options[:params_uri]}" : "#{options[:url]}#{options[:params_uri]}"
|
92
120
|
Jiralicious.session.request(options[:method], options[:url_uri], :handler => handler, :body => options[:body_uri].to_json)
|
93
121
|
end
|
94
122
|
|
@@ -102,11 +130,11 @@ module Jiralicious
|
|
102
130
|
when 200..204
|
103
131
|
response
|
104
132
|
when 400
|
105
|
-
raise Jiralicious::TransitionError.new(response)
|
133
|
+
raise Jiralicious::TransitionError.new(response.inspect)
|
106
134
|
when 404
|
107
|
-
raise Jiralicious::IssueNotFound.new(response)
|
135
|
+
raise Jiralicious::IssueNotFound.new(response.inspect)
|
108
136
|
else
|
109
|
-
raise Jiralicious::JiraError.new(response)
|
137
|
+
raise Jiralicious::JiraError.new(response.inspect)
|
110
138
|
end
|
111
139
|
end
|
112
140
|
end
|
@@ -129,9 +157,9 @@ module Jiralicious
|
|
129
157
|
end
|
130
158
|
|
131
159
|
##
|
132
|
-
# Searches for all objects of the inheritance class. This method can
|
133
|
-
# datasets and is not recommended for any request
|
134
|
-
# the Ruby application.
|
160
|
+
# Searches for all objects of the inheritance class. This method can
|
161
|
+
# create very large datasets and is not recommended for any request
|
162
|
+
# that could slow down either Jira or the Ruby application.
|
135
163
|
#
|
136
164
|
def all
|
137
165
|
self.class.all
|
@@ -156,6 +184,13 @@ module Jiralicious
|
|
156
184
|
# Overrides the default method_missing check. This override is used in lazy
|
157
185
|
# loading to ensure that the requested field or method is truly unavailable.
|
158
186
|
#
|
187
|
+
# [Arguments]
|
188
|
+
# :meth (system)
|
189
|
+
#
|
190
|
+
# :args (system)
|
191
|
+
#
|
192
|
+
# :block (system)
|
193
|
+
#
|
159
194
|
def method_missing(meth, *args, &block)
|
160
195
|
if !loaded?
|
161
196
|
self.loaded = true
|
@@ -169,6 +204,9 @@ module Jiralicious
|
|
169
204
|
##
|
170
205
|
# Validates if the provided object is a numeric value
|
171
206
|
#
|
207
|
+
# [Arguments]
|
208
|
+
# :object (required) object to be tested
|
209
|
+
#
|
172
210
|
def numeric?(object)
|
173
211
|
true if Float(object) rescue false
|
174
212
|
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'ostruct'
|
3
3
|
module Jiralicious
|
4
|
+
##
|
5
|
+
# Base configuration module for Jiralicious
|
6
|
+
#
|
4
7
|
module Configuration
|
5
8
|
# Array of available attributes
|
6
|
-
VALID_OPTIONS = [:username, :password, :uri, :api_version, :auth_type]
|
9
|
+
VALID_OPTIONS = [:username, :password, :uri, :api_version, :auth_type, :project]
|
7
10
|
# Default user name set prior to login attempt
|
8
11
|
DEFAULT_USERNAME = nil
|
9
12
|
# Default password set prior to login attempt
|
@@ -15,7 +18,9 @@ module Jiralicious
|
|
15
18
|
# Default API Version can be set any valid version or "latest"
|
16
19
|
DEFAULT_API_VERSION = "latest"
|
17
20
|
|
21
|
+
##
|
18
22
|
# Enables block configuration mode
|
23
|
+
#
|
19
24
|
def configure
|
20
25
|
yield self
|
21
26
|
end
|
@@ -23,19 +28,28 @@ module Jiralicious
|
|
23
28
|
# Provides access to the array of attributes
|
24
29
|
attr_accessor *VALID_OPTIONS
|
25
30
|
|
31
|
+
##
|
26
32
|
# Reset when extended into class
|
33
|
+
#
|
34
|
+
# [Arguments]
|
35
|
+
# :base (required)
|
36
|
+
#
|
27
37
|
def self.extended(base)
|
28
38
|
base.reset
|
29
39
|
end
|
30
40
|
|
41
|
+
##
|
31
42
|
# Pass options to set the values
|
43
|
+
#
|
32
44
|
def options
|
33
45
|
VALID_OPTIONS.inject({}) do |option, key|
|
34
46
|
option.merge!(key => send(key))
|
35
47
|
end
|
36
48
|
end
|
37
49
|
|
50
|
+
##
|
38
51
|
# Resets all attributes to default values
|
52
|
+
#
|
39
53
|
def reset
|
40
54
|
self.username = DEFAULT_USERNAME
|
41
55
|
self.password = DEFAULT_PASSWORD
|
@@ -47,8 +61,9 @@ module Jiralicious
|
|
47
61
|
##
|
48
62
|
# Loads the provided YML file.
|
49
63
|
#
|
50
|
-
# Can provide either direct or relational path to the file.
|
51
|
-
#
|
64
|
+
# Can provide either direct or relational path to the file.
|
65
|
+
# It is recommended to send a direct path due to dynamic
|
66
|
+
# loading and/or different file locations due to different deployment methods.
|
52
67
|
#
|
53
68
|
# [Direct Path] /usr/project/somepath_to_file/jira.yml
|
54
69
|
#
|
@@ -56,12 +71,23 @@ module Jiralicious
|
|
56
71
|
#
|
57
72
|
# "./config/jira.yml"
|
58
73
|
#
|
59
|
-
|
74
|
+
# [Arguments]
|
75
|
+
# :yml_file (required) path to file to load
|
76
|
+
#
|
77
|
+
# :mode (optional) used to define environment type
|
78
|
+
#
|
79
|
+
def load_yml(yml_file, mode=nil)
|
60
80
|
if File.exist?(yml_file)
|
61
81
|
yml_cfg = OpenStruct.new(YAML.load_file(yml_file))
|
82
|
+
if mode.nil? || mode =~ /production/i
|
62
83
|
yml_cfg.jira.each do |k, v|
|
63
84
|
instance_variable_set("@#{k}", v)
|
64
85
|
end
|
86
|
+
else
|
87
|
+
yml_cfg.send(mode).each do |k,v|
|
88
|
+
instance_variable_set("@#{k}", v)
|
89
|
+
end
|
90
|
+
end
|
65
91
|
else
|
66
92
|
reset
|
67
93
|
end
|
@@ -1,15 +1,19 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Jiralicious
|
3
3
|
##
|
4
|
-
# The CustomFieldOption provides a list of available custom
|
5
|
-
# used in lazy loading and can
|
4
|
+
# The CustomFieldOption provides a list of available custom
|
5
|
+
# field options. This method is used in lazy loading and can
|
6
|
+
# be used to validate options prior to updating the issue.
|
6
7
|
#
|
7
8
|
class CustomFieldOption < Jiralicious::Base
|
8
9
|
|
9
10
|
##
|
10
11
|
# Initialization Method
|
11
12
|
#
|
12
|
-
|
13
|
+
# [Arguments]
|
14
|
+
# :decoded_json (optional) rubyized json object
|
15
|
+
#
|
16
|
+
def initialize(decoded_json)
|
13
17
|
@loaded = false
|
14
18
|
if decoded_json.is_a? Hash
|
15
19
|
properties_from_hash(decoded_json)
|
data/lib/jiralicious/errors.rb
CHANGED
@@ -1,17 +1,27 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Jiralicious
|
4
|
+
# General Jira error
|
4
5
|
class JiraError < StandardError; end
|
6
|
+
# AuthenticateError
|
5
7
|
class AuthenticationError < StandardError; end
|
8
|
+
# NotLoggedIn error
|
6
9
|
class NotLoggedIn < AuthenticationError; end
|
10
|
+
# InvalidLogin error
|
7
11
|
class InvalidLogin < AuthenticationError; end
|
8
12
|
|
9
13
|
# These are in the JIRA API docs. Not sure about specifics, as the docs don't
|
10
14
|
# mention them. Added here for completeness and future implementation.
|
11
15
|
# http://confluence.atlassian.com/display/JIRA/JIRA+REST+API+%28Alpha%29+Tutorial
|
16
|
+
|
17
|
+
# Cookie has Expired (depricated)
|
12
18
|
class CookieExpired < AuthenticationError; end
|
19
|
+
# Captcha is Required (not used)
|
13
20
|
class CaptchaRequired < AuthenticationError; end
|
21
|
+
# IssueNotFound error (any invalid object)
|
14
22
|
class IssueNotFound < StandardError; end
|
23
|
+
# JQL Error (error in JQL search(
|
15
24
|
class JqlError < StandardError; end
|
25
|
+
# Transition Error
|
16
26
|
class TransitionError < StandardError; end
|
17
27
|
end
|
data/lib/jiralicious/field.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Jiralicious
|
3
3
|
##
|
4
|
-
# The Field class is used in multiple classes as a support
|
5
|
-
# is designed as a Object Oriented Method
|
4
|
+
# The Field class is used in multiple classes as a support
|
5
|
+
# object. This class is designed as a Object Oriented Method
|
6
|
+
# of viewing the Jira JSON/Hash.
|
6
7
|
#
|
7
8
|
class Field < Jiralicious::Base
|
8
9
|
##
|
9
10
|
# Initialization Method
|
10
11
|
#
|
11
|
-
# Builds the dynamic Field object from either a Hash or Array.
|
12
|
-
#
|
12
|
+
# Builds the dynamic Field object from either a Hash or Array.
|
13
|
+
# The decoded JSON object can be nested as deep as necessary
|
14
|
+
# but it is recommended that JSON objects are no deeper then
|
15
|
+
# 5 levels maximum.
|
13
16
|
#
|
14
|
-
|
17
|
+
# [Arguments]
|
18
|
+
# :decoded_json (optional) rubyized json object
|
19
|
+
#
|
20
|
+
def initialize(decoded_json)
|
15
21
|
@loaded = false
|
16
22
|
if decoded_json.is_a? Hash
|
17
23
|
decoded_json = properties_from_hash(decoded_json)
|
@@ -31,15 +37,20 @@ module Jiralicious
|
|
31
37
|
end
|
32
38
|
@loaded = true
|
33
39
|
else
|
40
|
+
i = 0;
|
34
41
|
decoded_json.each do |list|
|
35
|
-
if
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
42
|
+
if !list['id'].nil?
|
43
|
+
if numeric? list['id']
|
44
|
+
id = :"id_#{list['id']}"
|
45
|
+
else
|
46
|
+
id = :"#{list['id']}"
|
47
|
+
end
|
48
|
+
else
|
49
|
+
id = :"_#{i}"
|
50
|
+
i += 1
|
51
|
+
end
|
40
52
|
self.class.property id
|
41
|
-
|
42
|
-
self.merge!({id => out})
|
53
|
+
self[id] = self.class.new(list)
|
43
54
|
end
|
44
55
|
end
|
45
56
|
end
|