jigit 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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.gitignore +60 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +117 -0
  6. data/.travis.yml +20 -0
  7. data/CHANGELOG.md +5 -0
  8. data/Dangerfile +22 -0
  9. data/Gemfile +7 -0
  10. data/Gemfile.lock +138 -0
  11. data/LICENSE +21 -0
  12. data/README.md +66 -0
  13. data/Rakefile +32 -0
  14. data/bin/jigit +5 -0
  15. data/jigit.gemspec +35 -0
  16. data/lib/jigit.rb +12 -0
  17. data/lib/jigit/commands/init.rb +309 -0
  18. data/lib/jigit/commands/issue.rb +56 -0
  19. data/lib/jigit/commands/runner.rb +22 -0
  20. data/lib/jigit/commands/start_issue.rb +58 -0
  21. data/lib/jigit/commands/stop_issue.rb +53 -0
  22. data/lib/jigit/core/jigitfile.rb +31 -0
  23. data/lib/jigit/core/jigitfile_constants.rb +15 -0
  24. data/lib/jigit/core/jigitfile_generator.rb +34 -0
  25. data/lib/jigit/git/git_hook.rb +11 -0
  26. data/lib/jigit/git/git_hook_installer.rb +60 -0
  27. data/lib/jigit/git/git_ignore_updater.rb +20 -0
  28. data/lib/jigit/git/post_checkout_hook.rb +23 -0
  29. data/lib/jigit/helpers/informator.rb +131 -0
  30. data/lib/jigit/helpers/keychain_storage.rb +19 -0
  31. data/lib/jigit/jira/jira_api_client.rb +80 -0
  32. data/lib/jigit/jira/jira_api_client_error.rb +10 -0
  33. data/lib/jigit/jira/jira_config.rb +16 -0
  34. data/lib/jigit/jira/jira_transition_finder.rb +16 -0
  35. data/lib/jigit/jira/resources/jira_issue.rb +34 -0
  36. data/lib/jigit/jira/resources/jira_status.rb +18 -0
  37. data/lib/jigit/jira/resources/jira_transition.rb +18 -0
  38. data/lib/jigit/version.rb +4 -0
  39. data/spec/fixtures/jigitfile_invalid.yaml +2 -0
  40. data/spec/fixtures/jigitfile_valid.yaml +5 -0
  41. data/spec/lib/integration/jigit/core/jigitfile_generator_spec.rb +27 -0
  42. data/spec/lib/integration/jigit/core/keychain_storage_spec.rb +35 -0
  43. data/spec/lib/integration/jigit/git/git_hook_installer_spec.rb +66 -0
  44. data/spec/lib/integration/jigit/git/git_ignore_updater_spec.rb +45 -0
  45. data/spec/lib/integration/jigit/jira/jira_api_client_spec.rb +154 -0
  46. data/spec/lib/unit/jigit/core/jigitfile_spec.rb +33 -0
  47. data/spec/lib/unit/jigit/git/post_checkout_hook_spec.rb +22 -0
  48. data/spec/lib/unit/jigit/git_hooks/post_checkout_hook_spec.rb +22 -0
  49. data/spec/lib/unit/jigit/jira/jira_config_spec.rb +23 -0
  50. data/spec/lib/unit/jigit/jira/jira_issue_spec.rb +101 -0
  51. data/spec/lib/unit/jigit/jira/jira_status_spec.rb +62 -0
  52. data/spec/lib/unit/jigit/jira/jira_transition_finder_spec.rb +70 -0
  53. data/spec/lib/unit/jigit/jira/jira_transition_spec.rb +64 -0
  54. data/spec/mock_responses/issue.json +1108 -0
  55. data/spec/mock_responses/issue_1002_transitions.json +49 -0
  56. data/spec/mock_responses/statuses.json +37 -0
  57. data/spec/spec_helper.rb +17 -0
  58. data/tasks/generate_jira_localhost.rake +20 -0
  59. metadata +293 -0
@@ -0,0 +1,19 @@
1
+ require "keychain"
2
+
3
+ module Jigit
4
+ class KeychainStorage
5
+ def initialize(keychain = nil)
6
+ @keychain = keychain ? keychain : Keychain.default
7
+ end
8
+
9
+ def save(account, password, service)
10
+ @keychain.generic_passwords.create(service: service, account: account, password: password)
11
+ rescue Keychain::DuplicateItemError => e
12
+ puts "Duplicated item in keychain storage: #{e.message}"
13
+ end
14
+
15
+ def load_item(service)
16
+ @keychain.generic_passwords.where(service: service).first
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,80 @@
1
+ require "jira-ruby"
2
+ require "jigit/jira/resources/jira_issue"
3
+ require "jigit/jira/resources/jira_status"
4
+ require "jigit/jira/resources/jira_transition"
5
+ require "jigit/jira/jira_api_client_error"
6
+
7
+ module Jigit
8
+ class JiraAPIClient
9
+ def initialize(config, jira_client = nil)
10
+ raise "Config must not be nil to use JiraHelper" unless config
11
+ @config = config
12
+ @jira_client = jira_client
13
+ end
14
+
15
+ def jira_client
16
+ return @jira_client if @jira_client
17
+ options = {
18
+ username: @config.user,
19
+ password: @config.password,
20
+ site: "https://#{@config.host}",
21
+ context_path: "",
22
+ auth_type: :basic
23
+ }
24
+ @jira_client ||= JIRA::Client.new(options)
25
+ end
26
+
27
+ def validate_api?
28
+ serverinfo = jira_client.ServerInfo.all
29
+ return !serverinfo.nil?
30
+ rescue SocketError => exception
31
+ raise Jigit::NetworkError, "Can not fetch Jira server info: #{exception.message}"
32
+ rescue JIRA::HTTPError => exception
33
+ raise Jigit::JiraAPIClientError, "Can not fetch Jira server info: #{exception.message}"
34
+ end
35
+
36
+ def fetch_issue_transitions(issue)
37
+ raise "Can not fetch a JIRA issue's transitions without issue name" unless issue.jira_ruby_issue
38
+ begin
39
+ transitions = jira_client.Transition.all(issue: issue.jira_ruby_issue)
40
+ return nil unless transitions
41
+ transitions.map do |transition|
42
+ Jigit::JiraTransition.new(transition)
43
+ end
44
+ rescue SocketError => exception
45
+ raise Jigit::NetworkError, "Can not fetch JIRA issue transitions: #{exception.message}"
46
+ rescue JIRA::HTTPError => exception
47
+ raise Jigit::JiraAPIClientError, "Can not fetch JIRA issue transitions: #{exception.response.body}"
48
+ end
49
+ end
50
+
51
+ def fetch_jira_issue(issue_name)
52
+ raise "Can not fetch a JIRA issue without issue name" unless issue_name
53
+ begin
54
+ issue = jira_client.Issue.jql("key = #{issue_name}").first
55
+ return nil unless issue
56
+ Jigit::JiraIssue.new(issue)
57
+ rescue SocketError => exception
58
+ raise Jigit::NetworkError, "Can not fetch a JIRA issue: #{exception.message}"
59
+ rescue JIRA::HTTPError => exception
60
+ error = case exception.response.code
61
+ when "400" then Jigit::JiraInvalidIssueKeyError
62
+ else Jigit::JiraAPIClientError
63
+ end
64
+ raise error, "Can not fetch a JIRA issue: #{exception.response.body}"
65
+ end
66
+ end
67
+
68
+ def fetch_jira_statuses
69
+ statuses = jira_client.Status.all
70
+ return nil unless statuses
71
+ statuses.map do |status|
72
+ Jigit::JiraStatus.new(status)
73
+ end
74
+ rescue SocketError => exception
75
+ raise Jigit::NetworkError, "Can not fetch a JIRA statuses: #{exception.message}"
76
+ rescue JIRA::HTTPError => exception
77
+ raise Jigit::JiraAPIClientError, "Can not fetch a JIRA statuses: #{exception.response.body}"
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,10 @@
1
+ module Jigit
2
+ class JiraAPIClientError < StandardError
3
+ end
4
+
5
+ class NetworkError < StandardError
6
+ end
7
+
8
+ class JiraInvalidIssueKeyError < StandardError
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ module Jigit
2
+ class JiraConfig
3
+ attr_accessor :user
4
+ attr_accessor :password
5
+ attr_accessor :host
6
+
7
+ def initialize(user, password, host)
8
+ raise "User name must not be nil" unless user
9
+ raise "Password must not be nil" unless password
10
+ raise "Host must not be nil" unless host
11
+ self.user = user
12
+ self.password = password
13
+ self.host = host
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require "jigit/jira/resources/jira_transition"
2
+
3
+ module Jigit
4
+ class JiraTransitionFinder
5
+ def initialize(transitions)
6
+ @transitions = transitions
7
+ end
8
+
9
+ def find_transition_to(status_name)
10
+ return nil unless @transitions
11
+ @transitions.select do |transition|
12
+ transition.to_status.name == status_name
13
+ end.first
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ require "jigit/jira/resources/jira_status"
2
+ require "jigit/jira/resources/jira_transition"
3
+
4
+ module Jigit
5
+ class JiraIssue
6
+ attr_reader :jira_ruby_issue
7
+
8
+ def initialize(jira_ruby_issue)
9
+ raise "Can not initialize JiraIssue without jira-ruby issue" unless jira_ruby_issue
10
+ @jira_ruby_issue = jira_ruby_issue
11
+ end
12
+
13
+ def key
14
+ @jira_ruby_issue.key
15
+ end
16
+
17
+ def status
18
+ Jigit::JiraStatus.new(@jira_ruby_issue.status)
19
+ end
20
+
21
+ def assignee_name
22
+ @jira_ruby_issue.assignee.name
23
+ end
24
+
25
+ def type
26
+ end
27
+
28
+ def make_transition(transition_id)
29
+ raise "status_id must not be nil" unless transition_id
30
+ transition = @jira_ruby_issue.transitions.build
31
+ transition.save!("transition" => { "id" => transition_id })
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ module Jigit
2
+ class JiraStatus
3
+ attr_reader :jira_ruby_status
4
+
5
+ def initialize(jira_ruby_status)
6
+ raise "Can not initialize JiraStatus without jira-ruby status" unless jira_ruby_status
7
+ @jira_ruby_status = jira_ruby_status
8
+ end
9
+
10
+ def id
11
+ @jira_ruby_status.id
12
+ end
13
+
14
+ def name
15
+ @jira_ruby_status.name
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Jigit
2
+ class JiraTransition
3
+ attr_reader :jira_ruby_transition
4
+
5
+ def initialize(jira_ruby_transition)
6
+ raise "Can not initialize transition without jira-ruby transition" unless jira_ruby_transition
7
+ @jira_ruby_transition = jira_ruby_transition
8
+ end
9
+
10
+ def id
11
+ @jira_ruby_transition.id
12
+ end
13
+
14
+ def to_status
15
+ Jigit::JiraStatus.new(@jira_ruby_transition.to)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ module Jigit
2
+ VERSION = "1.0.0".freeze
3
+ DESCRIPTION = "Keep you JIRA issue statuses in sync with what you're doing actually.".freeze
4
+ end
@@ -0,0 +1,2 @@
1
+ localizations_repo: 'bla_bla_bla'
2
+ localizations fake
@@ -0,0 +1,5 @@
1
+ in_progress_status: "In Progress"
2
+ other_statuses:
3
+ - "To Do"
4
+ - "In Review"
5
+ host: "myhost.atlassian.net"
@@ -0,0 +1,27 @@
1
+ require "jigit/core/jigitfile_generator"
2
+ require "fileutils"
3
+
4
+ describe Jigit::JigitfileGenerator do
5
+ after(:each) do
6
+ FileUtils.rm_rf("spec/fixtures/Jigitfile.yml")
7
+ end
8
+
9
+ describe(".save") do
10
+ before(:each) do
11
+ generator = Jigit::JigitfileGenerator.new("spec/fixtures/")
12
+ generator.write_in_progress_status_name("In Progress")
13
+ generator.write_other_statuses(["To Do", "In Review", "Done"])
14
+ generator.write_jira_host("myhost.atlassian.net")
15
+ generator.save
16
+ end
17
+
18
+ it("writes prepopulated hash into yaml file") do
19
+ expected_lines = ["---\n", "in_progress_status: In Progress\n", "other_statuses:\n", "- To Do\n", "- In Review\n", "- Done\n", "host: myhost.atlassian.net\n"]
20
+ actual_lines = []
21
+ File.foreach("spec/fixtures/Jigitfile.yml") do |line|
22
+ actual_lines << line
23
+ end
24
+ expect(expected_lines).to be == actual_lines
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ require "jigit/helpers/keychain_storage"
2
+
3
+ describe Jigit::KeychainStorage do
4
+ before(:each) do
5
+ @keychain = Keychain.create(File.join(Dir.tmpdir, "keychain_storage_spec_#{Time.now.to_i}_#{Time.now.usec}_#{rand(1000)}.keychain"), "pass")
6
+ end
7
+
8
+ after(:each) do
9
+ @keychain.delete
10
+ end
11
+
12
+ describe "keychain" do
13
+ let(:service) { "myhost" }
14
+ let(:account) { "admin" }
15
+ let(:password) { "123456" }
16
+ let(:keychain_storage) { Jigit::KeychainStorage.new(@keychain) }
17
+
18
+ context("when stores a new item") do
19
+ it "makes the stored item be available to load" do
20
+ keychain_storage.save(account, password, service)
21
+ item = keychain_storage.load_item(service)
22
+ expect(item.password).to be == password
23
+ expect(item.account).to be == account
24
+ expect(item.service).to be == service
25
+ end
26
+ end
27
+
28
+ context("when stores a duplicated item") do
29
+ it "doesn't raise an exception" do
30
+ keychain_storage.save(account, password, service)
31
+ expect { keychain_storage.save(account, password, service) }.to_not raise_error
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,66 @@
1
+ require "jigit/git/git_hook_installer"
2
+ require "jigit/git/git_hook"
3
+ require "fileutils"
4
+
5
+ describe Jigit::GitHookInstaller do
6
+ describe(".install") do
7
+ after(:each) do
8
+ FileUtils.rm_rf("spec/fixtures/git_hook_installer")
9
+ end
10
+
11
+ context("when there is already git hook file") do
12
+ before(:each) do
13
+ FileUtils.mkdir_p("spec/fixtures/git_hook_installer/.git/hooks")
14
+ FileUtils.touch("spec/fixtures/git_hook_installer/.git/hooks/my_hook")
15
+ FileUtils.chmod("u=xwr", "spec/fixtures/git_hook_installer/.git/hooks/my_hook")
16
+ File.open("spec/fixtures/git_hook_installer/.git/hooks/my_hook", "r+") do |f|
17
+ f.puts("First line")
18
+ end
19
+
20
+ git_hook = double(Jigit::GitHook)
21
+ allow(git_hook).to receive(:hook_lines).and_return(["Second line", "Third line"])
22
+ allow(git_hook).to receive(:name).and_return("my_hook")
23
+
24
+ @subject = Jigit::GitHookInstaller.new("spec/fixtures/git_hook_installer/.git/hooks",
25
+ "spec/fixtures/git_hook_installer/.git")
26
+ @subject.install(git_hook)
27
+ end
28
+
29
+ it("appends the given lines into git hook file") do
30
+ actual_lines = []
31
+ expected_lines = ["First line\n", "Second line\n", "Third line\n"]
32
+ File.foreach("spec/fixtures/git_hook_installer/.git/hooks/my_hook") { |line| actual_lines << line }
33
+ expect(actual_lines).to be == expected_lines
34
+ end
35
+ end
36
+
37
+ context("when there is no git hook file") do
38
+ before(:each) do
39
+ FileUtils.mkdir_p("spec/fixtures/git_hook_installer/.git")
40
+
41
+ git_hook = double(Jigit::GitHook)
42
+ allow(git_hook).to receive(:hook_lines).and_return(["First line", "Second line"])
43
+ allow(git_hook).to receive(:name).and_return("my_hook")
44
+
45
+ @subject = Jigit::GitHookInstaller.new("spec/fixtures/git_hook_installer/.git/hooks",
46
+ "spec/fixtures/git_hook_installer/.git")
47
+ @subject.install(git_hook)
48
+ end
49
+
50
+ it("creates the hook file") do
51
+ expect(File.exist?("spec/fixtures/git_hook_installer/.git/hooks/my_hook")).to be(true)
52
+ end
53
+
54
+ it("writes the given lines into git hook file") do
55
+ actual_lines = []
56
+ expected_lines = ["First line\n", "Second line\n"]
57
+ File.foreach("spec/fixtures/git_hook_installer/.git/hooks/my_hook") { |line| actual_lines << line }
58
+ expect(expected_lines).to be == actual_lines
59
+ end
60
+
61
+ it("ensures that the git hook file executable") do
62
+ expect(File.executable?("spec/fixtures/git_hook_installer/.git/hooks/my_hook")).to be(true)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,45 @@
1
+ require "jigit/git/git_ignore_updater"
2
+ require "fileutils"
3
+
4
+ describe Jigit::GitIgnoreUpdater do
5
+ describe(".ignore") do
6
+ after(:each) do
7
+ FileUtils.rm_rf("spec/fixtures/git_ignore_updater")
8
+ end
9
+
10
+ context("when there is empty .gitignore") do
11
+ before(:each) do
12
+ FileUtils.mkdir_p("spec/fixtures/git_ignore_updater")
13
+ FileUtils.touch("spec/fixtures/git_ignore_updater/.gitignore")
14
+ @subject = Jigit::GitIgnoreUpdater.new("spec/fixtures/git_ignore_updater/.gitignore")
15
+ @subject.ignore(".jigit")
16
+ end
17
+
18
+ it("ignores the given line") do
19
+ actual_lines = []
20
+ expected_lines = [".jigit\n"]
21
+ File.foreach("spec/fixtures/git_ignore_updater/.gitignore") { |line| actual_lines << line }
22
+ expect(actual_lines).to be == expected_lines
23
+ end
24
+ end
25
+
26
+ context("when there is not empty .gitignore") do
27
+ before(:each) do
28
+ FileUtils.mkdir_p("spec/fixtures/git_ignore_updater")
29
+ FileUtils.touch("spec/fixtures/git_ignore_updater/.gitignore")
30
+ @subject = Jigit::GitIgnoreUpdater.new("spec/fixtures/git_ignore_updater/.gitignore")
31
+ File.open("spec/fixtures/git_ignore_updater/.gitignore", "r+") do |f|
32
+ f.puts(".DS_Store")
33
+ end
34
+ @subject.ignore(".jigit")
35
+ end
36
+
37
+ it("ignores the given line") do
38
+ actual_lines = []
39
+ expected_lines = [".DS_Store\n", ".jigit\n"]
40
+ File.foreach("spec/fixtures/git_ignore_updater/.gitignore") { |line| actual_lines << line }
41
+ expect(actual_lines).to be == expected_lines
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,154 @@
1
+ require "jigit/jira/jira_api_client"
2
+ require "webmock/rspec"
3
+
4
+ describe Jigit::JiraAPIClient do
5
+ let(:config) { object_double(Jigit::JiraConfig) }
6
+ let(:site_url) { "http://foo:bar@localhost:2990" }
7
+ let(:jira_client) do
8
+ basic_client = JIRA::Client.new({ username: "foo", password: "bar", auth_type: :basic, use_ssl: false })
9
+ basic_client
10
+ end
11
+
12
+ describe("fetch_jira_statuses") do
13
+ context("when there is HTTP error") do
14
+ before do
15
+ stub_request(:get, site_url + "/jira/rest/api/2/status").
16
+ to_return(status: 405, body: "<html><body>Some HTML</body></html>")
17
+ end
18
+
19
+ it("raises an error") do
20
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
21
+ expect { jira_api_client.fetch_jira_statuses }.to raise_error "Can not fetch a JIRA statuses: <html><body>Some HTML</body></html>"
22
+ end
23
+ end
24
+
25
+ context("when there is no statuses") do
26
+ before do
27
+ stub_request(:get, site_url + "/jira/rest/api/2/status").
28
+ to_return(status: 301, body: "{\"errorMessages\":[\"Statuses Do Not Exist\"],\"errors\":{}}")
29
+ end
30
+
31
+ it("returns nil") do
32
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
33
+ expect { jira_api_client.fetch_jira_statuses }.to raise_error "Can not fetch a JIRA statuses: {\"errorMessages\":[\"Statuses Do Not Exist\"],\"errors\":{}}"
34
+ end
35
+ end
36
+
37
+ context("when there are statuses") do
38
+ before do
39
+ stub_request(:get, site_url + "/jira/rest/api/2/status").
40
+ to_return(status: 200, body: get_mock_response("statuses.json"))
41
+ end
42
+
43
+ it("returns correct amount of statuses") do
44
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
45
+ fetched_statuses = jira_api_client.fetch_jira_statuses
46
+ expect(fetched_statuses.count).to be == 5
47
+ end
48
+
49
+ it("returns wrapped jira statuses") do
50
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
51
+ fetched_statuses = jira_api_client.fetch_jira_statuses
52
+ expect(fetched_statuses).to all(be_instance_of(Jigit::JiraStatus))
53
+ end
54
+ end
55
+ end
56
+
57
+ describe("fetch_issue_transitions") do
58
+ let(:jira_issue) do
59
+ base_issue = JIRA::Resource::Issue.new(jira_client, attrs: {
60
+ "id" => "10002",
61
+ "self" => "#{site_url}/jira/rest/api/2/issue/10002",
62
+ "fields" => {
63
+ "comment" => { "comments" => [] }
64
+ }
65
+ })
66
+ issue = Jigit::JiraIssue.new(base_issue)
67
+ issue
68
+ end
69
+
70
+ context("when there is HTTP error") do
71
+ before do
72
+ stub_request(:get, site_url + "/jira/rest/api/2/issue/10002/transitions?expand=transitions.fields").
73
+ to_return(status: 405, body: "<html><body>Some HTML</body></html>")
74
+ end
75
+
76
+ it("raises an error") do
77
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
78
+ expect { jira_api_client.fetch_issue_transitions(jira_issue) }.to raise_error "Can not fetch JIRA issue transitions: <html><body>Some HTML</body></html>"
79
+ end
80
+ end
81
+
82
+ context("when there is no transitions") do
83
+ before do
84
+ stub_request(:get, site_url + "/jira/rest/api/2/issue/10002/transitions?expand=transitions.fields").
85
+ to_return(status: 301, body: "{\"errorMessages\":[\"Transitions Do Not Exist\"],\"errors\":{}}")
86
+ end
87
+
88
+ it("raises as error") do
89
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
90
+ expect { jira_api_client.fetch_issue_transitions(jira_issue) }.to raise_error "Can not fetch JIRA issue transitions: {\"errorMessages\":[\"Transitions Do Not Exist\"],\"errors\":{}}"
91
+ end
92
+ end
93
+
94
+ context("when there are transitions") do
95
+ before do
96
+ stub_request(:get, site_url + "/jira/rest/api/2/issue/10002/transitions?expand=transitions.fields").
97
+ to_return(status: 200, body: get_mock_response("issue_1002_transitions.json"))
98
+ end
99
+
100
+ it("returns correct amount of transitions") do
101
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
102
+ fetched_transitions = jira_api_client.fetch_issue_transitions(jira_issue)
103
+ expect(fetched_transitions.count).to be == 4
104
+ end
105
+
106
+ it("returns wrapped jira transitions") do
107
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
108
+ fetched_transitions = jira_api_client.fetch_issue_transitions(jira_issue)
109
+ expect(fetched_transitions).to all(be_instance_of(Jigit::JiraTransition))
110
+ end
111
+ end
112
+ end
113
+
114
+ describe("fetch_jira_issue") do
115
+ let(:issue_name) { "ADT-1" }
116
+
117
+ context("when there is HTTP error") do
118
+ before do
119
+ stub_request(:get, site_url + "/jira/rest/api/2/search?jql=key%20=%20ADT-1").
120
+ to_return(status: 405, body: "<html><body>Some HTML</body></html>")
121
+ end
122
+
123
+ it("raises an error") do
124
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
125
+ expect { jira_api_client.fetch_jira_issue(issue_name) }.to raise_error "Can not fetch a JIRA issue: <html><body>Some HTML</body></html>"
126
+ end
127
+ end
128
+
129
+ context("when there is no issue") do
130
+ before do
131
+ stub_request(:get, site_url + "/jira/rest/api/2/search?jql=key%20=%20ADT-1").
132
+ to_return(status: 301, body: "{\"errorMessages\":[\"Issue Does Not Exist\"],\"errors\":{}}")
133
+ end
134
+
135
+ it("raises an error") do
136
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
137
+ expect { jira_api_client.fetch_jira_issue(issue_name) }.to raise_error "Can not fetch a JIRA issue: {\"errorMessages\":[\"Issue Does Not Exist\"],\"errors\":{}}"
138
+ end
139
+ end
140
+
141
+ context("when there is issue") do
142
+ before do
143
+ stub_request(:get, site_url + "/jira/rest/api/2/search?jql=key%20=%20ADT-1").
144
+ to_return(status: 200, body: get_mock_response("issue.json"))
145
+ end
146
+
147
+ it("returns wrapped jira issue") do
148
+ jira_api_client = Jigit::JiraAPIClient.new(config, jira_client)
149
+ fetched_issue = jira_api_client.fetch_jira_issue(issue_name)
150
+ expect(fetched_issue).to be_instance_of(Jigit::JiraIssue)
151
+ end
152
+ end
153
+ end
154
+ end