sclemmer-jira-ruby 0.1.12
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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +46 -0
- data/README.rdoc +309 -0
- data/Rakefile +28 -0
- data/example.rb +119 -0
- data/http-basic-example.rb +112 -0
- data/lib/jira.rb +33 -0
- data/lib/jira/base.rb +497 -0
- data/lib/jira/base_factory.rb +49 -0
- data/lib/jira/client.rb +165 -0
- data/lib/jira/has_many_proxy.rb +43 -0
- data/lib/jira/http_client.rb +69 -0
- data/lib/jira/http_error.rb +16 -0
- data/lib/jira/oauth_client.rb +84 -0
- data/lib/jira/railtie.rb +10 -0
- data/lib/jira/request_client.rb +18 -0
- data/lib/jira/resource/attachment.rb +12 -0
- data/lib/jira/resource/comment.rb +14 -0
- data/lib/jira/resource/component.rb +10 -0
- data/lib/jira/resource/field.rb +10 -0
- data/lib/jira/resource/filter.rb +15 -0
- data/lib/jira/resource/issue.rb +80 -0
- data/lib/jira/resource/issuetype.rb +10 -0
- data/lib/jira/resource/priority.rb +10 -0
- data/lib/jira/resource/project.rb +31 -0
- data/lib/jira/resource/status.rb +10 -0
- data/lib/jira/resource/transition.rb +33 -0
- data/lib/jira/resource/user.rb +14 -0
- data/lib/jira/resource/version.rb +10 -0
- data/lib/jira/resource/worklog.rb +16 -0
- data/lib/jira/tasks.rb +0 -0
- data/lib/jira/version.rb +3 -0
- data/lib/tasks/generate.rake +18 -0
- data/sclemmer-jira-ruby.gemspec +28 -0
- data/spec/integration/attachment_spec.rb +23 -0
- data/spec/integration/comment_spec.rb +55 -0
- data/spec/integration/component_spec.rb +42 -0
- data/spec/integration/field_spec.rb +35 -0
- data/spec/integration/issue_spec.rb +94 -0
- data/spec/integration/issuetype_spec.rb +26 -0
- data/spec/integration/priority_spec.rb +27 -0
- data/spec/integration/project_spec.rb +56 -0
- data/spec/integration/status_spec.rb +27 -0
- data/spec/integration/transition_spec.rb +52 -0
- data/spec/integration/user_spec.rb +25 -0
- data/spec/integration/version_spec.rb +43 -0
- data/spec/integration/worklog_spec.rb +55 -0
- data/spec/jira/base_factory_spec.rb +46 -0
- data/spec/jira/base_spec.rb +583 -0
- data/spec/jira/client_spec.rb +188 -0
- data/spec/jira/has_many_proxy_spec.rb +47 -0
- data/spec/jira/http_client_spec.rb +109 -0
- data/spec/jira/http_error_spec.rb +26 -0
- data/spec/jira/oauth_client_spec.rb +111 -0
- data/spec/jira/request_client_spec.rb +14 -0
- data/spec/jira/resource/attachment_spec.rb +20 -0
- data/spec/jira/resource/filter_spec.rb +97 -0
- data/spec/jira/resource/issue_spec.rb +123 -0
- data/spec/jira/resource/project_factory_spec.rb +13 -0
- data/spec/jira/resource/project_spec.rb +70 -0
- data/spec/jira/resource/worklog_spec.rb +24 -0
- data/spec/mock_responses/attachment/10000.json +20 -0
- data/spec/mock_responses/component.post.json +28 -0
- data/spec/mock_responses/component/10000.invalid.put.json +5 -0
- data/spec/mock_responses/component/10000.json +39 -0
- data/spec/mock_responses/component/10000.put.json +39 -0
- data/spec/mock_responses/field.json +32 -0
- data/spec/mock_responses/field/1.json +15 -0
- data/spec/mock_responses/issue.json +1108 -0
- data/spec/mock_responses/issue.post.json +5 -0
- data/spec/mock_responses/issue/10002.invalid.put.json +6 -0
- data/spec/mock_responses/issue/10002.json +126 -0
- data/spec/mock_responses/issue/10002.put.missing_field_update.json +6 -0
- data/spec/mock_responses/issue/10002/comment.json +65 -0
- data/spec/mock_responses/issue/10002/comment.post.json +29 -0
- data/spec/mock_responses/issue/10002/comment/10000.json +29 -0
- data/spec/mock_responses/issue/10002/comment/10000.put.json +29 -0
- data/spec/mock_responses/issue/10002/transitions.json +49 -0
- data/spec/mock_responses/issue/10002/transitions.post.json +1 -0
- data/spec/mock_responses/issue/10002/worklog.json +98 -0
- data/spec/mock_responses/issue/10002/worklog.post.json +30 -0
- data/spec/mock_responses/issue/10002/worklog/10000.json +31 -0
- data/spec/mock_responses/issue/10002/worklog/10000.put.json +30 -0
- data/spec/mock_responses/issuetype.json +42 -0
- data/spec/mock_responses/issuetype/5.json +8 -0
- data/spec/mock_responses/priority.json +42 -0
- data/spec/mock_responses/priority/1.json +8 -0
- data/spec/mock_responses/project.json +12 -0
- data/spec/mock_responses/project/SAMPLEPROJECT.issues.json +1108 -0
- data/spec/mock_responses/project/SAMPLEPROJECT.json +84 -0
- data/spec/mock_responses/status.json +37 -0
- data/spec/mock_responses/status/1.json +7 -0
- data/spec/mock_responses/user_username=admin.json +17 -0
- data/spec/mock_responses/version.post.json +7 -0
- data/spec/mock_responses/version/10000.invalid.put.json +5 -0
- data/spec/mock_responses/version/10000.json +11 -0
- data/spec/mock_responses/version/10000.put.json +7 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/clients_helper.rb +16 -0
- data/spec/support/matchers/have_attributes.rb +11 -0
- data/spec/support/matchers/have_many.rb +9 -0
- data/spec/support/matchers/have_one.rb +5 -0
- data/spec/support/shared_examples/integration.rb +194 -0
- metadata +302 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
module JIRA
|
2
|
+
|
3
|
+
# This is the base class for all the JIRA resource factory instances.
|
4
|
+
class BaseFactory
|
5
|
+
|
6
|
+
attr_reader :client
|
7
|
+
|
8
|
+
def initialize(client)
|
9
|
+
@client = client
|
10
|
+
end
|
11
|
+
|
12
|
+
# Return the name of the class which this factory generates, i.e.
|
13
|
+
# JIRA::Resource::FooFactory creates JIRA::Resource::Foo instances.
|
14
|
+
def target_class
|
15
|
+
# Need to do a little bit of work here as Module.const_get doesn't work
|
16
|
+
# with nested class names, i.e. JIRA::Resource::Foo.
|
17
|
+
#
|
18
|
+
# So create a method chain from the class componenets. This code will
|
19
|
+
# unroll to:
|
20
|
+
# Module.const_get('JIRA').const_get('Resource').const_get('Foo')
|
21
|
+
#
|
22
|
+
target_class_name = self.class.name.sub(/Factory$/, '')
|
23
|
+
class_components = target_class_name.split('::')
|
24
|
+
|
25
|
+
class_components.inject(Module) do |mod, const_name|
|
26
|
+
mod.const_get(const_name)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.delegate_to_target_class(*method_names)
|
31
|
+
method_names.each do |method_name|
|
32
|
+
define_method method_name do |*args|
|
33
|
+
target_class.send(method_name, @client, *args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# The priciple purpose of this class is to delegate methods to the corresponding
|
39
|
+
# non-factory class and automatically prepend the client argument to the argument
|
40
|
+
# list.
|
41
|
+
delegate_to_target_class :all, :find, :collection_path, :singular_path, :jql
|
42
|
+
|
43
|
+
# This method needs special handling as it has a default argument value
|
44
|
+
def build(attrs={})
|
45
|
+
target_class.build(@client, attrs)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
data/lib/jira/client.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module JIRA
|
5
|
+
|
6
|
+
# This class is the main access point for all JIRA::Resource instances.
|
7
|
+
#
|
8
|
+
# The client must be initialized with an options hash containing
|
9
|
+
# configuration options. The available options are:
|
10
|
+
#
|
11
|
+
# :site => 'http://localhost:2990',
|
12
|
+
# :context_path => '/jira',
|
13
|
+
# :signature_method => 'RSA-SHA1',
|
14
|
+
# :request_token_path => "/plugins/servlet/oauth/request-token",
|
15
|
+
# :authorize_path => "/plugins/servlet/oauth/authorize",
|
16
|
+
# :access_token_path => "/plugins/servlet/oauth/access-token",
|
17
|
+
# :private_key_file => "rsakey.pem",
|
18
|
+
# :rest_base_path => "/rest/api/2",
|
19
|
+
# :consumer_key => nil,
|
20
|
+
# :consumer_secret => nil,
|
21
|
+
# :ssl_verify_mode => OpenSSL::SSL::VERIFY_PEER,
|
22
|
+
# :use_ssl => true,
|
23
|
+
# :username => nil,
|
24
|
+
# :password => nil,
|
25
|
+
# :auth_type => :oauth
|
26
|
+
# :proxy_address => nil
|
27
|
+
# :proxy_port => nil
|
28
|
+
#
|
29
|
+
# See the JIRA::Base class methods for all of the available methods on these accessor
|
30
|
+
# objects.
|
31
|
+
|
32
|
+
class Client
|
33
|
+
|
34
|
+
extend Forwardable
|
35
|
+
|
36
|
+
# The OAuth::Consumer instance returned by the OauthClient
|
37
|
+
#
|
38
|
+
# The authenticated client instance returned by the respective client type
|
39
|
+
# (Oauth, Basic)
|
40
|
+
attr_accessor :consumer, :request_client
|
41
|
+
|
42
|
+
# The configuration options for this client instance
|
43
|
+
attr_reader :options
|
44
|
+
|
45
|
+
def_delegators :@request_client, :init_access_token, :set_access_token, :set_request_token, :request_token, :access_token
|
46
|
+
|
47
|
+
DEFAULT_OPTIONS = {
|
48
|
+
:site => 'http://localhost:2990',
|
49
|
+
:context_path => '/jira',
|
50
|
+
:rest_base_path => "/rest/api/2",
|
51
|
+
:ssl_verify_mode => OpenSSL::SSL::VERIFY_PEER,
|
52
|
+
:use_ssl => true,
|
53
|
+
:auth_type => :oauth
|
54
|
+
}
|
55
|
+
|
56
|
+
def initialize(options={})
|
57
|
+
options = DEFAULT_OPTIONS.merge(options)
|
58
|
+
@options = options
|
59
|
+
@options[:rest_base_path] = @options[:context_path] + @options[:rest_base_path]
|
60
|
+
|
61
|
+
case options[:auth_type]
|
62
|
+
when :oauth
|
63
|
+
@request_client = OauthClient.new(@options)
|
64
|
+
@consumer = @request_client.consumer
|
65
|
+
when :basic
|
66
|
+
@request_client = HttpClient.new(@options)
|
67
|
+
end
|
68
|
+
|
69
|
+
@options.freeze
|
70
|
+
end
|
71
|
+
|
72
|
+
def Project # :nodoc:
|
73
|
+
JIRA::Resource::ProjectFactory.new(self)
|
74
|
+
end
|
75
|
+
|
76
|
+
def Issue # :nodoc:
|
77
|
+
JIRA::Resource::IssueFactory.new(self)
|
78
|
+
end
|
79
|
+
|
80
|
+
def Filter # :nodoc:
|
81
|
+
JIRA::Resource::FilterFactory.new(self)
|
82
|
+
end
|
83
|
+
|
84
|
+
def Component # :nodoc:
|
85
|
+
JIRA::Resource::ComponentFactory.new(self)
|
86
|
+
end
|
87
|
+
|
88
|
+
def User # :nodoc:
|
89
|
+
JIRA::Resource::UserFactory.new(self)
|
90
|
+
end
|
91
|
+
|
92
|
+
def Issuetype # :nodoc:
|
93
|
+
JIRA::Resource::IssuetypeFactory.new(self)
|
94
|
+
end
|
95
|
+
|
96
|
+
def Priority # :nodoc:
|
97
|
+
JIRA::Resource::PriorityFactory.new(self)
|
98
|
+
end
|
99
|
+
|
100
|
+
def Status # :nodoc:
|
101
|
+
JIRA::Resource::StatusFactory.new(self)
|
102
|
+
end
|
103
|
+
|
104
|
+
def Comment # :nodoc:
|
105
|
+
JIRA::Resource::CommentFactory.new(self)
|
106
|
+
end
|
107
|
+
|
108
|
+
def Attachment # :nodoc:
|
109
|
+
JIRA::Resource::AttachmentFactory.new(self)
|
110
|
+
end
|
111
|
+
|
112
|
+
def Worklog # :nodoc:
|
113
|
+
JIRA::Resource::WorklogFactory.new(self)
|
114
|
+
end
|
115
|
+
|
116
|
+
def Version # :nodoc:
|
117
|
+
JIRA::Resource::VersionFactory.new(self)
|
118
|
+
end
|
119
|
+
|
120
|
+
def Transition # :nodoc:
|
121
|
+
JIRA::Resource::TransitionFactory.new(self)
|
122
|
+
end
|
123
|
+
|
124
|
+
def Field # :nodoc:
|
125
|
+
JIRA::Resource::FieldFactory.new(self)
|
126
|
+
end
|
127
|
+
|
128
|
+
# HTTP methods without a body
|
129
|
+
def delete(path, headers = {})
|
130
|
+
request(:delete, path, nil, merge_default_headers(headers))
|
131
|
+
end
|
132
|
+
|
133
|
+
def get(path, headers = {})
|
134
|
+
request(:get, path, nil, merge_default_headers(headers))
|
135
|
+
end
|
136
|
+
|
137
|
+
def head(path, headers = {})
|
138
|
+
request(:head, path, nil, merge_default_headers(headers))
|
139
|
+
end
|
140
|
+
|
141
|
+
# HTTP methods with a body
|
142
|
+
def post(path, body = '', headers = {})
|
143
|
+
headers = {'Content-Type' => 'application/json'}.merge(headers)
|
144
|
+
request(:post, path, body, merge_default_headers(headers))
|
145
|
+
end
|
146
|
+
|
147
|
+
def put(path, body = '', headers = {})
|
148
|
+
headers = {'Content-Type' => 'application/json'}.merge(headers)
|
149
|
+
request(:put, path, body, merge_default_headers(headers))
|
150
|
+
end
|
151
|
+
|
152
|
+
# Sends the specified HTTP request to the REST API through the
|
153
|
+
# appropriate method (oauth, basic).
|
154
|
+
def request(http_method, path, body = '', headers={})
|
155
|
+
@request_client.request(http_method, path, body, headers)
|
156
|
+
end
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
def merge_default_headers(headers)
|
161
|
+
{'Accept' => 'application/json'}.merge(headers)
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Whenever a collection from a has_many relationship is accessed, an instance
|
3
|
+
# of this class is returned. This instance wraps the Array of instances in
|
4
|
+
# the collection with an extra build method, which allows new instances to be
|
5
|
+
# built on the collection with the correct properties.
|
6
|
+
#
|
7
|
+
# In practice, instances of this class behave exactly like an Array.
|
8
|
+
#
|
9
|
+
class JIRA::HasManyProxy
|
10
|
+
|
11
|
+
attr_reader :target_class, :parent
|
12
|
+
attr_accessor :collection
|
13
|
+
|
14
|
+
def initialize(parent, target_class, collection = [])
|
15
|
+
@parent = parent
|
16
|
+
@target_class = target_class
|
17
|
+
@collection = collection
|
18
|
+
end
|
19
|
+
|
20
|
+
# Builds an instance of this class with the correct parent.
|
21
|
+
# For example, issue.comments.build(attrs) will initialize a
|
22
|
+
# comment as follows:
|
23
|
+
#
|
24
|
+
# JIRA::Resource::Comment.new(issue.client,
|
25
|
+
# :attrs => attrs,
|
26
|
+
# :issue => issue)
|
27
|
+
def build(attrs = {})
|
28
|
+
resource = target_class.new(parent.client, :attrs => attrs, parent.to_sym => parent)
|
29
|
+
collection << resource
|
30
|
+
resource
|
31
|
+
end
|
32
|
+
|
33
|
+
# Forces an HTTP request to fetch all instances of the target class that
|
34
|
+
# are associated with the parent
|
35
|
+
def all
|
36
|
+
target_class.all(parent.client, parent.to_sym => parent)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Delegate any missing methods to the collection that this proxy wraps
|
40
|
+
def method_missing(method_name, *args, &block)
|
41
|
+
collection.send(method_name, *args, &block)
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/https'
|
3
|
+
require 'cgi/cookie'
|
4
|
+
|
5
|
+
module JIRA
|
6
|
+
class HttpClient < RequestClient
|
7
|
+
|
8
|
+
DEFAULT_OPTIONS = {
|
9
|
+
:username => '',
|
10
|
+
:password => ''
|
11
|
+
}
|
12
|
+
|
13
|
+
attr_reader :options
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
17
|
+
@cookies = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def make_request(http_method, path, body='', headers={})
|
21
|
+
request = Net::HTTP.const_get(http_method.to_s.capitalize).new(path, headers)
|
22
|
+
request.body = body unless body.nil?
|
23
|
+
add_cookies(request) if options[:use_cookies]
|
24
|
+
request.basic_auth(@options[:username], @options[:password])
|
25
|
+
response = basic_auth_http_conn.request(request)
|
26
|
+
store_cookies(response) if options[:use_cookies]
|
27
|
+
response
|
28
|
+
end
|
29
|
+
|
30
|
+
def basic_auth_http_conn
|
31
|
+
http_conn(uri)
|
32
|
+
end
|
33
|
+
|
34
|
+
def http_conn(uri)
|
35
|
+
if @options[:proxy_address]
|
36
|
+
http_class = Net::HTTP::Proxy(@options[:proxy_address], @options[:proxy_port] ? @options[:proxy_port] : 80)
|
37
|
+
else
|
38
|
+
http_class = Net::HTTP
|
39
|
+
end
|
40
|
+
http_conn = http_class.new(uri.host, uri.port)
|
41
|
+
http_conn.use_ssl = @options[:use_ssl]
|
42
|
+
http_conn.verify_mode = @options[:ssl_verify_mode]
|
43
|
+
http_conn
|
44
|
+
end
|
45
|
+
|
46
|
+
def uri
|
47
|
+
uri = URI.parse(@options[:site])
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def store_cookies(response)
|
53
|
+
cookies = response.get_fields('set-cookie')
|
54
|
+
if cookies
|
55
|
+
cookies.each do |cookie|
|
56
|
+
data = CGI::Cookie.parse(cookie)
|
57
|
+
data.delete('Path')
|
58
|
+
@cookies.merge!(data)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_cookies(request)
|
64
|
+
cookie_array = @cookies.values.map { |cookie| cookie.to_s }
|
65
|
+
request.add_field('Cookie', cookie_array.join('; ')) if cookie_array.any?
|
66
|
+
request
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
module JIRA
|
3
|
+
|
4
|
+
class HTTPError < StandardError
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_instance_delegators :@response, :message, :code
|
8
|
+
attr_reader :response
|
9
|
+
|
10
|
+
def initialize(response)
|
11
|
+
@response = response
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require 'json'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module JIRA
|
6
|
+
class OauthClient < RequestClient
|
7
|
+
|
8
|
+
DEFAULT_OPTIONS = {
|
9
|
+
:signature_method => 'RSA-SHA1',
|
10
|
+
:request_token_path => "/plugins/servlet/oauth/request-token",
|
11
|
+
:authorize_path => "/plugins/servlet/oauth/authorize",
|
12
|
+
:access_token_path => "/plugins/servlet/oauth/access-token",
|
13
|
+
:private_key_file => "rsakey.pem",
|
14
|
+
:consumer_key => nil,
|
15
|
+
:consumer_secret => nil
|
16
|
+
}
|
17
|
+
|
18
|
+
# This exception is thrown when the client is used before the OAuth access token
|
19
|
+
# has been initialized.
|
20
|
+
class UninitializedAccessTokenError < StandardError
|
21
|
+
def message
|
22
|
+
"init_access_token must be called before using the client"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
extend Forwardable
|
27
|
+
|
28
|
+
attr_accessor :consumer
|
29
|
+
attr_reader :options
|
30
|
+
|
31
|
+
def_instance_delegators :@consumer, :key, :secret, :get_request_token
|
32
|
+
|
33
|
+
def initialize(options)
|
34
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
35
|
+
@consumer = init_oauth_consumer(@options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def init_oauth_consumer(options)
|
39
|
+
@options[:request_token_path] = @options[:context_path] + @options[:request_token_path]
|
40
|
+
@options[:authorize_path] = @options[:context_path] + @options[:authorize_path]
|
41
|
+
@options[:access_token_path] = @options[:context_path] + @options[:access_token_path]
|
42
|
+
OAuth::Consumer.new(@options[:consumer_key],@options[:consumer_secret],@options)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the current request token if it is set, else it creates
|
46
|
+
# and sets a new token.
|
47
|
+
def request_token
|
48
|
+
@request_token ||= get_request_token
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets the request token from a given token and secret.
|
52
|
+
def set_request_token(token, secret)
|
53
|
+
@request_token = OAuth::RequestToken.new(@consumer, token, secret)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Initialises and returns a new access token from the params hash
|
57
|
+
# returned by the OAuth transaction.
|
58
|
+
def init_access_token(params)
|
59
|
+
@access_token = request_token.get_access_token(params)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Sets the access token from a preexisting token and secret.
|
63
|
+
def set_access_token(token, secret)
|
64
|
+
@access_token = OAuth::AccessToken.new(@consumer, token, secret)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the current access token. Raises an
|
68
|
+
# JIRA::Client::UninitializedAccessTokenError exception if it is not set.
|
69
|
+
def access_token
|
70
|
+
raise UninitializedAccessTokenError.new unless @access_token
|
71
|
+
@access_token
|
72
|
+
end
|
73
|
+
|
74
|
+
def make_request(http_method, path, body='', headers={})
|
75
|
+
case http_method
|
76
|
+
when :delete, :get, :head
|
77
|
+
response = access_token.send http_method, path, headers
|
78
|
+
when :post, :put
|
79
|
+
response = access_token.send http_method, path, body, headers
|
80
|
+
end
|
81
|
+
response
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/jira/railtie.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require 'json'
|
3
|
+
require 'net/https'
|
4
|
+
|
5
|
+
module JIRA
|
6
|
+
class RequestClient
|
7
|
+
|
8
|
+
# Returns the response if the request was successful (HTTP::2xx) and
|
9
|
+
# raises a JIRA::HTTPError if it was not successful, with the response
|
10
|
+
# attached.
|
11
|
+
|
12
|
+
def request(*args)
|
13
|
+
response = make_request(*args)
|
14
|
+
raise HTTPError.new(response) unless response.kind_of?(Net::HTTPSuccess)
|
15
|
+
response
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|