docbrown/app/models/admin_menu.rb
Daniel Uber 4225819ae0
Fixes flaky spec (#13637)
When we call Hash.dup the values pointed to by the keys are not
duplicated (the hash is, but the keys and values are the same).

Because the FeatureFlag enabled path is mutating the values, this is
interacting during tests.

`deep_dup` the ITEMS hash before mutating when the either of the two
menu item feature flags are enabled.
2021-05-03 15:06:18 -05:00

109 lines
3.7 KiB
Ruby

# This "model" is not backed by the database. Its main purpose is to
# setup and provide methods to interact with the admin sidebar and tabbed menu
class AdminMenu
# On second level navigation with more children, we reference the default tabs controller. i.e look at developer_tools
# rubocop:disable Metrics/BlockLength
ITEMS = Menu.define do
scope :people, "group-2-line", [
item(name: "people", controller: "users"),
]
scope :content_manager, "dashboard-line", [
item(name: "posts", controller: "articles"),
item(name: "badges", children: [
item(name: "library", controller: "badges"),
item(name: "achievements", controller: "badge_achievements"),
]),
item(name: "organizations"),
item(name: "podcasts"),
item(name: "tags"),
]
scope :customization, "tools-line", [
item(name: "config"),
item(name: "html variants", controller: "html_variants"),
item(name: "display ads"),
item(name: "navigation links"),
item(name: "pages"),
item(name: "profile fields", visible: false),
]
scope :admin_team, "user-line", [
item(name: "admin team", controller: "permissions"),
]
scope :moderation, "shield-flash-line", [
item(name: "reports"),
item(name: "mods"),
item(name: "moderator actions ads", controller: "moderator_actions"),
item(name: "privileged reactions"),
# item(name: "interaction limits")
]
scope :advanced, "flashlight-line", [
item(name: "broadcasts"),
item(name: "response templates"),
item(name: "sponsorships"),
item(name: "developer tools", controller: "tools", children: [
item(name: "tools"),
item(name: "vault secrets", controller: "secrets"),
item(name: "webhooks", controller: "webhook_endpoints"),
item(name: "data update scripts", visible: false),
]),
]
scope :apps, "palette-line", [
item(name: "chat channels"),
item(name: "events"),
item(name: "listings"),
item(name: "welcome"),
]
end.freeze
# rubocop:enable Metrics/BlockLength
def self.navigation_items
return ITEMS unless FeatureFlag.enabled?(:profile_admin) || FeatureFlag.enabled?(:data_update_scripts)
feature_flagged_menu_items
end
def self.nested_menu_items(scope_name, nav_item)
return unless navigation_items.dig(scope_name.to_sym, :children)
navigation_items.dig(scope_name.to_sym, :children).each do |items|
return items if items[:controller] == nav_item
next unless items[:children]&.any?
items[:children].each do |child|
return items if child[:controller] == nav_item
end
end
end
def self.nested_menu_items_from_request(request)
scope, nav_item = request.path.split("/").last(2)
nested_menu_items(scope, nav_item)
end
def self.feature_flagged_menu_items
# We default to creating a ITEMS constant with visibility set to false
# and then simply amend the visibility of the feature flag when it's
# turned on, instead of creating the payload dynamically each time.
menu_items = ITEMS.deep_dup
if FeatureFlag.enabled?(:profile_admin)
profile_hash = menu_items.dig(:customization, :children).detect { |item| item[:controller] == "profile_fields" }
profile_hash[:visible] = true
end
if FeatureFlag.enabled?(:data_update_scripts)
data_update_script_hash = menu_items.dig(:advanced, :children)
.detect { |item| item[:controller] == "tools" }[:children]
.detect { |item| item[:controller] == "data_update_scripts" }
data_update_script_hash[:visible] = true
end
menu_items
end
end