Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: copy orchestration template #13053

Merged
merged 1 commit into from
Jan 4, 2017

Conversation

cynepco3hahue
Copy link

For the SSUI we need to have possibility to copy OrchestrationTemplate via API


expect do
run_post(orchestration_templates_url(test_ot.id), gen_request(:copy, :content => ''))
end.to change(OrchestrationTemplateCfn, :count).by(2)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test the http status and expected response as well here

@@ -144,6 +144,18 @@ def save_as_orderable!
new_record? ? replace_with_old_template(old_template) : transfer_stacks(old_template)
end

def deep_copy(new_attributes = {})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really sure this deep copy is needed since it's only dup-ing and updating the attributes

api_basic_authorize collection_action_identifier(:orchestration_templates, :copy)

run_post(orchestration_templates_url(test_ot.id), gen_request(:copy))
expect(response.status).to eq(400)
Copy link

@jntullo jntullo Dec 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a suggestion, but this could also be written
expect(response).to have_http_status(:forbidden) which is nice for readability 😄

@@ -125,4 +125,23 @@
expect(OrchestrationTemplate.exists?(hot.id)).to be_falsey
end
end

context 'orchestration template copy' do
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should also add a test for copying multiple

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cynepco3hahue can you also add tests for unhappy path for authorization for this feature?

@cynepco3hahue cynepco3hahue force-pushed the API_copy_ot branch 4 times, most recently from 9798578 to 6db0c32 Compare December 13, 2016 08:44
@@ -94,6 +94,23 @@ def delete_resource(type, id = nil, _data = nil)
delete_resource_action(klass, type, id)
end

def copy_resource(type, id, data = {})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in app/controllers/api/orchestration_template_controller.rb because it is specific to orchestration templates

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks pretty general, so I thought maybe it can be useful in the future if you want to add copy API for some entity.
What do you think?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a bad idea - but that's a question for @abellotti or @imtayadeway 😃

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cynepco3hahue I would make the same recommendation as per @jntullo - if it is needed for another resource we can always review that later, and there may be a better way of sharing that between API controllers without giving it to everyone in the base class

def copy_resource(type, id, data = {})
klass = collection_class(type)
resource = resource_search(id, type, klass)
attributes = data.dup
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't think you need to dup the data here since you're not manipulating it

if new_resource.respond_to? "#{attr}="
new_resource.send("#{attr}=", value)
else
raise ActiveModel::UnknownAttributeError.new(self, attr)
Copy link

@jntullo jntullo Dec 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would not raise an UnknownAttributeError since that'll be handled by the rescue below. Would just do a raise "uknown attribute #{attr}"

end
new_resource.tap(&:save!)
rescue => err
raise BadRequestError, "Failed to copy orchestration template - #{err}"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it stays in generic, will need to remove reference to orchestration template

@cynepco3hahue cynepco3hahue force-pushed the API_copy_ot branch 2 times, most recently from eed9c95 to bf7c315 Compare December 14, 2016 06:50
klass = collection_class(type)
resource = resource_search(id, type, klass)
new_resource = resource.dup
data.each do |attr, value|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does new_resource.assign_attributes(data) achieve the same effect?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, thanks now it looks better

orchestration_templates_url(test_ot_1.id),
gen_request(:copy, :content => test_content_1)
)
end.to change(OrchestrationTemplateCfn, :count).by(2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did it change by 2? Is it because the execution is where the lazy-evaluated test_ot_1 gets created? For this reason I think it's better to avoid lets and create everything you are going to test in the setup phase in the body of the test. Duplication is OK in tests and can improve readability

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change it.

expect do
run_post(
orchestration_templates_url(test_ot_1.id),
gen_request(:copy, :content => test_content_1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test doesn't make clear the value of this feature. Can you already exercise this behavior by creating an orchestration template (via POST/create) with the attributes specified?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it will save you from entering a new name, description and type. Also, we have the possibility to copy an orchestration template via UI, so it better to have such possibility via API.
I believe @chriskacerguis can explain the intention after this feature in the context of self-service.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cynepco3hahue that's fine, but you are essentially only exercising behavior we already have through POST/create in this test - can you update to verify the copying of existing attributes works?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh sure I will add it

raise "uknown attribute #{attr}"
end
end
new_resource.tap(&:save!)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the tap necessary?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes if you want to return the object

api_basic_authorize collection_action_identifier(:orchestration_templates, :copy)

expected = {
'content' => test_content_1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you verify that you don't get the id/href back of the original?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add the verification for id, but adding verification for the href a little bit problematic, FactorGirl OrchestrationEntity does not have the href.
I believe to check only id's good enough for test purpose.
What do you think?

@@ -125,4 +125,70 @@
expect(OrchestrationTemplate.exists?(hot.id)).to be_falsey
end
end

context 'orchestration template copy' do
it 'copy template with the same content' do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make these fully descriptive and full sentences (including the "it") so something like "it will not copy a template with no attributes specified" or similar...


context 'orchestration template copy' do
it 'copy template with the same content' do
test_ot_1 = FactoryGirl.create(:orchestration_template_cfn)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be clear that this is a test.... perhaps simply "orchestration_template" or "orchestration_template_1" for these variables?

it 'copy template with the same content' do
test_ot_1 = FactoryGirl.create(:orchestration_template_cfn)

api_basic_authorize collection_action_identifier(:orchestration_templates, :copy)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent with spacing can you try to group lines that belong to each phase of the test, i.e. all setup steps together, all execution steps, all verification steps, etc...


it 'copy single template with the different content' do
test_ot_1 = FactoryGirl.create(:orchestration_template_cfn)
test_content_1 = "{ 'Description': 'Test content 1' }\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious as to why this doesn't get deserialized by Rails when you call response.parsed_body?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it because we add new line in the orchestration template by intention(I can see it from code)
text.encode(:universal_newline => true).chomp.concat("\n")

@@ -125,4 +125,83 @@
expect(OrchestrationTemplate.exists?(hot.id)).to be_falsey
end
end

context 'orchestration template copy' do
before do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

befores, like lets, are best for details which are necessary but not relevant to understanding the behavior being exercised. Since both these objects are central, I'd resist the urge to DRY up here and allow a little duplication for the sake of readability

api_basic_authorize collection_action_identifier(:orchestration_templates, :copy)

orchestration_template_2 = FactoryGirl.create(:orchestration_template_cfn)
new_content_2 = "{ 'Description': 'Test content 2' }\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'm curious as to why this doesn't get parsed/deserialized. Does { "description" => "Test content 2" } work?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it because we add new line in the orchestration template by intention(I can see it from code)
text.encode(:universal_newline => true).chomp.concat("\n")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this cause issues with consuming/parsing this API? @abellotti any thoughts here?

@cynepco3hahue
Copy link
Author

@imtayadeway @jntullo Can you please review again?

1 similar comment
@cynepco3hahue
Copy link
Author

@imtayadeway @jntullo Can you please review again?

def copy_resource(type, id, data = {})
klass = collection_class(type)
resource = resource_search(id, type, klass)
new_resource = resource.dup
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than using .tap(&:save!) below, you can just tap the whole thing.

resource.dup.tap do |new_resource|
   new_resource.assign_attributes(data)
   new_resource.save!
end 

Copy link
Member

@abellotti abellotti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor changes requested, otherwise I'm 👍 with this. Thanks.


def copy_resource(type, id, data = {})
klass = collection_class(type)
resource = resource_search(id, type, klass)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can combine the above 2 lines,

resource = resource_search(id, type, collection_class(type))

new_resource.save!
end
rescue => err
raise BadRequestError, "Failed to copy #{klass} - #{err}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would prefer english instead of klass/type.

  ... "Failed to copy orchestration template - #{err}"

@imtayadeway
Copy link
Contributor

@cynepco3hahue can you take care of pending requests above? Thanks!

For the SSUI we need to have possibility to copy OrchestrationTemplate
via API
@miq-bot
Copy link
Member

miq-bot commented Jan 4, 2017

Checked commit cynepco3hahue@d3aeb20 with ruby 2.2.5, rubocop 0.37.2, and haml-lint 0.16.1
2 files checked, 0 offenses detected
Everything looks good. 🍰

@abellotti
Copy link
Member

LGTM!!

@abellotti abellotti merged commit 0b19f50 into ManageIQ:master Jan 4, 2017
@abellotti abellotti added this to the Sprint 52 Ending Jan 16, 2017 milestone Jan 4, 2017
@cynepco3hahue cynepco3hahue deleted the API_copy_ot branch January 18, 2017 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants