Refactor handling of mandatory settings (#13553)
* Refactor handling of mandatory settings * Add e2e test * Rename controller
This commit is contained in:
parent
69597a6b7d
commit
3837c3a221
8 changed files with 158 additions and 16 deletions
|
|
@ -0,0 +1,45 @@
|
|||
module Admin
|
||||
module Settings
|
||||
class MandatorySettingsController < Admin::ApplicationController
|
||||
def create
|
||||
errors = upsert_config(settings_params)
|
||||
|
||||
if errors.none?
|
||||
Audit::Logger.log(:internal, current_user, params.dup)
|
||||
redirect_to admin_config_path, notice: "Site configuration was successfully updated."
|
||||
else
|
||||
redirect_to admin_config_path, alert: "😭 #{errors.to_sentence}"
|
||||
end
|
||||
end
|
||||
|
||||
def upsert_config(configs)
|
||||
errors = []
|
||||
configs.each do |key, value|
|
||||
settings_model = ::Settings::Mandatory::MAPPINGS[key.to_sym]
|
||||
if value.is_a?(Array)
|
||||
settings_model.public_send("#{key}=", value.reject(&:blank?)) if value.present?
|
||||
else
|
||||
settings_model.public_send("#{key}=", value.strip) unless value.nil?
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
errors << e.message
|
||||
next
|
||||
end
|
||||
|
||||
errors
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# NOTE: we need to override this since the controller name doesn't reflect
|
||||
# the model name
|
||||
def authorization_resource
|
||||
::Settings::Mandatory
|
||||
end
|
||||
|
||||
def settings_params
|
||||
params.permit(::Settings::Mandatory.keys)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,14 +4,6 @@ module VerifySetupCompleted
|
|||
|
||||
module_function
|
||||
|
||||
MANDATORY_CONFIGS = {
|
||||
community_name: Settings::Community,
|
||||
community_description: Settings::Community,
|
||||
|
||||
suggested_tags: SiteConfig,
|
||||
suggested_users: SiteConfig
|
||||
}.freeze
|
||||
|
||||
included do
|
||||
# rubocop:disable Rails/LexicallyScopedActionFilter
|
||||
before_action :verify_setup_completed, only: %i[index new edit show]
|
||||
|
|
@ -23,9 +15,7 @@ module VerifySetupCompleted
|
|||
end
|
||||
|
||||
def missing_configs
|
||||
@missing_configs ||= MANDATORY_CONFIGS.reject do |config, settings_model|
|
||||
settings_model.public_send(config).present?
|
||||
end.keys
|
||||
@missing_configs ||= Settings::Mandatory.missing
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ module ApplicationHelper
|
|||
def admin_config_label(method, content = nil, model: SiteConfig)
|
||||
content ||= tag.span(method.to_s.humanize)
|
||||
|
||||
if method.to_sym.in?(VerifySetupCompleted::MANDATORY_CONFIGS)
|
||||
if method.to_sym.in?(Settings::Mandatory.keys)
|
||||
required = tag.span("Required", class: "crayons-indicator crayons-indicator--critical")
|
||||
content = safe_join([content, required])
|
||||
end
|
||||
|
|
|
|||
28
app/models/settings/mandatory.rb
Normal file
28
app/models/settings/mandatory.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
module Settings
|
||||
# We use this model to back the "Get Started" form of the config admin page.
|
||||
class Mandatory
|
||||
include ActiveModel::Naming
|
||||
|
||||
MAPPINGS = {
|
||||
community_name: Settings::Community,
|
||||
community_description: Settings::Community,
|
||||
|
||||
suggested_tags: SiteConfig,
|
||||
suggested_users: SiteConfig
|
||||
}.freeze
|
||||
|
||||
MAPPINGS.each do |setting, settings_model|
|
||||
delegate setting, "#{setting}=", to: settings_model
|
||||
end
|
||||
|
||||
def self.keys
|
||||
MAPPINGS.keys
|
||||
end
|
||||
|
||||
def self.missing
|
||||
MAPPINGS.reject do |settings, settings_model|
|
||||
settings_model.public_send(settings).present?
|
||||
end.keys
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -33,10 +33,10 @@
|
|||
class="<%= VerifySetupCompleted.setup_completed? ? "hide collapse" : "show expand" %> p-3"
|
||||
aria-labelledby="getStartedHeader">
|
||||
|
||||
<%= form_for(SiteConfig.new, url: admin_config_path) do |f| %>
|
||||
<%= form_with(url: admin_settings_mandatory_settings_path, local: true, data: { testid: "getStartedSectionForm" }) do |f| %>
|
||||
<fieldset class="grid gap-4">
|
||||
|
||||
<% VerifySetupCompleted::MANDATORY_CONFIGS.each do |config_key, settings_model| %>
|
||||
<% Settings::Mandatory::MAPPINGS.each do |config_key, settings_model| %>
|
||||
<%# we need to list the config as separate fields if the data structure is a Hash %>
|
||||
<% placeholder_module = Constants.const_get(settings_model.name) %>
|
||||
<% if settings_model.public_send(config_key).is_a?(Hash) %>
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
<%= a_field.text_field key,
|
||||
class: "crayons-textfield",
|
||||
value: settings_model.public_send(config_key)[key],
|
||||
placeholder: placeholer_module::DETAILS[config_key][:placeholder] %>
|
||||
placeholder: placeholder_module::DETAILS[config_key][:placeholder] %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ Rails.application.routes.draw do
|
|||
resources :authentications, only: [:create]
|
||||
resources :campaigns, only: [:create]
|
||||
resources :communities, only: [:create]
|
||||
resources :mandatory_settings, only: [:create]
|
||||
resources :mascots, only: [:create]
|
||||
resources :rate_limits, only: [:create]
|
||||
resources :user_experiences, only: [:create]
|
||||
|
|
|
|||
78
cypress/integration/adminFlows/config/getStartedSection.js
Normal file
78
cypress/integration/adminFlows/config/getStartedSection.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
describe('Get Started Section', () => {
|
||||
beforeEach(() => {
|
||||
cy.testSetup();
|
||||
cy.fixture('users/adminUser.json').as('user');
|
||||
|
||||
cy.get('@user').then((user) => {
|
||||
cy.loginUser(user);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Community name setting', () => {
|
||||
it('updates the community name', () => {
|
||||
cy.get('@user').then(({ username }) => {
|
||||
cy.visit('/admin/config');
|
||||
|
||||
cy.findByTestId('getStartedSectionForm').as('getStartedSectionForm');
|
||||
|
||||
cy.get('@getStartedSectionForm')
|
||||
.get('#community_name')
|
||||
.clear()
|
||||
.type('Awesome community');
|
||||
|
||||
cy.get('@getStartedSectionForm')
|
||||
.findByPlaceholderText('Confirmation text')
|
||||
.type(
|
||||
`My username is @${username} and this action is 100% safe and appropriate.`,
|
||||
);
|
||||
|
||||
cy.get('@getStartedSectionForm')
|
||||
.findByText('Update Site Configuration')
|
||||
.click();
|
||||
|
||||
cy.url().should('contains', '/admin/config');
|
||||
|
||||
cy.findByText('Site configuration was successfully updated.').should(
|
||||
'be.visible',
|
||||
);
|
||||
|
||||
// Page reloaded so need to get a new reference to the form.
|
||||
cy.findByTestId('getStartedSectionForm').as('getStartedSectionForm');
|
||||
cy.get('#community_name').should('have.value', 'Awesome community');
|
||||
});
|
||||
});
|
||||
|
||||
it('updates the suggested tags', () => {
|
||||
cy.get('@user').then(({ username }) => {
|
||||
cy.visit('/admin/config');
|
||||
|
||||
cy.findByTestId('getStartedSectionForm').as('getStartedSectionForm');
|
||||
|
||||
cy.get('@getStartedSectionForm')
|
||||
.get('#suggested_tags')
|
||||
.clear()
|
||||
.type('much tag, so wow');
|
||||
|
||||
cy.get('@getStartedSectionForm')
|
||||
.findByPlaceholderText('Confirmation text')
|
||||
.type(
|
||||
`My username is @${username} and this action is 100% safe and appropriate.`,
|
||||
);
|
||||
|
||||
cy.get('@getStartedSectionForm')
|
||||
.findByText('Update Site Configuration')
|
||||
.click();
|
||||
|
||||
cy.url().should('contains', '/admin/config');
|
||||
|
||||
cy.findByText('Site configuration was successfully updated.').should(
|
||||
'be.visible',
|
||||
);
|
||||
|
||||
// Page reloaded so need to get a new reference to the form.
|
||||
cy.findByTestId('getStartedSectionForm').as('getStartedSectionForm');
|
||||
cy.get('#suggested_tags').should('have.value', 'much tag,so wow');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -8,7 +8,7 @@ RSpec.describe "Admin manages configuration", type: :system do
|
|||
visit admin_config_path
|
||||
end
|
||||
|
||||
VerifySetupCompleted::MANDATORY_CONFIGS.each do |option, _setting_model|
|
||||
Settings::Mandatory::MAPPINGS.each do |option, _setting_model|
|
||||
it "marks #{option} as required" do
|
||||
selector = "label[for='site_config_#{option}']"
|
||||
expect(first(selector).text).to include("Required")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue