Add feature flag for profile admin section (#11149)

* Add feature flag for profile admin section

* Fix spec description

* Also remove profile admin link from sidebar

* Disable profile admin routes based on feature flag

* Minor fixes

* Remove unnecessary object from spec

* Refactor AdminHelper

* Fix specs

* Fix remaining specs
This commit is contained in:
Michael Kohl 2020-11-02 08:48:18 +07:00 committed by GitHub
parent 8578fdc358
commit 7b6c5b60c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 133 additions and 39 deletions

View file

@ -3,41 +3,6 @@ module Admin
before_action :authorize_admin
after_action :verify_authorized
# This is used in app/views/admin/shared/_navbar.html.erb to build the
# side navbar in alphabetical order.
MENU_ITEMS = [
{ name: "articles", controller: "articles" },
{ name: "broadcasts", controller: "broadcasts" },
{ name: "badges", controller: "badges" },
{ name: "badge_achievements", controller: "badge_achievements" },
{ name: "chat_channels", controller: "chat_channels" },
{ name: "comments", controller: "comments" },
{ name: "config", controller: "config" },
{ name: "display_ads", controller: "display_ads" },
{ name: "events", controller: "events" },
{ name: "growth", controller: "growth" },
{ name: "html_variants", controller: "html_variants" },
{ name: "listings", controller: "listings" },
{ name: "moderator_actions", controller: "moderator_actions" },
{ name: "mods", controller: "mods" },
{ name: "navigation_links", controller: "navigation_links" },
{ name: "privileged_reactions", controller: "privileged_reactions" },
{ name: "organizations", controller: "organizations" },
{ name: "pages", controller: "pages" },
{ name: "permissions", controller: "permissions" },
{ name: "podcasts", controller: "podcasts" },
{ name: "config: profile setup", controller: "profile_fields" },
{ name: "reports", controller: "reports" },
{ name: "response_templates", controller: "response_templates" },
{ name: "sponsorships", controller: "sponsorships" },
{ name: "tags", controller: "tags" },
{ name: "tools", controller: "tools" },
{ name: "users", controller: "users" },
{ name: "vault secrets", controller: "secrets" },
{ name: "webhooks", controller: "webhook_endpoints" },
{ name: "welcome", controller: "welcome" },
].sort_by { |menu_item| menu_item[:name] }.freeze
private
def authorization_resource

View file

@ -0,0 +1,46 @@
module AdminHelper
# This is used in app/views/admin/shared/_navbar.html.erb to build the
# side navbar in alphabetical order. It's also used to display the "menu"
# in app/vews/admin/admin_portals/index.html.erb.
# If you add an item before "config", please update the insert call in
# admin_menu_items below.
MENU_ITEMS = [
{ name: "articles", controller: "articles" },
{ name: "broadcasts", controller: "broadcasts" },
{ name: "badges", controller: "badges" },
{ name: "badge_achievements", controller: "badge_achievements" },
{ name: "chat_channels", controller: "chat_channels" },
{ name: "comments", controller: "comments" },
{ name: "config", controller: "config" },
{ name: "display_ads", controller: "display_ads" },
{ name: "events", controller: "events" },
{ name: "growth", controller: "growth" },
{ name: "html_variants", controller: "html_variants" },
{ name: "listings", controller: "listings" },
{ name: "moderator_actions", controller: "moderator_actions" },
{ name: "mods", controller: "mods" },
{ name: "navigation_links", controller: "navigation_links" },
{ name: "privileged_reactions", controller: "privileged_reactions" },
{ name: "organizations", controller: "organizations" },
{ name: "pages", controller: "pages" },
{ name: "permissions", controller: "permissions" },
{ name: "podcasts", controller: "podcasts" },
{ name: "reports", controller: "reports" },
{ name: "response_templates", controller: "response_templates" },
{ name: "sponsorships", controller: "sponsorships" },
{ name: "tags", controller: "tags" },
{ name: "tools", controller: "tools" },
{ name: "users", controller: "users" },
{ name: "vault secrets", controller: "secrets" },
{ name: "webhooks", controller: "webhook_endpoints" },
{ name: "welcome", controller: "welcome" },
].sort_by { |menu_item| menu_item[:name] }
PROFILE_ADMIN = { name: "config: profile setup", controller: "profile_fields" }.freeze
def admin_menu_items
return MENU_ITEMS unless Flipper.enabled?(:profile_admin)
MENU_ITEMS.dup.insert(7, PROFILE_ADMIN)
end
end

View file

@ -1,5 +1,5 @@
<div class="grid gap-2 m:gap-4 l:gap-6 m:grid-cols-2 l:grid-cols-3 px-2 m:px-0">
<% Admin::ApplicationController::MENU_ITEMS.each do |menu_item| %>
<% admin_menu_items.each do |menu_item| %>
<div class="tag-card crayons-card branded-4 p-4 m:p-6 m:pt-4 flex flex-col relative">
<h3 class="crayons-tag crayons-tag--l mb-2">
<a href="/admin/<%= menu_item[:controller] %>" class="crayons-link">

View file

@ -1,4 +1,4 @@
<% Admin::ApplicationController::MENU_ITEMS.each do |menu_item| %>
<% admin_menu_items.each do |menu_item| %>
<a class="crayons-link crayons-link--block <%= "crayons-link--current" if request.path.split("/")[2].match?(menu_item[:controller]) %>" href="/admin/<%= menu_item[:controller] %>">
<%= menu_item[:name].to_s.titleize %>
</a>

View file

@ -83,8 +83,12 @@ Rails.application.routes.draw do
end
end
resources :profile_field_groups, only: %i[update create destroy]
resources :profile_fields, only: %i[index update create destroy]
# NOTE: @citizen428 The next two resources have a temporary constraint
# while profile generalization is still WIP
constraints(->(_request) { Flipper.enabled?(:profile_admin) }) do
resources :profile_field_groups, only: %i[update create destroy]
resources :profile_fields, only: %i[index update create destroy]
end
resources :reactions, only: [:update]
resources :response_templates, only: %i[index new edit create update destroy]
resources :chat_channels, only: %i[index create update destroy] do

View file

@ -3,6 +3,10 @@ require "rails_helper"
RSpec.describe ProfileFieldGroup, type: :model do
subject { group }
before do
allow(Flipper).to receive(:enabled?).with(:profile_admin).and_return(true)
end
let!(:group) { create(:profile_field_group) }
it { is_expected.to have_many(:profile_fields).dependent(:nullify) }

View file

@ -0,0 +1,25 @@
require "rails_helper"
RSpec.describe "/admin", type: :request do
let(:super_admin) { create(:user, :super_admin) }
before { sign_in super_admin }
describe "profile admin feature flag" do
it "shows the option when the feature flag is enabled" do
allow(Flipper).to receive(:enabled?).with(:profile_admin).and_return(true)
get admin_path
expect(response.body).to include("Config: Profile Setup")
end
it "does not show the option when the feature flag is disabled" do
allow(Flipper).to receive(:enabled?).with(:profile_admin).and_return(false)
get admin_path
expect(response.body).not_to include("Config: Profile Setup")
end
end
end

View file

@ -5,6 +5,7 @@ RSpec.describe "/admin/profile_field_groups", type: :request do
before do
sign_in admin
allow(Flipper).to receive(:enabled?).with(:profile_admin).and_return(true)
end
describe "POST /admin/profile_field_groups" do

View file

@ -5,6 +5,7 @@ RSpec.describe "/admin/profile_fields", type: :request do
before do
sign_in admin
allow(Flipper).to receive(:enabled?).with(:profile_admin).and_return(true)
end
describe "GET /admin/profile_fields" do

View file

@ -0,0 +1,25 @@
require "rails_helper"
RSpec.describe "admin sidebar", type: :request do
let(:super_admin) { create(:user, :super_admin) }
before { sign_in super_admin }
describe "profile admin feature flag" do
it "shows the option in the sidebar when the feature flag is enabled" do
allow(Flipper).to receive(:enabled?).with(:profile_admin).and_return(true)
get admin_articles_path
expect(response.body).to include("Config: Profile Setup")
end
it "does not show the option in the sidebar when the feature flag is disabled" do
allow(Flipper).to receive(:enabled?).with(:profile_admin).and_return(false)
get admin_articles_path
expect(response.body).not_to include("Config: Profile Setup")
end
end
end

View file

@ -0,0 +1,23 @@
require "rails_helper"
RSpec.describe "Profile admin routes", type: :routing do
it "renders the profile admin route if the feature flag is enabled" do
allow(Flipper).to receive(:enabled?).with(:profile_admin).and_return(true)
expect(get: admin_profile_fields_path).to route_to(
controller: "admin/profile_fields",
action: "index",
locale: nil,
)
end
it "does not render the profile admin route if the feature flag is disabled" do
allow(Flipper).to receive(:enabled?).with(:profile_admin).and_return(false)
expect(get: admin_profile_fields_path).not_to route_to(
controller: "admin/profile_fields",
action: "index",
locale: nil,
)
end
end