require "spec_helper"
describe Embulk::Input::JiraApi::Client do
describe ".setup" do
subject { Embulk::Input::JiraApi::Client.setup {} }
it "returns Embulk::Input::JiraApi::Client instance" do
expect(subject.is_a?(Embulk::Input::JiraApi::Client)).to be_truthy
end
it "calls Jiralicious.configure" do
allow(Jiralicious).to receive(:configure)
end
end
describe "#search" do
let(:jql) { "project=FOO" }
let(:api) { Embulk::Input::JiraApi::Client.new }
subject { api.search(jql) }
it do
allow(Jiralicious).to receive(:search).with(jql)
end
describe "retry and timeout" do
before do
allow(Timeout).to receive(:timeout) { raise Timeout::Error }
allow(api).to receive(:sleep)
end
it "retry DEFAULT_SEARCH_RETRY_TIMES times then raise error" do
expect(Timeout).to receive(:timeout).exactly(Embulk::Input::JiraApi::Client::DEFAULT_SEARCH_RETRY_TIMES + 1)
expect { subject }.to raise_error
end
end
end
describe "#search_issues" do
let(:jql) { "project=FOO" }
let(:jira_api) { Embulk::Input::JiraApi::Client.new }
let(:title_401) { "Unauthorized (401)"}
let(:multi_json_error) {MultiJson::ParseError.build(StandardError.new("
#{title_401}"), {})}
let(:results) do
[
{
"id" => 1,
"jira_key" => "FOO-1",
"fields" =>
{
"summary" => "issue summary",
"project" =>
{
"key" => "FO1"
}
}
},
{
"id" => 2,
"jira_key" => "FOO-2",
"fields" =>
{
"summary" => "jira issue",
"project" =>
{
"key" => "FO2"
}
}
}
]
end
subject { jira_api.search_issues(jql) }
it "Search issues successfully" do
allow(Jiralicious).to receive_message_chain(:search, :issues_raw).and_return(results)
allow(jira_api).to receive(:find_issue).and_return(results.first)
expect(subject).to be_kind_of Array
expect(subject.map(&:class)).to match_array [Embulk::Input::JiraApi::Issue, Embulk::Input::JiraApi::Issue]
end
it "Search issues successfully when first item success - 401 - second items success" do
allow(Jiralicious).to receive_message_chain(:search, :issues_raw).and_return(results)
allow(jira_api).to receive(:find_issue).and_return(results.first).and_raise(multi_json_error).and_return(results.first)
expect(subject).to be_kind_of Array
expect(subject.map(&:class)).to match_array [Embulk::Input::JiraApi::Issue, Embulk::Input::JiraApi::Issue]
end
it "Search issues successfully when 401 - first and second items success" do
allow(Jiralicious).to receive_message_chain(:search, :issues_raw).and_return(results)
allow(jira_api).to receive(:find_issue).and_raise(multi_json_error).and_return(results.first)
expect(subject).to be_kind_of Array
expect(subject.map(&:class)).to match_array [Embulk::Input::JiraApi::Issue, Embulk::Input::JiraApi::Issue]
end
it "Search issues got 401 due to high concurrent load issues" do
allow(Jiralicious).to receive_message_chain(:search, :issues_raw).and_return(results)
allow(jira_api).to receive(:find_issue).and_raise(multi_json_error)
allow(jira_api).to receive(:sleep)
expect { subject }.to raise_error(StandardError, title_401)
end
end
describe "#total_count" do
subject { jira_api.total_count(jql) }
let(:jira_api) { Embulk::Input::JiraApi::Client.new }
let(:jql) { "project=FOO" }
let(:results) { Object.new } # add mock later
let(:results_count) { 5 }
before do
allow(results).to receive(:num_results).and_return(results_count)
end
it "calls Embulk::Input::JiraApi::Client#search with proper arguments" do
expect(jira_api).to receive(:search).with(jql, max_results: 1).and_return(results)
subject
end
it "returns issues count" do
allow(jira_api).to receive(:search).with(jql, max_results: 1).and_return(results)
expect(subject).to eq results_count
end
end
describe "#timeout_and_retry" do
let(:wait) { 1 }
let(:retry_times) { 3 }
let(:jira_api) { Embulk::Input::JiraApi::Client.new }
let(:block) { proc{ "it works" } }
subject { jira_api.send(:timeout_and_retry, wait, retry_times, &block) }
before do
allow(jira_api).to receive(:sleep)
end
it "return given block result if timeout is not occured" do
expect(subject).to eq block.call
end
it "Always timeout, raise error after N times retry" do
allow(Timeout).to receive(:timeout) { raise Timeout::Error }
expect(Timeout).to receive(:timeout).with(wait).exactly(retry_times + 1).times
expect { subject }.to raise_error(Timeout::Error)
end
describe "invalid JSON response" do
let(:block) { proc{ MultiJson.load("#{title}")} }
before { allow(Embulk.logger).to receive(:warn) }
# Disable this test to enable retry for 401
# context "Unauthorized" do
# let(:title) { "Unauthorized (401)" }
#
# it do
# expect { subject }.to raise_error(Embulk::ConfigError)
# end
# end
context "Unavailable" do
let(:title) { "Atlassian Cloud Notifications - Page Unavailable"}
it do
expect { subject }.to raise_error(StandardError, title)
end
end
end
end
describe "#calculate_rate_limit" do
let(:jira_api) { Embulk::Input::JiraApi::Client.new }
it "current_limit = 50, all_items = 50, fail_items=50, times=1" do
current_limit = 50
all_items = 50
fail_items = 50
times = 1
expected_result = Embulk::Input::JiraApi::Client::MIN_RATE_LIMIT
expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
end
it "current_limit = 50, all_items = 50, fail_items=20, times=1" do
current_limit = 50
all_items = 50
fail_items = 20
times = 1
expected_result = 20
expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
end
it "current_limit = MIN_RATE_LIMIT, all_items = 50, fail_items=20, times=2" do
current_limit = Embulk::Input::JiraApi::Client::MIN_RATE_LIMIT
all_items = 50
fail_items = 20
times = 2
expected_result = Embulk::Input::JiraApi::Client::MIN_RATE_LIMIT
expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
end
it "current_limit = 10, all_items = 30, fail_items=25, times=2" do
current_limit = 10
all_items = 30
fail_items = 25
times = 2
expected_result = 5
expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
end
it "current_limit = 50, all_items = 50, fail_items=20, times=DEFAULT_SEARCH_RETRY_TIMES/2" do
current_limit = 50
all_items = 50
fail_items = 20
times = Embulk::Input::JiraApi::Client::DEFAULT_SEARCH_RETRY_TIMES/2
expected_result = Embulk::Input::JiraApi::Client::MIN_RATE_LIMIT
expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
end
end
end