Skip to content

Commit

Permalink
Merge pull request #713 from Fryguy/add_my_settings_view_to_roles
Browse files Browse the repository at this point in the history
Add my_settings_view to roles

(cherry picked from commit 45860ac)
  • Loading branch information
kbrock authored and Fryguy committed Nov 16, 2023
1 parent 1992430 commit 93d1be4
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 0 deletions.
46 changes: 46 additions & 0 deletions db/migrate/20231114223004_add_my_settings_view_to_roles.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class AddMySettingsViewToRoles < ActiveRecord::Migration[6.1]
class MiqUserRole < ActiveRecord::Base
has_and_belongs_to_many :miq_product_features, :join_table => :miq_roles_features, :class_name => "AddMySettingsViewToRoles::MiqProductFeature"
end

class MiqProductFeature < ActiveRecord::Base; end

def up
return unless MiqUserRole.exists?(:read_only => false)

say_with_time("Adding my_settings_view to custom user roles") do
my_settings_features = MiqProductFeature.where("identifier LIKE ?", "my_settings_%").pluck(:identifier)
my_settings_view = my_settings_id = nil

roles_with_features(my_settings_features)
.where.not(:id => roles_with_features(%w[my_settings my_settings_view]))
.each do |user_role|
my_settings_id ||= MiqProductFeature.find_by(:identifier => "my_settings").id

# This migration will likely run before the product feature is seeded so we need to manually insert it otherwise
my_settings_view ||= MiqProductFeature.create_with(
:name => "View",
:description => "View My Settings",
:feature_type => "view",
:protected => false,
:parent_id => my_settings_id,
:hidden => nil,
:tenant_id => nil
).find_or_create_by(
:identifier => "my_settings_view"
)

user_role.miq_product_features << my_settings_view
end
end
end

private

# Bring back all custom user roles that have the given feature_identifiers
def roles_with_features(feature_identifiers)
MiqUserRole
.joins(:miq_product_features)
.where(:read_only => false, :miq_product_features => {:identifier => feature_identifiers})
end
end
122 changes: 122 additions & 0 deletions spec/migrations/20231114223004_add_my_settings_view_to_roles_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
require_migration

describe AddMySettingsViewToRoles do
migration_context :up do
let(:user_role_stub) { migration_stub(:MiqUserRole) }
let(:product_feature_stub) { migration_stub(:MiqProductFeature) }

let!(:my_settings_base) { product_feature_stub.create!(:feature_type => "node", :identifier => "my_settings") }
let!(:my_settings_other) { product_feature_stub.create!(:feature_type => "admin", :identifier => "my_settings_visuals", :parent_id => my_settings_base.id) }

let(:my_settings_view) do
product_feature_stub
.create_with(:feature_type => "view", :identifier => "my_settings_view", :parent_id => my_settings_base.id)
.find_or_create_by(:identifier => "my_settings_view")
end

let!(:seeded_user_role) { user_role_stub.create!(:miq_product_features => [my_settings_other], :read_only => true) }

it "does nothing if there aren't any custom user roles" do
migrate

expect(seeded_user_role.miq_product_features).to match_array([my_settings_other]) # unchanged
expect(product_feature_stub.where(:identifier => "my_settings_view")).to_not exist
end

it "updates custom user roles with a my_settings_* feature" do
custom_user_role = user_role_stub.create!(:miq_product_features => [my_settings_other], :read_only => false)

migrate

custom_user_role.reload
seeded_user_role.reload
expect(custom_user_role.miq_product_features).to match_array([my_settings_other, my_settings_view])
expect(seeded_user_role.miq_product_features).to match_array([my_settings_other]) # unchanged

expect(product_feature_stub.where(:identifier => "my_settings_view")).to exist
expect(product_feature_stub.where(:identifier => "my_settings_view")).to match_array([my_settings_view])
end

it "skips custom user roles with the base my_settings feature" do
custom_user_role = user_role_stub.create!(:miq_product_features => [my_settings_base], :read_only => false)

migrate

custom_user_role.reload
seeded_user_role.reload
expect(custom_user_role.miq_product_features).to match_array([my_settings_base]) # unchanged
expect(seeded_user_role.miq_product_features).to match_array([my_settings_other]) # unchanged

expect(product_feature_stub.where(:identifier => "my_settings_view")).to_not exist
end

it "skips custom user roles with the base my_settings feature and a my_settings_* feature" do # This edge case should not exist, but we handle it anyway
custom_user_role = user_role_stub.create!(:miq_product_features => [my_settings_base, my_settings_other], :read_only => false)

migrate

custom_user_role.reload
seeded_user_role.reload
expect(custom_user_role.miq_product_features).to match_array([my_settings_base, my_settings_other]) # unchanged
expect(seeded_user_role.miq_product_features).to match_array([my_settings_other]) # unchanged

expect(product_feature_stub.where(:identifier => "my_settings_view")).to_not exist
end

context "when my_settings_view already exists" do
before { my_settings_view }

it "updates custom user roles with a my_settings_* feature" do
custom_user_role = user_role_stub.create!(:miq_product_features => [my_settings_other], :read_only => false)

migrate

custom_user_role.reload
seeded_user_role.reload
expect(custom_user_role.miq_product_features).to match_array([my_settings_other, my_settings_view])
expect(seeded_user_role.miq_product_features).to match_array([my_settings_other]) # unchanged

expect(product_feature_stub.where(:identifier => "my_settings_view")).to match_array([my_settings_view])
end

it "handles custom user roles with a my_settings_* feature and already have my_settings_view" do
custom_user_role = user_role_stub.create!(:miq_product_features => [my_settings_other, my_settings_view], :read_only => false)

migrate

custom_user_role.reload
seeded_user_role.reload
expect(custom_user_role.miq_product_features).to match_array([my_settings_other, my_settings_view]) # unchanged
expect(seeded_user_role.miq_product_features).to match_array([my_settings_other]) # unchanged

expect(product_feature_stub.where(:identifier => "my_settings_view")).to match_array([my_settings_view])
end

it "skips custom user roles with the base my_settings feature" do
custom_user_role = user_role_stub.create!(:miq_product_features => [my_settings_base], :read_only => false)

migrate

custom_user_role.reload
seeded_user_role.reload
expect(custom_user_role.miq_product_features).to match_array([my_settings_base]) # unchanged
expect(seeded_user_role.miq_product_features).to match_array([my_settings_other]) # unchanged

expect(product_feature_stub.where(:identifier => "my_settings_view")).to match_array([my_settings_view])
end

it "skips custom user roles with the base my_settings feature and a my_settings_* feature" do # This edge case should not exist, but we handle it anyway
custom_user_role = user_role_stub.create!(:miq_product_features => [my_settings_base, my_settings_other], :read_only => false)

migrate

custom_user_role.reload
seeded_user_role.reload
expect(custom_user_role.miq_product_features).to match_array([my_settings_base, my_settings_other]) # unchanged
expect(seeded_user_role.miq_product_features).to match_array([my_settings_other]) # unchanged

expect(product_feature_stub.where(:identifier => "my_settings_view")).to match_array([my_settings_view])
end
end
end
end

0 comments on commit 93d1be4

Please sign in to comment.