Skip to content

Commit

Permalink
Add my_settings_view to roles
Browse files Browse the repository at this point in the history
  • Loading branch information
Fryguy committed Nov 16, 2023
1 parent 7a159b6 commit e8771c8
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 0 deletions.
48 changes: 48 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,48 @@
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_%").where.not(:identifier => "my_settings_view")
my_settings_id = MiqProductFeature.find_by(:identifier => "my_settings").id

my_settings_view = nil

affected_user_roles(my_settings_features).each do |user_role|
product_features = user_role.miq_product_features.map(&:identifier)

next if product_features.include?("my_settings") || product_features.include?("my_settings_view")

# 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 a my_settings_^% feature
def affected_user_roles(features)
MiqUserRole
.joins(:miq_product_features)
.where(:read_only => false, :miq_product_features => {:identifier => features.map(&:identifier)})
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 e8771c8

Please sign in to comment.