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

add dialog info when import/export custom buttons #20137

Conversation

borisko123
Copy link
Contributor

@borisko123 borisko123 commented May 7, 2020

Fixes #20124

Current flow for import/export custom buttons ignores possible reference of the button to service dialog.
It is very inconvenient, since after import one need to add this reference manually in UI.
What's done:

  • files custom_buttons.rb modified both for import and export to include stuff for handle dialog data
    (actually added dialog label)
  • modified spec tests for new functionality

How to run unit tests:

  • rspec spec/lib/task_helpers/imports/custom_buttons_spec.rb
  • rspec spec/lib/task_helpers/exports/custom_buttons_spec.rb

How to test manually on real data:

  1. Add manually the domain, service dialog, button group, the button
  2. Connect button to service dialog
  3. Create directories for import/export, say contrib_export/buttons/
  4. Export button:
    bundle exec rake evm:export:custom_buttons -- --directory contrib_export/buttons/
  5. Remove button
  6. Import button:
    bundle exec rake evm:import:custom_buttons -- --source contrib_export/buttons/
  7. Make sure the button is linked to dialog
    Button and dialog
    (see screenshot)

The screen

@lfu
Copy link
Member

lfu commented May 8, 2020

@borisko123 Please address the rubocop warnings.

@borisko123
Copy link
Contributor Author

@borisko123 Please address the rubocop warnings.

@borisko123 borisko123 closed this May 9, 2020
@borisko123 borisko123 reopened this May 9, 2020
@borisko123
Copy link
Contributor Author

@lfu seems all clean now

@lfu
Copy link
Member

lfu commented May 11, 2020

@gmcculloug Any idea why dialog was excluded from import/export in #17699? What was the concern?

@gmcculloug
Copy link
Member

As I recall, we were following scripts that already existed (side the MIQ repo) which processed custom buttons and dialogs separately.

If you add this you'll just want to consider how you handle if the dialog already exists. Dialogs can be re-used by different buttons and/or services.

@lfu
Copy link
Member

lfu commented May 11, 2020

@borisko123 Thanks for the update.
What kind of dialog info is supposed to be added in this PR? Is it the dialog object with all its tabs and fields? Seems only dialog label is added in the export yaml file.

Please take a look at this file for importing a dialog and this for exporting. Hope they can give you some ideas.

@borisko123
Copy link
Contributor Author

borisko123 commented May 11, 2020 via email

@borisko123
Copy link
Contributor Author

borisko123 commented May 11, 2020 via email

@borisko123
Copy link
Contributor Author

borisko123 commented May 11, 2020 via email

@lfu
Copy link
Member

lfu commented May 11, 2020

What if a dialog exists with the same name but different contents? Dialogs can be re-used by different buttons and/or services. It seems not right to use the existing dialog just because it has the same name.
@Fryguy @gmcculloug @gtanzillo Suggestion?

@borisko123
Copy link
Contributor Author

From Dialog model: the name/label is unique within region:
validates :name, :unique_within_region => true
In case we will filter our objects (button, dialog,reasource_action),by region, all should work as expected.
Actually, the original rhconsulting (https://github.com/rhtconsulting/cfme-rhconsulting-scripts/blob/master/rhconsulting_buttons.rake) script had this functionality.
Somehow I missed this.

So I suggest to add this functionality (filtering ) and then all should work.

@lfu
Copy link
Member

lfu commented May 12, 2020

If the user really wants to use an existing dialog just because it has the same name, we can add one more command line option like --connect_dialog_by_name true to import.
Existing dialog with the same name would be connected to the custom button if the option is specified. Otherwise, the dialog would not be used.
Hopefully the user would be aware of what is going to happen with the specified option.

@gmcculloug @gtanzillo What do you think of the new option? Any suggestion for the option name?

@borisko123
Copy link
Contributor Author

If the user really wants to use an existing dialog just because it has the same name, we can add one more command line option like --connect_dialog_by_name true to import.
Existing dialog with the same name would be connected to the custom button if the option is specified. Otherwise, the dialog would not be used.
Hopefully the user would be aware of what is going to happen with the specified option.

It seems this option should be set to true by default.
More often we want to import 'as-is'

@gtanzillo
Copy link
Member

It seems this option should be set to true by default.
More often we want to import 'as-is'

I would also agree that it would be more often that the user would want to use an existing dialog with the same name. However, i think would still be safer if that intention was explicitly specified on the command line.

@borisko123
Copy link
Contributor Author

borisko123 commented May 13, 2020 via email

@lfu
Copy link
Member

lfu commented May 13, 2020

Please modify the code where the new feature is added and keep other places untouched.
Then use git rebase to squash your commits into a clean commit without the intermediate steps.

@borisko123
Copy link
Contributor Author

borisko123 commented May 13, 2020 via email

@lfu
Copy link
Member

lfu commented May 13, 2020 via email

@borisko123 borisko123 force-pushed the add_dialog_info_for_import_export_custom_buttons branch 2 times, most recently from 44aa954 to 50fbbde Compare May 17, 2020 15:52
@borisko123
Copy link
Contributor Author

borisko123 commented May 17, 2020

Please modify the code where the new feature is added and keep other places untouched.
Then use git rebase to squash your commits into a clean commit without the intermediate steps.
@lfu
please check now

@borisko123 borisko123 force-pushed the add_dialog_info_for_import_export_custom_buttons branch 3 times, most recently from d034b34 to 7069262 Compare May 25, 2020 17:13
ActiveRecord::Base.transaction { obj_hash.each { |obj_def| create_object(*obj_def) } }
end

def find_or_create_object(class_name, obj)
Copy link
Member

Choose a reason for hiding this comment

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

In my opinion, this is to import custom buttons where they don't exist.
In case custom buttons exist, they may use Edit task in UI to modify them.
This new method is not necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lfu, this method is my main enhancement.
Original code raises exception when button exists.
This is unacceptable.
The import may occurs many times on the already existing buttons(in development and even in production), with or without some button changing.
In both cases the code should replace the button, optionally updating the button attributes.
The 'rhconsulting' script, which was used for porting, had this behaviour.
Your idea of using UI, seems strange to me, as all the goal of import/export scripts is to make things without UI.
Please re-think your opinion

Copy link
Member

Choose a reason for hiding this comment

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

The import may occurs many times on the already existing buttons(in development and even in production), with or without some button changing.

There are couple of things here.

  1. Why do you need import again if the buttons exist?
  2. name alone is not enough to identify a button.
  3. Not sure if it is a good practice to update an existing button just because it happens to have the same name. What if the buttons are owned by other users?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. It is needed, for example, during development, when import may be done multiple times from the same or different developers. Personally, had problems with this. Currently this will cause error,
    and one need to delete manually ALL the button(s) in import directory, prior to import, or update yaml file. This is far from being convenient.
  2. You are right. Button should be looked up by class and apply_id.
    This may be added to code
  3. For user's support some logic exists (see check_user method). This method is untouched in PR.
    It set user from export data, or 'admin'. Maybe it may be improved.
    Summary:
    A. Importing existed buttons needs additional efforts.
    In my opinion, it is nice to have.
    In case ManageIQ team has another opinion. it is not worth to implement this at all
    B. This PR includes 2 independent features: dialog support and import existing buttons.
    In any way, since dialog support code is already mostly approved by you, I suggest retaining only corresponding code (for dialog support) in this PR and continue to review.

    C. Optionally, open issue about importing existing buttons.

end
end

def populate_action(item, assoc)
Copy link
Member

Choose a reason for hiding this comment

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

These two methods added here are not necessary. Please move the code into add_associations.

@lfu
Copy link
Member

lfu commented Jun 1, 2020

@borisko123 I like your idea to keep this PR just for dialog support. Let's open another issue for importing existing buttons.

@borisko123 borisko123 force-pushed the add_dialog_info_for_import_export_custom_buttons branch 2 times, most recently from af0240a to 2d8da36 Compare June 4, 2020 08:57
@borisko123
Copy link
Contributor Author

borisko123 commented Jun 4, 2020

@borisko123 I like your idea to keep this PR just for dialog support. Let's open another issue for importing existing buttons.

@lfu done PR just for dialog, please check
New issue will open soon.

assert_imports_only_custom_button_set_one
end
end
end
end

def assert_dialog_is_set(connect)
btn1 = CustomButton.find_by(:name => custom_button_1_name)
expect(btn1).to be
Copy link
Member

Choose a reason for hiding this comment

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

This line seems not right.

Copy link
Member

Choose a reason for hiding this comment

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

  button_1 = CustomButton.find_by(:name => "button 1")
  expect(button_1).not_to be_nil
  if connect
       expect(button_1.resource_action.dialog.id).to eq(test_dialog_2.id)
     else
       expect(button_1.resource_action.dialog).to be_nil
     end
  end

Copy link
Member

Choose a reason for hiding this comment

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

Prefer variable name button_1 over btn1.

Copy link
Member

Choose a reason for hiding this comment

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

@borisko123 Can you fix this line expect(btn1).to be?

Copy link
Contributor Author

@borisko123 borisko123 Jun 16, 2020

Choose a reason for hiding this comment

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

Hi @lfu , what is wrong with this line?
It asserts that button exists...

from : https://relishapp.com/rspec/rspec-expectations/v/3-9/docs/built-in-matchers/be-matchers
expect(obj).to be # passes if obj is truthy (not nil or false)

Copy link
Member

Choose a reason for hiding this comment

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

Screen Shot 2020-06-16 at 13 35 56

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lfu Done

end
end

context "with existing identical buttons" do
it 'should not import anything' do
TaskHelpers::Imports::CustomButtons.new.import(options)
assert_raises_import_error
Copy link
Member

Choose a reason for hiding this comment

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

What caused this change?

Copy link
Member

Choose a reason for hiding this comment

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

Never mind.

assert_imports_only_custom_button_set_one
end
end
end
end

def assert_dialog_is_set(connect)
btn1 = CustomButton.find_by(:name => custom_button_1_name)
Copy link
Member

Choose a reason for hiding this comment

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

Minor. But can we have a better variable name here? Like button or button_1?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lfu done

@borisko123 borisko123 force-pushed the add_dialog_info_for_import_export_custom_buttons branch from 2d8da36 to 257466c Compare June 6, 2020 14:54
let(:options) { {:source => source} }
let(:connect_dialog_by_name) { true }
let(:options) { {:source => source, :connect_dialog_by_name => connect_dialog_by_name} }
let(:button_1) { 'button 1' }
Copy link
Member

Choose a reason for hiding this comment

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

This variable never changes. Can be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

right. :button_1 is constant here, defined via let, and used at line 85:
btn1 = CustomButton.find_by(:name => button_1)
Do you want me to use literal instead? like
btn1 = CustomButton.find_by(:name => 'button 1')
Using 'let' to define constant is found as preffered way: see
https://stackoverflow.com/questions/5230070/scope-constants-to-an-rspec-context

Copy link
Member

Choose a reason for hiding this comment

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

In my opinion, there is no need to define a variable here whose value doesn't change between the test cases.

Copy link
Member

Choose a reason for hiding this comment

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

Agree that btn1 = CustomButton.find_by(:name => 'button 1') is clearer since button_1 does not seem to be used anywhere else. Which code sets the name to button 1? Perhaps both of those can use the same variable, such as button_1_name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@borisko123 borisko123 force-pushed the add_dialog_info_for_import_export_custom_buttons branch from 257466c to da43b07 Compare June 11, 2020 18:30
-fix error in spec example
-the test result depends on file order
-code style review
-modified according to miq-bot request
-fix rubocop offence
-add new flag (for dialog), modify specs
- after review, simplify export dialog (@lfu, Tempfile creation (@gmcculloug)
- refactor to include only dialog support stuff
- rubocop issues
- review literal button name without let
- fix to be (be_an(CustomButton)
@borisko123 borisko123 force-pushed the add_dialog_info_for_import_export_custom_buttons branch from da43b07 to a1fa28e Compare June 17, 2020 10:20
@miq-bot
Copy link
Member

miq-bot commented Jun 17, 2020

Checked commit borisko123@a1fa28e with ruby 2.5.7, rubocop 0.69.0, haml-lint 0.28.0, and yamllint
4 files checked, 0 offenses detected
Everything looks fine. 🍰

@lfu
Copy link
Member

lfu commented Jun 17, 2020

@gtanzillo LGTM

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.

add dialog support for import/export of custom buttons
6 participants