jira-ruby 0.0.2

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.
@@ -0,0 +1,44 @@
1
+ module Jira
2
+ module Resource
3
+
4
+ # This is the base class for all the Jira resource factory instances.
5
+ class BaseFactory
6
+
7
+ attr_reader :client
8
+
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ # Return the name of the class which this factory generates, i.e.
14
+ # Jira::Resource::FooFactory creates Jira::Resource::Foo instances.
15
+ def target_class
16
+ # Need to do a little bit of work here as Module.const_get doesn't work
17
+ # with nested class names, i.e. Jira::Resource::Foo.
18
+ #
19
+ # So create a method chain from the class componenets. This code will
20
+ # unroll to:
21
+ # Module.const_get('Jira').const_get('Resource').const_get('Foo')
22
+ #
23
+ target_class_name = self.class.name.sub(/Factory$/, '')
24
+ class_components = target_class_name.split('::')
25
+
26
+ class_components.inject(Module) do |mod, const_name|
27
+ mod.const_get(const_name)
28
+ end
29
+ end
30
+
31
+ def all
32
+ target_class.all(@client)
33
+ end
34
+
35
+ def find(key)
36
+ target_class.find(@client, key)
37
+ end
38
+
39
+ def build(attrs={})
40
+ target_class.build(@client, attrs)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,15 @@
1
+ module Jira
2
+ module Resource
3
+
4
+ class ComponentFactory < BaseFactory ; end
5
+
6
+ class Component < Base
7
+
8
+ def self.key_attribute
9
+ :id
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ require 'forwardable'
2
+ module Jira
3
+ module Resource
4
+
5
+ class HTTPError < StandardError
6
+ extend Forwardable
7
+
8
+ delegate [:message, :code] => :response
9
+ attr_reader :response
10
+
11
+ def initialize(response)
12
+ @response = response
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module Jira
2
+ module Resource
3
+
4
+ class IssueFactory < BaseFactory ; end
5
+
6
+ class Issue < Base
7
+
8
+ def self.key_attribute
9
+ :id
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module Jira
2
+ module Resource
3
+
4
+ class ProjectFactory < BaseFactory ; end
5
+
6
+ class Project < Base ; end
7
+
8
+ end
9
+ end
data/lib/jira/tasks.rb ADDED
File without changes
@@ -0,0 +1,3 @@
1
+ module Jira
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,16 @@
1
+ namespace :jira do
2
+ desc "Generate a consumer key for your application"
3
+ task :generate_consumer_key do
4
+ #FIXME SERIOUSLY. THIS IS NOT A REAL SOLUTION. I FEEL SO UNCLEAN.
5
+ system("for i in {1..10}; do echo $RANDOM$RANDOM$RANDOM; done | md5 | awk '{ print \"You can use this as your consumer key: \" $0 }'")
6
+ end
7
+
8
+ desc "Run the system call to generate a RSA public certificate"
9
+ task :generate_public_cert do
10
+ puts "Executing 'openssl req -x509 -nodes -newkey rsa:1024 -sha1 -keyout rsakey.pem -out rsacert.pem'"
11
+ system("openssl req -x509 -nodes -newkey rsa:1024 -sha1 -keyout rsakey.pem -out rsacert.pem")
12
+ puts "Done. The RSA-SHA1 private keyfile is in the current directory: \'rsakey.pem\'."
13
+ puts "You will need to copy the following certificate into your application link configuration in Jira:"
14
+ system("cat rsacert.pem")
15
+ end
16
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jira::Resource::Component do
4
+
5
+
6
+ let(:client) do
7
+ client = Jira::Client.new('foo', 'bar')
8
+ client.set_access_token('abc', '123')
9
+ client
10
+ end
11
+
12
+ let(:expected_attributes) do
13
+ {
14
+ 'self' => "http://localhost:2990/jira/rest/api/2/component/10000",
15
+ 'id' => "10000",
16
+ 'name' => "Cheesecake"
17
+ }
18
+ end
19
+
20
+ before(:each) do
21
+ stub_request(:get,
22
+ "http://localhost:2990/jira/rest/api/2/component/10000").
23
+ to_return(:body => get_mock_response('component/10000.json'))
24
+ stub_request(:delete,
25
+ "http://localhost:2990/jira/rest/api/2/component/10000").
26
+ to_return(:body => nil)
27
+ stub_request(:post,
28
+ "http://localhost:2990/jira/rest/api/2/component").
29
+ with(:body => '{"name":"Test component","project":"SAMPLEPROJECT"}').
30
+ to_return(:status => 201, :body => get_mock_response('component.post.json'))
31
+ stub_request(:put,
32
+ "http://localhost:2990/jira/rest/api/2/component/10000").
33
+ with(:body => '{"name":"Jammy"}').
34
+ to_return(:status => 200, :body => get_mock_response('component/10000.put.json'))
35
+ end
36
+
37
+ it "should get a single component by id" do
38
+ component = client.Component.find(10000)
39
+
40
+ component.should have_attributes(expected_attributes)
41
+ end
42
+
43
+ it "builds and fetches single component" do
44
+ component = client.Component.build('id' => 10000)
45
+ component.fetch
46
+
47
+ component.should have_attributes(expected_attributes)
48
+ end
49
+
50
+ it "deletes a component" do
51
+ component = client.Component.build('id' => "10000")
52
+ component.delete.should be_true
53
+ end
54
+
55
+ it "saves a new component" do
56
+ component = client.Component.build
57
+ component.save({"name" => "Test component", "project" => "SAMPLEPROJECT"}).should be_true
58
+ component.id.should == "10001"
59
+ component.name.should == "Test component"
60
+ end
61
+
62
+ it "saves an existing component" do
63
+ component = client.Component.build('id' => '10000')
64
+ component.fetch
65
+ component.save('name' => 'Jammy').should be_true
66
+ component.id.should == "10000"
67
+ component.name.should == "Jammy"
68
+ end
69
+
70
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jira::Resource::Issue do
4
+
5
+ let(:client) do
6
+ client = Jira::Client.new('foo', 'bar')
7
+ client.set_access_token('abc', '123')
8
+ client
9
+ end
10
+
11
+ let(:expected_attributes) do
12
+ {
13
+ 'self' => "http://localhost:2990/jira/rest/api/2/issue/10002",
14
+ 'key' => "SAMPLEPROJECT-1",
15
+ 'expand' => "renderedFields,names,schema,transitions,editmeta,changelog"
16
+ }
17
+ end
18
+
19
+ before(:each) do
20
+ stub_request(:get,
21
+ "http://localhost:2990/jira/rest/api/2/issue/10002").
22
+ to_return(:body => get_mock_response('issue/10002.json'))
23
+ stub_request(:delete,
24
+ "http://localhost:2990/jira/rest/api/2/issue/10002").
25
+ to_return(:body => nil)
26
+ stub_request(:post, "http://localhost:2990/jira/rest/api/2/issue").
27
+ with(:body => '{"foo":"bar"}').
28
+ to_return(:body => get_mock_response('issue.post.json'))
29
+ stub_request(:put, "http://localhost:2990/jira/rest/api/2/issue/10002").
30
+ with(:body => '{"foo":"bar"}').
31
+ to_return(:body => nil)
32
+ stub_request(:get,
33
+ "http://localhost:2990/jira/rest/api/2/issue/99999").
34
+ to_return(:status => 404, :body => '{"errorMessages":["Issue Does Not Exist"],"errors": {}}')
35
+ end
36
+
37
+ it "should get a single issue by key" do
38
+ issue = client.Issue.find('10002')
39
+
40
+ issue.should have_attributes(expected_attributes)
41
+ end
42
+
43
+ it "should handle issue not found" do
44
+ lambda do
45
+ issue = client.Issue.find('99999')
46
+ end.should raise_exception(Jira::Resource::HTTPError)
47
+ end
48
+
49
+ it "builds and fetches single issue" do
50
+ issue = client.Issue.build('id' => '10002')
51
+ issue.fetch
52
+
53
+ issue.should have_attributes(expected_attributes)
54
+ end
55
+
56
+ it "deletes an issue" do
57
+ issue = client.Issue.build('id' => "10002")
58
+ issue.delete.should be_true
59
+ end
60
+
61
+ it "should save a new record" do
62
+ subject = described_class.new(client)
63
+ subject.save('foo' => 'bar').should be_true
64
+ end
65
+
66
+ it "should save an existing record" do
67
+ subject = client.Issue.build('id' => '10002')
68
+ subject.fetch
69
+ subject.save('foo' => 'bar').should be_true
70
+ end
71
+
72
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jira::Resource::Project do
4
+
5
+ let(:client) do
6
+ client = Jira::Client.new('foo', 'bar')
7
+ client.set_access_token('abc', '123')
8
+ client
9
+ end
10
+
11
+ let(:expected_attributes) do
12
+ {
13
+ 'self' => "http://localhost:2990/jira/rest/api/2/project/SAMPLEPROJECT",
14
+ 'key' => "SAMPLEPROJECT",
15
+ 'name' => "Sample Project for Developing RoR RESTful API"
16
+ }
17
+ end
18
+
19
+ before(:each) do
20
+ stub_request(:get,
21
+ "http://localhost:2990/jira/rest/api/2/project").
22
+ to_return(:body => get_mock_response('project.json'))
23
+ stub_request(:get,
24
+ "http://localhost:2990/jira/rest/api/2/project/SAMPLEPROJECT").
25
+ to_return(:body => get_mock_response('project/SAMPLEPROJECT.json'))
26
+ end
27
+
28
+ it "should get all the projects" do
29
+ projects = client.Project.all
30
+ projects.length.should == 1
31
+
32
+ first = projects.first
33
+ first.should have_attributes(expected_attributes)
34
+ end
35
+
36
+ it "should get a single project by key" do
37
+ project = client.Project.find('SAMPLEPROJECT')
38
+
39
+ project.should have_attributes(expected_attributes)
40
+ end
41
+
42
+ it "builds and fetches single project" do
43
+ project = client.Project.build('key' => 'SAMPLEPROJECT')
44
+ project.fetch
45
+
46
+ project.should have_attributes(expected_attributes)
47
+ end
48
+ end
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jira::Client do
4
+
5
+ subject {Jira::Client.new('foo','bar')}
6
+
7
+ let(:response) do
8
+ response = mock("response")
9
+ response.stub(:kind_of?).with(Net::HTTPSuccess).and_return(true)
10
+ response
11
+ end
12
+
13
+ it "creates an instance" do
14
+ subject.class.should == Jira::Client
15
+ end
16
+
17
+ it "sets consumer key" do
18
+ subject.key.should == 'foo'
19
+ end
20
+
21
+ it "sets consumer secret" do
22
+ subject.secret.should == 'bar'
23
+ end
24
+
25
+ it "sets the default options" do
26
+ Jira::Client::DEFAULT_OPTIONS.each do |key, value|
27
+ subject.options[key].should == value
28
+ end
29
+ end
30
+
31
+ it "allows the overriding of some options" do
32
+ # Check it overrides a given option ...
33
+ client = Jira::Client.new('foo', 'bar', :site => 'http://foo.com/')
34
+ client.options[:site].should == 'http://foo.com/'
35
+
36
+ # ... but leaves the rest intact
37
+ Jira::Client::DEFAULT_OPTIONS.keys.reject do |key|
38
+ key == :site
39
+ end.each do |key|
40
+ client.options[key].should == Jira::Client::DEFAULT_OPTIONS[key]
41
+ end
42
+
43
+ Jira::Client::DEFAULT_OPTIONS[:site].should_not == 'http://foo.com/'
44
+ end
45
+
46
+ # To avoid having to validate options after initialisation, e.g. setting
47
+ # client.options[:invalid] = 'foo'
48
+ it "freezes the options" do
49
+ subject.options.should be_frozen
50
+ end
51
+
52
+ it "creates a Oauth::Consumer on initialize" do
53
+ subject.consumer.class.should == OAuth::Consumer
54
+ subject.consumer.key.should == subject.key
55
+ subject.consumer.secret.should == subject.secret
56
+ end
57
+
58
+ it "returns an OAuth request_token" do
59
+ # Cannot just check for method delegation as http connection will be attempted
60
+ request_token = OAuth::RequestToken.new(subject.consumer)
61
+ subject.consumer.stub(:get_request_token => request_token)
62
+ subject.get_request_token.should == request_token
63
+ end
64
+
65
+ it "is possible to set the request token" do
66
+ token = mock()
67
+ OAuth::RequestToken.should_receive(:new).with(subject.consumer, 'foo', 'bar').and_return(token)
68
+
69
+ request_token = subject.set_request_token('foo', 'bar')
70
+
71
+ request_token.should == token
72
+ subject.request_token.should == token
73
+ end
74
+
75
+ describe "access token" do
76
+
77
+ it "initializes the access token" do
78
+ request_token = OAuth::RequestToken.new(subject.consumer)
79
+ subject.consumer.stub(:get_request_token => request_token)
80
+ mock_access_token = mock()
81
+ request_token.should_receive(:get_access_token).with(:oauth_verifier => 'abc123').and_return(mock_access_token)
82
+ subject.init_access_token(:oauth_verifier => 'abc123')
83
+ subject.access_token.should == mock_access_token
84
+ end
85
+
86
+ it "raises an exception when accessing without initialisation" do
87
+ lambda do
88
+ subject.access_token
89
+ end.should raise_exception(Jira::Client::UninitializedAccessTokenError, "init_access_token must be called before using the client")
90
+ end
91
+
92
+ it "is possible to set the access token" do
93
+ token = mock()
94
+ OAuth::AccessToken.should_receive(:new).with(subject.consumer, 'foo', 'bar').and_return(token)
95
+
96
+ access_token = subject.set_access_token('foo', 'bar')
97
+
98
+ access_token.should == token
99
+ subject.access_token.should == token
100
+ end
101
+
102
+ end
103
+
104
+ describe "http" do
105
+
106
+ it "responds to the http methods" do
107
+ mock_access_token = mock()
108
+ subject.stub(:access_token => mock_access_token)
109
+ [:delete, :get, :head].each do |method|
110
+ mock_access_token.should_receive(:request).with(method, '/path', {'Accept' => 'application/json'}).and_return(response)
111
+ subject.send(method, '/path')
112
+ end
113
+ [:post, :put].each do |method|
114
+ mock_access_token.should_receive(:request).with(method,
115
+ '/path', '',
116
+ {'Accept' => 'application/json', 'Content-Type' => 'application/json'}).and_return(response)
117
+ subject.send(method, '/path')
118
+ end
119
+ end
120
+
121
+ it "performs a request" do
122
+ access_token = mock()
123
+ access_token.should_receive(:request).with(:get, '/foo').and_return(response)
124
+ subject.stub(:access_token => access_token)
125
+ subject.request(:get, '/foo')
126
+ end
127
+
128
+ it "raises an exception for non success responses" do
129
+ response = mock()
130
+ response.stub(:kind_of?).with(Net::HTTPSuccess).and_return(false)
131
+ access_token = mock()
132
+ access_token.should_receive(:request).with(:get, '/foo').and_return(response)
133
+ subject.stub(:access_token => access_token)
134
+
135
+ lambda do
136
+ subject.request(:get, '/foo')
137
+ end.should raise_exception(Jira::Resource::HTTPError)
138
+ end
139
+
140
+ end
141
+
142
+ describe "Resource Factories" do
143
+
144
+ it "gets all projects" do
145
+ Jira::Resource::Project.should_receive(:all).with(subject).and_return([])
146
+ subject.Project.all.should == []
147
+ end
148
+
149
+ it "finds a single project" do
150
+ find_result = mock()
151
+ Jira::Resource::Project.should_receive(:find).with(subject, '123').and_return(find_result)
152
+ subject.Project.find('123').should == find_result
153
+ end
154
+
155
+ end
156
+
157
+ end