jira_client 1.0.0

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.
Files changed (67) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/jira_client.gemspec +27 -0
  8. data/lib/jira_client.rb +121 -0
  9. data/lib/jira_client/api/comments.rb +19 -0
  10. data/lib/jira_client/api/issues.rb +62 -0
  11. data/lib/jira_client/api/projects.rb +19 -0
  12. data/lib/jira_client/api/server.rb +15 -0
  13. data/lib/jira_client/api/statuses.rb +20 -0
  14. data/lib/jira_client/api/users.rb +18 -0
  15. data/lib/jira_client/api/utils.rb +25 -0
  16. data/lib/jira_client/api/worklogs.rb +26 -0
  17. data/lib/jira_client/base.rb +54 -0
  18. data/lib/jira_client/comment.rb +12 -0
  19. data/lib/jira_client/configuration.rb +27 -0
  20. data/lib/jira_client/core_ext/string.rb +7 -0
  21. data/lib/jira_client/error/bad_request.rb +5 -0
  22. data/lib/jira_client/error/configuration_error.rb +5 -0
  23. data/lib/jira_client/error/issue_error.rb +5 -0
  24. data/lib/jira_client/error/resource_not_found.rb +5 -0
  25. data/lib/jira_client/error/unauthorized.rb +5 -0
  26. data/lib/jira_client/issue.rb +26 -0
  27. data/lib/jira_client/project.rb +5 -0
  28. data/lib/jira_client/server_info.rb +11 -0
  29. data/lib/jira_client/status.rb +7 -0
  30. data/lib/jira_client/timetracking.rb +6 -0
  31. data/lib/jira_client/user.rb +10 -0
  32. data/lib/jira_client/version.rb +3 -0
  33. data/lib/jira_client/worklog.rb +10 -0
  34. data/spec/fixtures/admin.json +17 -0
  35. data/spec/fixtures/basic_issue.json +6 -0
  36. data/spec/fixtures/comment.json +23 -0
  37. data/spec/fixtures/comments.json +30 -0
  38. data/spec/fixtures/invalid_assignee.json +6 -0
  39. data/spec/fixtures/invalid_comment.json +6 -0
  40. data/spec/fixtures/invalid_jql.json +6 -0
  41. data/spec/fixtures/issue_with_comments.json +33 -0
  42. data/spec/fixtures/issue_with_description.json +10 -0
  43. data/spec/fixtures/issue_with_status.json +15 -0
  44. data/spec/fixtures/issue_with_timetracking.json +16 -0
  45. data/spec/fixtures/issue_with_worklogs.json +34 -0
  46. data/spec/fixtures/issues.json +28 -0
  47. data/spec/fixtures/my_certificate.pem +52 -0
  48. data/spec/fixtures/no_issues_found.json +6 -0
  49. data/spec/fixtures/project.json +10 -0
  50. data/spec/fixtures/projects.json +22 -0
  51. data/spec/fixtures/server_info.json +14 -0
  52. data/spec/fixtures/status.json +7 -0
  53. data/spec/fixtures/statuses.json +16 -0
  54. data/spec/fixtures/user_doesnt_exist.json +6 -0
  55. data/spec/fixtures/users.json +22 -0
  56. data/spec/fixtures/worklog.json +31 -0
  57. data/spec/jira_client/api/comments_spec.rb +59 -0
  58. data/spec/jira_client/api/issues_spec.rb +314 -0
  59. data/spec/jira_client/api/projects_spec.rb +55 -0
  60. data/spec/jira_client/api/server_spec.rb +31 -0
  61. data/spec/jira_client/api/statuses_spec.rb +69 -0
  62. data/spec/jira_client/api/users_spec.rb +56 -0
  63. data/spec/jira_client/api/worklogs_spec.rb +86 -0
  64. data/spec/jira_client/configuration_spec.rb +78 -0
  65. data/spec/jira_client_spec.rb +49 -0
  66. data/spec/spec_helper.rb +56 -0
  67. metadata +226 -0
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+
3
+ describe JiraClient::API::Projects do
4
+
5
+ describe "#find_projects" do
6
+
7
+ before do
8
+ stub_get("/project").to_return(:body => fixture("projects.json"), :headers => {:content_type => "application/json; charset=utf-8"})
9
+ end
10
+
11
+ it "requests the correct resource" do
12
+ JiraClient.find_projects
13
+ expect(a_get("/project")).to have_been_made
14
+ end
15
+ it "returns an array of JiraClient::Project objects" do
16
+ projects = JiraClient.find_projects
17
+ projects.should be_a_kind_of Array
18
+ projects.each do |project|
19
+ project.should be_a_kind_of JiraClient::Project
20
+ end
21
+ end
22
+ it "assigns the correct information" do
23
+ projects = JiraClient.find_projects
24
+ projects.first.name.should == "Example"
25
+ projects.first.key.should == "EX"
26
+ projects.last.name.should == "Alphabetical"
27
+ projects.last.key.should == "ABC"
28
+ end
29
+ end
30
+
31
+ describe "#find_project_by_key" do
32
+
33
+ before do
34
+ stub_get("/project/ABC").to_return(:body => fixture("project.json"), :headers => {:content_type => "application/json; charset=utf-8"})
35
+ end
36
+
37
+ it "requests the correct resource" do
38
+ JiraClient.find_project_by_key(:ABC)
39
+ expect(a_get('/project/ABC')).to have_been_made
40
+ end
41
+ it "returns a JiraClient::Project object" do
42
+ project = JiraClient.find_project_by_key :ABC
43
+ project.should be_a_kind_of JiraClient::Project
44
+ end
45
+ it "accepts a key as a string" do
46
+ project = JiraClient.find_project_by_key "ABC"
47
+ project.should be_a_kind_of JiraClient::Project
48
+ end
49
+ it "accepts a key as a symbol" do
50
+ project = JiraClient.find_project_by_key :ABC
51
+ project.should be_a_kind_of JiraClient::Project
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+
3
+ describe JiraClient::API::Server do
4
+
5
+ before do
6
+ stub_get("/serverInfo").to_return(:body => fixture("server_info.json"), :headers => {:content_type => "application/json; charset=utf-8"})
7
+ end
8
+
9
+ describe "#info" do
10
+
11
+ before do
12
+ @info = JiraClient.server_info
13
+ end
14
+
15
+ it "requests the correct resource" do
16
+ expect(a_get("/serverInfo")).to have_been_made
17
+ end
18
+ it "returns a JiraClient::ServerInfo object" do
19
+ expect(@info).to be_a_kind_of JiraClient::ServerInfo
20
+ end
21
+ it "sets the correct attributes" do
22
+ expect(@info.version).to eq("5.1.8")
23
+ expect(@info.base_url).to eq("https://example.jira.com")
24
+ expect(@info.build_number).to eq(787)
25
+ expect(@info.build_date).to eq(Time.parse("2012-10-29T00:00:00.000+0000"))
26
+ expect(@info.server_time).to eq(Time.parse("2013-04-24T22:01:45.802+0100"))
27
+ expect(@info.server_title).to eq("Example JIRA")
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,69 @@
1
+ require "spec_helper"
2
+
3
+ describe JiraClient::API::Statuses do
4
+
5
+ describe "#find_statuses" do
6
+
7
+ before do
8
+ stub_get("/status").to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
9
+ end
10
+
11
+ it "requests the correct resource" do
12
+ JiraClient.find_statuses
13
+ expect(a_get('/status')).to have_been_made
14
+ end
15
+ it "returns an array of JiraClient::Status objects" do
16
+ statuses = JiraClient.find_statuses
17
+ statuses.should be_a_kind_of Array
18
+ statuses.each do |status|
19
+ status.should be_a_kind_of JiraClient::Status
20
+ end
21
+ end
22
+ it "assigns the correct information" do
23
+ statuses = JiraClient.find_statuses
24
+ statuses.first.name.should == "In Progress"
25
+ statuses.first.description.should == "The issue is currently being worked on."
26
+ statuses.last.name.should == "Closed"
27
+ statuses.last.description.should == "The issue is closed."
28
+ end
29
+ end
30
+
31
+ describe "#find_status_by_id" do
32
+
33
+ before do
34
+ stub_get("/status/10000").to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
35
+ @status = JiraClient.find_status_by_id 10000
36
+ end
37
+
38
+ it "requests the correct resource" do
39
+ expect(a_get("/status/10000")).to have_been_made
40
+ end
41
+ it "returns a JiraClient::Status object" do
42
+ @status.should be_a_kind_of JiraClient::Status
43
+ end
44
+ it "assigns the correct information" do
45
+ @status.name.should == "In Progress"
46
+ @status.id.should == "10000"
47
+ end
48
+ end
49
+
50
+ describe "#find_status_by_name" do
51
+
52
+ before do
53
+ stub_get("/status/In%20Progress").to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
54
+ @status = JiraClient.find_status_by_name "In Progress"
55
+ end
56
+
57
+ it "requests the correct resource" do
58
+ expect(a_get("/status/In Progress")).to have_been_made
59
+ end
60
+ it "returns a JiraClient::Status object" do
61
+ @status.should be_a_kind_of JiraClient::Status
62
+ end
63
+ it "assigns the correct information" do
64
+ @status.name.should == "In Progress"
65
+ @status.id.should == "10000"
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+
3
+ describe JiraClient::API::Users do
4
+
5
+ describe "#find_user_by_username" do
6
+
7
+ before do
8
+ stub_get("/user?username=admin").to_return(:body => fixture("admin.json"))
9
+ @user = JiraClient.find_user_by_username "admin"
10
+ end
11
+
12
+ it "requests the correct resource" do
13
+ expect(a_get("/user?username=admin")).to have_been_made
14
+ end
15
+ it "returns a JiraClient::User object" do
16
+ @user.should be_a_kind_of JiraClient::User
17
+ end
18
+ it "sets the correct attributes" do
19
+ @user.display_name.should == "admin"
20
+ @user.should be_active
21
+ @user.email_address.should == "admin@example.com"
22
+ end
23
+
24
+ describe "when the user can't be found" do
25
+
26
+ before do
27
+ stub_get("/user?username=doesnt_exist").to_return(:status => 404, :body => fixture("user_doesnt_exist.json"))
28
+ end
29
+
30
+ it "raises a not found error" do
31
+ expect { JiraClient.find_user_by_username("doesnt_exist") }.to raise_error(JiraClient::Error::ResourceNotFound)
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "#find_users" do
37
+
38
+ before do
39
+ stub_get("/user/search?username=test").to_return(:status => 200, :body => fixture("users.json"))
40
+ @users = JiraClient.find_users("test")
41
+ end
42
+
43
+ it "requests the correct resource" do
44
+ expect(a_get("/user/search?username=test")).to have_been_made
45
+ end
46
+ it "returns the correct number of results" do
47
+ @users.size.should == 2
48
+ end
49
+ it "returns user objects" do
50
+ @users.each do |user|
51
+ user.should be_a_kind_of JiraClient::User
52
+ end
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,86 @@
1
+ require "spec_helper"
2
+
3
+ describe JiraClient::API::Worklogs do
4
+
5
+ describe "#create_worklog" do
6
+
7
+ before do
8
+ stub_post("/issue/PROJECT-1234/worklog").to_return(:status => 201)
9
+ end
10
+
11
+ it "requests the correct resource" do
12
+ JiraClient.create_worklog("PROJECT-1234", "30m")
13
+ expect(a_post("/issue/PROJECT-1234/worklog")).to have_been_made
14
+ end
15
+
16
+ describe "Parsing duration strings" do
17
+ it "understands 30m" do
18
+ JiraClient.create_worklog("PROJECT-1234", "30m")
19
+ expect(a_post("/issue/PROJECT-1234/worklog").with(:body => {:timeSpentSeconds => 1800})).to have_been_made
20
+ end
21
+ it "understands 1h30m" do
22
+ JiraClient.create_worklog("PROJECT-1234", "1h30m")
23
+ expect(a_post("/issue/PROJECT-1234/worklog").with(:body => {:timeSpentSeconds => 5400})).to have_been_made
24
+ end
25
+ it "understands 1.5h" do
26
+ JiraClient.create_worklog("PROJECT-1234", "1.5h")
27
+ expect(a_post("/issue/PROJECT-1234/worklog").with(:body => {:timeSpentSeconds => 5400})).to have_been_made
28
+ end
29
+ end
30
+
31
+ describe "Adjusting estimates" do
32
+ it "can adjust remaining estimate to a specified amount" do
33
+ stub_post("/issue/PROJECT-1234/worklog?adjustEstimate=new&newEstimate=1h").to_return(:status => 201)
34
+ JiraClient.create_worklog("PROJECT-1234", "30m", :remaining_estimate => "1h")
35
+ expect(a_post("/issue/PROJECT-1234/worklog?adjustEstimate=new&newEstimate=1h").with(:body => {:timeSpentSeconds => 1800})).to have_been_made
36
+ end
37
+ it "can adjust remaining estimate to zero" do
38
+ stub_post("/issue/PROJECT-1234/worklog?adjustEstimate=new&newEstimate=0").to_return(:status => 201)
39
+ JiraClient.create_worklog("PROJECT-1234", "30m", :remaining_estimate => 0)
40
+ expect(a_post("/issue/PROJECT-1234/worklog?adjustEstimate=new&newEstimate=0")).to have_been_made
41
+ end
42
+ it "can manually reduce the estimate by a specified amount" do
43
+ stub_post("/issue/PROJECT-1234/worklog?adjustEstimate=manual&reduceBy=1h").to_return(:status => 201)
44
+ JiraClient.create_worklog("PROJECT-1234", "30m", :reduce_estimate => "1h")
45
+ expect(a_post("/issue/PROJECT-1234/worklog?adjustEstimate=manual&reduceBy=1h")).to have_been_made
46
+ end
47
+ end
48
+
49
+ describe "Commenting on work logs" do
50
+ it "should be possible" do
51
+ JiraClient.create_worklog("PROJECT-1234", "30m", :comment => "I did some work")
52
+ expect(a_post("/issue/PROJECT-1234/worklog").with(:body => {:timeSpentSeconds => 1800, :comment => "I did some work"})).to have_been_made
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "#find_issue_worklogs" do
58
+
59
+ before do
60
+ stub_get("/issue/PROJECT-1234/worklog").to_return(:body => fixture("worklog.json"))
61
+ @worklogs = JiraClient.find_issue_worklogs("PROJECT-1234")
62
+ @worklog = @worklogs.first
63
+ end
64
+
65
+ it "requests the correct resource" do
66
+ expect(a_get("/issue/PROJECT-1234/worklog")).to have_been_made
67
+ end
68
+ it "returns an array of JiraClient::Worklog objects" do
69
+ @worklogs.should be_a_kind_of Array
70
+ @worklog.should be_a_kind_of JiraClient::Worklog
71
+ end
72
+ it "sets the correct attributes on the JiraClient::Worklog objects" do
73
+ @worklog.time_spent.should == "3h 20m"
74
+ @worklog.started.should == Time.parse("2012-02-15T17:34:37.937-0600")
75
+ @worklog.time_spent_seconds.should == 12000
76
+ @worklog.comment.should == "I did some work here."
77
+ end
78
+ it "parses the author as a JiraClient::User object" do
79
+ @worklog.author.should be_a_kind_of JiraClient::User
80
+ end
81
+ it "parses the update author as a JiraClient::User object" do
82
+ @worklog.update_author.should be_a_kind_of JiraClient::User
83
+ end
84
+ end
85
+
86
+ end
@@ -0,0 +1,78 @@
1
+ require "spec_helper"
2
+
3
+ describe "JiraClient.reset!" do
4
+ it "resets all options to defaults" do
5
+ JiraClient.configure do |config|
6
+ config.base_url = "some_url"
7
+ config.port = 2411
8
+ config.username = "admin"
9
+ config.password = "password"
10
+ end
11
+ JiraClient.reset!
12
+ expect(JiraClient.configuration).to be_nil
13
+ end
14
+ end
15
+
16
+ describe "JiraClient.configure" do
17
+ it "config variables are accessible through the configuration method" do
18
+ JiraClient.configure do |config|
19
+ config.base_url = "https://example.jira.com"
20
+ end
21
+ expect(JiraClient.configuration.base_url).to eq("https://example.jira.com")
22
+ end
23
+ it "raises JiraClient::Error::ConfigurationError when an unknown config option is provided" do
24
+ expect do
25
+ JiraClient.configure do |config|
26
+ config.unknown_config_variable = "not allowed"
27
+ end
28
+ end.to raise_error(JiraClient::Error::ConfigurationError)
29
+ end
30
+
31
+ describe "authentication options" do
32
+ describe "basic authentication" do
33
+ it "accepts a username" do
34
+ expect do
35
+ JiraClient.configure {|c| c.username = "admin"}
36
+ end.not_to raise_error
37
+ end
38
+ it "accepts a password" do
39
+ expect do
40
+ JiraClient.configure {|c| c.password = "admin"}
41
+ end.not_to raise_error
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "JiraClient.configuration" do
48
+ it "raises an error when #configure has not been run" do
49
+ JiraClient.stub(:configuration).and_return(nil)
50
+ expect { JiraClient.find_issue_by_key "TEST-1" }.to raise_error(JiraClient::Error::ConfigurationError)
51
+ end
52
+
53
+ describe "#full_url" do
54
+ it "includes the base_url" do
55
+ JiraClient.configure {|c| c.base_url = "http://localhost"}
56
+ JiraClient.configuration.full_url.should include("http://localhost")
57
+ end
58
+ it "includes the port if specified" do
59
+ JiraClient.configure do |config|
60
+ config.base_url = "http://localhost"
61
+ config.port = 2990
62
+ end
63
+ JiraClient.configuration.full_url.should include(":2990")
64
+ end
65
+ it "includes the default API path" do
66
+ JiraClient.configure {|c| c.base_url = "http://localhost"}
67
+ JiraClient.configuration.full_url.should include ("/rest/api/2")
68
+ end
69
+ it "trims trailing / from the base_url" do
70
+ JiraClient.configure {|c| c.base_url = "http://localhost/"}
71
+ JiraClient.configuration.full_url.should == "http://localhost/rest/api/2"
72
+ end
73
+ it "raises an error if not configured properly" do
74
+ JiraClient.configure {|c| c.base_url = nil}
75
+ expect { JiraClient.configuration.full_url }.to raise_error JiraClient::Error::ConfigurationError
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,49 @@
1
+ require "spec_helper"
2
+
3
+ describe JiraClient do
4
+ describe "proxy server" do
5
+ it "sets the proxy server on RestClient" do
6
+ JiraClient.configure do |config|
7
+ config.proxy = "http://myproxy.com"
8
+ end
9
+ # Build the resource
10
+ JiraClient.send(:resource)
11
+ RestClient.proxy.should == "http://myproxy.com"
12
+ end
13
+ end
14
+ describe "basic authentication" do
15
+
16
+ before do
17
+ @basic_auth_url = JiraClient.configuration.full_url.gsub("https://", "https://admin:admin@") + "/project"
18
+ stub_request(:get, @basic_auth_url).to_return(:body => fixture("projects.json"))
19
+ end
20
+
21
+ it "sends a username/password when provided" do
22
+ JiraClient.configure {|c| c.username = "admin"; c.password = "admin"}
23
+ JiraClient.find_projects
24
+ expect(a_request(:get, @basic_auth_url)).to have_been_made
25
+ end
26
+ end
27
+
28
+ describe "certificate authentication" do
29
+
30
+ before do
31
+ JiraClient.configure do |config|
32
+ config.certificate = fixture("my_certificate.pem")
33
+ config.certificate_passphrase = "password"
34
+ end
35
+ @resource_options = JiraClient.send(:resource).options
36
+ end
37
+
38
+ it "sets ssl_client_cert" do
39
+ @resource_options[:ssl_client_cert].should_not be_nil
40
+ end
41
+ it "sets ssl_client_key" do
42
+ @resource_options[:ssl_client_key].should_not be_nil
43
+ end
44
+ it "sets verify_ssl" do
45
+ @resource_options[:verify_ssl].should_not be_nil
46
+ @resource_options[:verify_ssl].should == OpenSSL::SSL::VERIFY_NONE
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,56 @@
1
+ require "simplecov"
2
+
3
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
4
+ SimpleCov::Formatter::HTMLFormatter
5
+ ]
6
+ SimpleCov.start
7
+
8
+ require "webmock/rspec"
9
+ require "jira_client"
10
+
11
+ RSpec.configure do |config|
12
+ config.treat_symbols_as_metadata_keys_with_true_values = true
13
+ config.run_all_when_everything_filtered = true
14
+ config.filter_run :focus
15
+ config.order = 'random'
16
+ config.before(:each) do
17
+ JiraClient.configure do |c|
18
+ c.base_url = "https://example.jira.com"
19
+ end
20
+ end
21
+ config.after(:each) do
22
+ JiraClient.reset!
23
+ end
24
+ end
25
+
26
+ def a_get(path)
27
+ a_request(:get, JiraClient.configuration.full_url + path)
28
+ end
29
+
30
+ def a_post(path)
31
+ a_request(:post, JiraClient.configuration.full_url + path)
32
+ end
33
+
34
+ def a_put(path)
35
+ a_request(:put, JiraClient.configuration.full_url + path)
36
+ end
37
+
38
+ def stub_get(path)
39
+ stub_request(:get, JiraClient.configuration.full_url + path)
40
+ end
41
+
42
+ def stub_post(path)
43
+ stub_request(:post, JiraClient.configuration.full_url + path)
44
+ end
45
+
46
+ def stub_put(path)
47
+ stub_request(:put, JiraClient.configuration.full_url + path)
48
+ end
49
+
50
+ def fixture(file)
51
+ File.new(fixture_path + '/' + file)
52
+ end
53
+
54
+ def fixture_path
55
+ File.expand_path("../fixtures", __FILE__)
56
+ end