Skip to content

Commit

Permalink
Send IDs through exec_api_call as a regular param not a block
Browse files Browse the repository at this point in the history
When sending them through an array in a block, the client calls the action
on the collection with an array of IDs.  Unfortunately this returns an
Array of ManageIQ::API::Client::ActionResults and Arrays aren't currently
an expected response for this caller, so it will raise:
"Got unexpected API result object Array"

Rather than dealing with the confusion of calling .first on the array,
allow an ID to be passed in.

https://bugzilla.redhat.com/show_bug.cgi?id=1526009
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1528339
  • Loading branch information
bdunne committed Dec 21, 2017
1 parent 805e023 commit 1eca9a8
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 56 deletions.
13 changes: 4 additions & 9 deletions app/models/mixins/inter_region_api_method_relay.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ def api_relay_method(method, action = method)
if in_current_region?
super(*meth_args, &meth_block)
else
InterRegionApiMethodRelay.exec_api_call(region_number, collection_name, action, api_args) do
[{:id => id}]
end
InterRegionApiMethodRelay.exec_api_call(region_number, collection_name, action, api_args, id)
end
end
end
Expand Down Expand Up @@ -71,14 +69,11 @@ def self.api_client_connection_for_region(region_number, user = User.current_use
)
end

def self.exec_api_call(region, collection_name, action, api_args = nil, &resource_block)
def self.exec_api_call(region, collection_name, action, api_args = nil, id = nil)
api_args ||= {}
collection = api_client_connection_for_region(region).public_send(collection_name)
result = if resource_block
collection.public_send(action, api_args, &resource_block)
else
collection.public_send(action, api_args)
end
collection_or_instance = id ? collection.find(id) : collection
result = collection_or_instance.public_send(action, api_args)
case result
when ManageIQ::API::Client::ActionResult
raise InterRegionApiMethodRelayError, result.message if result.failed?
Expand Down
66 changes: 19 additions & 47 deletions spec/models/mixins/inter_region_api_method_relay_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,12 @@ def self.test_class_method_action(_arg)
end

def expect_api_call(expected_action, expected_args = nil)
expect(described_class).to receive(:exec_api_call) do |region_num, collection, action, args, &block|
expect(described_class).to receive(:exec_api_call) do |region_num, collection, action, args, instance_id|
expect(region_num).to eq(region)
expect(collection).to eq(collection_name)
expect(action).to eq(expected_action)
expect(args).to eq(expected_args) if expected_args

expect(block.call).to eq([{:id => id}])
expect(instance_id).to eq(id)
end
end

Expand Down Expand Up @@ -229,54 +228,27 @@ def expect_api_call(expected_action, expected_args = nil)
}.to raise_error(described_class::InterRegionApiMethodRelayError)
end

context "when no block is passed" do
it "calls the given action with the given args" do
args = {:my => "args", :here => 123}
expect(api_collection).to receive(action).with(args).and_return(api_success_result)
described_class.exec_api_call(region, collection_name, action, args)
end

it "defaults the args to an empty hash" do
expect(api_collection).to receive(action).with({}).and_return(api_success_result)
described_class.exec_api_call(region, collection_name, action)
end

it "defaults the args to an empty hash when nil is explicitly passed as args" do
expect(api_collection).to receive(action).with({}).and_return(api_success_result)
described_class.exec_api_call(region, collection_name, action, nil)
end
it "calls the given action with the given args" do
args = {:my => "args", :here => 123}
expect(api_collection).to receive(action).with(args).and_return(api_success_result)
described_class.exec_api_call(region, collection_name, action, args)
end

context "when a block is passed" do
let(:resource_proc) { -> { "some stuff" } }

it "calls the given action with the given args" do
expected_args = {:my => "args", :here => 123}
expect(api_collection).to receive(action) do |args, &block|
expect(args).to eq(expected_args)
expect(block.call).to eq("some stuff")
end.and_return(api_success_result)

described_class.exec_api_call(region, collection_name, action, expected_args, &resource_proc)
end

it "defaults the args to an empty hash" do
expect(api_collection).to receive(action) do |args, &block|
expect(args).to eq({})
expect(block.call).to eq("some stuff")
end.and_return(api_success_result)

described_class.exec_api_call(region, collection_name, action, &resource_proc)
end
it "defaults the args to an empty hash" do
expect(api_collection).to receive(action).with({}).and_return(api_success_result)
described_class.exec_api_call(region, collection_name, action)
end

it "defaults the args to an empty hash when nil is explicitly passed as args" do
expect(api_collection).to receive(action) do |args, &block|
expect(args).to eq({})
expect(block.call).to eq("some stuff")
end.and_return(api_success_result)
it "defaults the args to an empty hash when nil is explicitly passed as args" do
expect(api_collection).to receive(action).with({}).and_return(api_success_result)
described_class.exec_api_call(region, collection_name, action, nil)
end

described_class.exec_api_call(region, collection_name, action, nil, &resource_proc)
end
it "calls a method on an instance if id is passed" do
instance = double("instance")
expect(api_collection).to receive(:find).with(4).and_return(instance)
expect(instance).to receive(action).and_return(api_success_result)
described_class.exec_api_call(region, collection_name, action, nil, 4)
end
end
end
Expand Down

0 comments on commit 1eca9a8

Please sign in to comment.