Split Settings::Campaign from SiteConfig (#13238)
This commit is contained in:
parent
daad36d708
commit
a86c178fe0
18 changed files with 335 additions and 125 deletions
22
app/controllers/admin/settings/campaigns_controller.rb
Normal file
22
app/controllers/admin/settings/campaigns_controller.rb
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
module Admin
|
||||
module Settings
|
||||
class CampaignsController < Admin::ApplicationController
|
||||
def create
|
||||
result = ::Campaigns::SettingsUpsert.call(settings_params)
|
||||
|
||||
if result.success?
|
||||
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: "😭 #{result.errors.to_sentence}"
|
||||
end
|
||||
end
|
||||
|
||||
def settings_params
|
||||
params
|
||||
.require(:settings_campaign)
|
||||
.permit(*::Settings::Campaign.keys)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -11,7 +11,7 @@ class SidebarsController < ApplicationController
|
|||
|
||||
def get_latest_campaign_articles
|
||||
campaign_articles_scope = Article.tagged_with(Campaign.current.featured_tags, any: true)
|
||||
.where("published_at > ? AND score > ?", SiteConfig.campaign_articles_expiry_time.weeks.ago, 0)
|
||||
.where("published_at > ? AND score > ?", Settings::Campaign.articles_expiry_time.weeks.ago, 0)
|
||||
.order(hotness_score: :desc)
|
||||
|
||||
requires_approval = Campaign.current.articles_require_approval?
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class StoriesController < ApplicationController
|
|||
|
||||
def get_latest_campaign_articles
|
||||
campaign_articles_scope = Article.tagged_with(Campaign.current.featured_tags, any: true)
|
||||
.where("published_at > ? AND score > ?", SiteConfig.campaign_articles_expiry_time.weeks.ago, 0)
|
||||
.where("published_at > ? AND score > ?", Settings::Campaign.articles_expiry_time.weeks.ago, 0)
|
||||
.order(hotness_score: :desc)
|
||||
|
||||
requires_approval = Campaign.current.articles_require_approval?
|
||||
|
|
|
|||
40
app/lib/constants/settings/campaign.rb
Normal file
40
app/lib/constants/settings/campaign.rb
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
module Constants
|
||||
module Settings
|
||||
module Campaign
|
||||
DETAILS = {
|
||||
articles_expiry_time: {
|
||||
description: "Sets the expiry time for articles (in weeks) to be displayed in campaign sidebar",
|
||||
placeholder: ""
|
||||
},
|
||||
articles_require_approval: {
|
||||
description: "",
|
||||
placeholder: "Campaign stories show up on sidebar with approval?"
|
||||
},
|
||||
call_to_action: {
|
||||
description: "This text populates the call to action button on the campaign sidebar",
|
||||
placeholder: "Share your project"
|
||||
},
|
||||
featured_tags: {
|
||||
description: "Posts with which tags will be featured in the campaign sidebar (comma separated, letters only)",
|
||||
placeholder: "List of campaign tags: comma separated, letters only e.g. shecoded,theycoded"
|
||||
},
|
||||
hero_html_variant_name: {
|
||||
description: "Hero HtmlVariant name",
|
||||
placeholder: ""
|
||||
},
|
||||
sidebar_enabled: {
|
||||
description: "",
|
||||
placeholder: "Campaign sidebar enabled or not"
|
||||
},
|
||||
sidebar_image: {
|
||||
description: ::Constants::SiteConfig::IMAGE_PLACEHOLDER,
|
||||
placeholder: "Used at the top of the campaign sidebar"
|
||||
},
|
||||
url: {
|
||||
description: "https://url.com/lander",
|
||||
placeholder: "URL campaign sidebar image will link to"
|
||||
}
|
||||
}.freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,38 +4,6 @@ module Constants
|
|||
SVG_PLACEHOLDER = "<svg ...></svg>".freeze
|
||||
|
||||
DETAILS = {
|
||||
campaign_articles_require_approval: {
|
||||
description: "",
|
||||
placeholder: "Campaign stories show up on sidebar with approval?"
|
||||
},
|
||||
campaign_call_to_action: {
|
||||
description: "This text populates the call to action button on the campaign sidebar",
|
||||
placeholder: "Share your project"
|
||||
},
|
||||
campaign_featured_tags: {
|
||||
description: "Posts with which tags will be featured in the campaign sidebar (comma separated, letters only)",
|
||||
placeholder: "List of campaign tags: comma separated, letters only e.g. tagone,tagtwo"
|
||||
},
|
||||
campaign_hero_html_variant_name: {
|
||||
description: "Hero HtmlVariant name",
|
||||
placeholder: ""
|
||||
},
|
||||
campaign_sidebar_enabled: {
|
||||
description: "",
|
||||
placeholder: "Campaign sidebar enabled or not"
|
||||
},
|
||||
campaign_sidebar_image: {
|
||||
description: IMAGE_PLACEHOLDER,
|
||||
placeholder: "Used at the top of the campaign sidebar"
|
||||
},
|
||||
campaign_url: {
|
||||
description: "https://url.com/lander",
|
||||
placeholder: "URL campaign sidebar image will link to"
|
||||
},
|
||||
campaign_articles_expiry_time: {
|
||||
description: "Sets the expiry time for articles (in weeks) to be displayed in campaign sidebar",
|
||||
placeholder: ""
|
||||
},
|
||||
community_copyright_start_year: {
|
||||
description: "Used to mark the year this forem was started.",
|
||||
placeholder: Time.zone.today.year.to_s
|
||||
|
|
|
|||
|
|
@ -10,17 +10,16 @@ class Campaign
|
|||
end
|
||||
|
||||
METHODS = %w[
|
||||
hero_html_variant_name
|
||||
articles_require_approval?
|
||||
call_to_action
|
||||
featured_tags
|
||||
hero_html_variant_name
|
||||
sidebar_enabled?
|
||||
sidebar_image
|
||||
url
|
||||
articles_require_approval?
|
||||
call_to_action
|
||||
].freeze
|
||||
|
||||
# Define delegate methods for SiteConfig
|
||||
METHODS.each { |m| define_method(m) { SiteConfig.public_send("campaign_#{m}") } }
|
||||
delegate(*METHODS, to: Settings::Campaign)
|
||||
|
||||
def show_in_sidebar?
|
||||
sidebar_enabled? && sidebar_image.present?
|
||||
|
|
|
|||
19
app/models/settings/campaign.rb
Normal file
19
app/models/settings/campaign.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
module Settings
|
||||
class Campaign < RailsSettings::Base
|
||||
self.table_name = :settings_campaigns
|
||||
|
||||
# The configuration is cached, change this if you want to force update
|
||||
# the cache, or call Settings::Campaign.clear_cache
|
||||
cache_prefix { "v1" }
|
||||
|
||||
# Define your fields
|
||||
field :articles_expiry_time, type: :integer, default: 4
|
||||
field :articles_require_approval, type: :boolean, default: 0
|
||||
field :call_to_action, type: :string, default: "Share your project"
|
||||
field :featured_tags, type: :array, default: %w[]
|
||||
field :hero_html_variant_name, type: :string, default: ""
|
||||
field :sidebar_enabled, type: :boolean, default: 0
|
||||
field :sidebar_image, type: :string, default: nil, validates: { url: true }
|
||||
field :url, type: :string, default: nil
|
||||
end
|
||||
end
|
||||
|
|
@ -11,8 +11,6 @@ class SiteConfig < RailsSettings::Base
|
|||
HEX_COLOR_REGEX = /\A#(\h{6}|\h{3})\z/.freeze
|
||||
LIGHTNING_ICON = File.read(Rails.root.join("app/assets/images/lightning.svg")).freeze
|
||||
STACK_ICON = File.read(Rails.root.join("app/assets/images/stack.svg")).freeze
|
||||
VALID_URL = %r{\A(http|https)://([/|.\w\s-])*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?\z}.freeze
|
||||
URL_MESSAGE = "must be a valid URL".freeze
|
||||
|
||||
# Forem Team
|
||||
# [forem-fix] Remove channel name from SiteConfig
|
||||
|
|
@ -36,18 +34,19 @@ class SiteConfig < RailsSettings::Base
|
|||
}
|
||||
field :authentication_providers, type: :array, default: %w[]
|
||||
|
||||
# NOTE: @citizen428 The whole block of campaign settings will be removed once
|
||||
# we fully migrated to Settings::Campaign across the fleet.
|
||||
# Campaign
|
||||
field :campaign_call_to_action, type: :string, default: "Share your project"
|
||||
field :campaign_hero_html_variant_name, type: :string, default: ""
|
||||
field :campaign_featured_tags, type: :array, default: %w[]
|
||||
field :campaign_sidebar_enabled, type: :boolean, default: 0
|
||||
field :campaign_sidebar_image, type: :string, default: nil, validates: {
|
||||
format: { with: VALID_URL, message: URL_MESSAGE }
|
||||
url: true
|
||||
}
|
||||
field :campaign_url, type: :string, default: nil
|
||||
field :campaign_articles_require_approval, type: :boolean, default: 0
|
||||
field :campaign_articles_expiry_time, type: :integer, default: 4
|
||||
|
||||
# Community Content
|
||||
field :community_name, type: :string, default: ApplicationConfig["COMMUNITY_NAME"] || "New Forem"
|
||||
field :community_emoji, type: :string, default: "🌱", validates: { emoji_only: true }
|
||||
|
|
@ -88,18 +87,16 @@ class SiteConfig < RailsSettings::Base
|
|||
field :main_social_image,
|
||||
type: :string,
|
||||
default: proc { URL.local_image("social-media-cover.png") },
|
||||
validates: { format: { with: VALID_URL, message: URL_MESSAGE } }
|
||||
validates: { url: true }
|
||||
|
||||
field :favicon_url, type: :string, default: proc { URL.local_image("favicon.ico") }
|
||||
field :logo_png,
|
||||
type: :string,
|
||||
default: proc { URL.local_image("icon.png") },
|
||||
validates: { format: { with: VALID_URL, message: URL_MESSAGE } }
|
||||
validates: { url: true }
|
||||
|
||||
field :logo_svg, type: :string
|
||||
field :secondary_logo_url, type: :string, validates: {
|
||||
format: { with: VALID_URL, message: URL_MESSAGE }
|
||||
}
|
||||
field :secondary_logo_url, type: :string, validates: { url: true }
|
||||
|
||||
field :enable_video_upload, type: :boolean, default: false
|
||||
|
||||
|
|
@ -108,11 +105,9 @@ class SiteConfig < RailsSettings::Base
|
|||
field :mascot_image_url,
|
||||
type: :string,
|
||||
default: proc { URL.local_image("mascot.png") },
|
||||
validates: { format: { with: VALID_URL, message: URL_MESSAGE } }
|
||||
validates: { url: true }
|
||||
field :mascot_image_description, type: :string, default: "The community mascot"
|
||||
field :mascot_footer_image_url, type: :string, validates: {
|
||||
format: { with: VALID_URL, message: URL_MESSAGE }
|
||||
}
|
||||
field :mascot_footer_image_url, type: :string, validates: { url: true }
|
||||
field :mascot_footer_image_width, type: :integer, default: 52
|
||||
field :mascot_footer_image_height, type: :integer, default: 120
|
||||
|
||||
|
|
@ -141,9 +136,7 @@ class SiteConfig < RailsSettings::Base
|
|||
field :mailchimp_incoming_webhook_secret, type: :string, default: ""
|
||||
|
||||
# Onboarding
|
||||
field :onboarding_background_image, type: :string, validates: {
|
||||
format: { with: VALID_URL, message: URL_MESSAGE }
|
||||
}
|
||||
field :onboarding_background_image, type: :string, validates: { url: true }
|
||||
field :suggested_tags, type: :array, default: %w[]
|
||||
field :suggested_users, type: :array, default: %w[]
|
||||
field :prefer_manual_suggested_users, type: :boolean, default: false
|
||||
|
|
|
|||
41
app/services/campaigns/settings_upsert.rb
Normal file
41
app/services/campaigns/settings_upsert.rb
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
module Campaigns
|
||||
class SettingsUpsert
|
||||
attr_reader :errors
|
||||
|
||||
def self.call(configs)
|
||||
new(configs).call
|
||||
end
|
||||
|
||||
def initialize(configs)
|
||||
@configs = configs
|
||||
@errors = []
|
||||
end
|
||||
|
||||
def call
|
||||
upsert_configs
|
||||
self
|
||||
end
|
||||
|
||||
def success?
|
||||
@errors.none?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# NOTE: @citizen428 - This was adapted from Settings::Upsert. I'll see if
|
||||
# a pattern for refactoring emerges in the future, but for now I'll leave
|
||||
# this as-is.
|
||||
def upsert_configs
|
||||
@configs.each do |key, value|
|
||||
if value.is_a?(Array) && value.any?
|
||||
Settings::Campaign.public_send("#{key}=", value.reject(&:blank?))
|
||||
elsif value.present?
|
||||
Settings::Campaign.public_send("#{key}=", value.strip)
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
@errors << e.message
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -363,7 +363,7 @@
|
|||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= form_for(SiteConfig.new, url: admin_config_path) do |f| %>
|
||||
<%= form_for(Settings::Campaign.new, url: admin_settings_campaigns_path) do |f| %>
|
||||
<div class="card mt-3">
|
||||
<%= render partial: "admin/shared/card_header",
|
||||
locals: {
|
||||
|
|
@ -375,76 +375,76 @@
|
|||
<div id="campaignBodyContainer" class="card-body collapse hide" aria-labelledby="campaignBodyContainer">
|
||||
<fieldset class="grid gap-4">
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :campaign_hero_html_variant_name, "Campaign hero HTML variant name" %>
|
||||
<%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_hero_html_variant_name][:description] %>
|
||||
<%= f.text_field :campaign_hero_html_variant_name,
|
||||
<%= admin_config_label :hero_html_variant_name, "Campaign hero HTML variant name" %>
|
||||
<%= admin_config_description Constants::Settings::Campaign::DETAILS[:hero_html_variant_name][:description] %>
|
||||
<%= f.text_field :hero_html_variant_name,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.campaign_hero_html_variant_name,
|
||||
placeholder: Constants::SiteConfig::DETAILS[:campaign_hero_html_variant_name][:placeholder] %>
|
||||
value: Settings::Campaign.hero_html_variant_name,
|
||||
placeholder: Constants::Settings::Campaign::DETAILS[:hero_html_variant_name][:placeholder] %>
|
||||
</div>
|
||||
|
||||
<div class="crayons-field crayons-field--checkbox">
|
||||
<%= f.check_box :campaign_articles_require_approval, checked: SiteConfig.campaign_articles_require_approval, class: "crayons-checkbox" %>
|
||||
<%= admin_config_label :campaign_articles_require_approval %>
|
||||
<%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_articles_require_approval][:description] %>
|
||||
<%= f.check_box :articles_require_approval, checked: Settings::Campaign.articles_require_approval, class: "crayons-checkbox" %>
|
||||
<%= admin_config_label :articles_require_approval %>
|
||||
<%= admin_config_description Constants::Settings::Campaign::DETAILS[:articles_require_approval][:description] %>
|
||||
</div>
|
||||
|
||||
<div class="crayons-field crayons-field--checkbox">
|
||||
<%= f.check_box :campaign_sidebar_enabled, checked: SiteConfig.campaign_sidebar_enabled, class: "crayons-checkbox" %>
|
||||
<%= admin_config_label :campaign_sidebar_enabled %>
|
||||
<%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_sidebar_enabled][:description] %>
|
||||
<%= f.check_box :sidebar_enabled, checked: Settings::Campaign.sidebar_enabled, class: "crayons-checkbox" %>
|
||||
<%= admin_config_label :sidebar_enabled %>
|
||||
<%= admin_config_description Constants::Settings::Campaign::DETAILS[:sidebar_enabled][:description] %>
|
||||
</div>
|
||||
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :campaign_sidebar_image %>
|
||||
<%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_sidebar_image][:description] %>
|
||||
<% if SiteConfig.campaign_sidebar_image.present? %>
|
||||
<%= admin_config_label :sidebar_image %>
|
||||
<%= admin_config_description Constants::Settings::Campaign::DETAILS[:sidebar_image][:description] %>
|
||||
<% if Settings::Campaign.sidebar_image.present? %>
|
||||
<div class="row mt-2">
|
||||
<div class="col-12">
|
||||
<img alt="Campaign sidebar image" class="img-fluid" src="<%= SiteConfig.campaign_sidebar_image %>" />
|
||||
<img alt="Campaign sidebar image" class="img-fluid" src="<%= Settings::Campaign.sidebar_image %>" />
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= f.text_field :campaign_sidebar_image,
|
||||
<%= f.text_field :sidebar_image,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.campaign_sidebar_image,
|
||||
placeholder: Constants::SiteConfig::DETAILS[:campaign_sidebar_image][:placeholder] %>
|
||||
value: Settings::Campaign.sidebar_image,
|
||||
placeholder: Constants::Settings::Campaign::DETAILS[:sidebar_image][:placeholder] %>
|
||||
</div>
|
||||
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :campaign_url, "Campaign URL" %>
|
||||
<%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_url][:description] %>
|
||||
<%= f.text_field :campaign_url,
|
||||
<%= admin_config_label :url, "Campaign URL" %>
|
||||
<%= admin_config_description Constants::Settings::Campaign::DETAILS[:url][:description] %>
|
||||
<%= f.text_field :url,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.campaign_url,
|
||||
placeholder: Constants::SiteConfig::DETAILS[:campaign_url][:placeholder] %>
|
||||
value: Settings::Campaign.url,
|
||||
placeholder: Constants::Settings::Campaign::DETAILS[:url][:placeholder] %>
|
||||
</div>
|
||||
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :campaign_featured_tags %>
|
||||
<%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_featured_tags][:description] %>
|
||||
<%= f.text_field :campaign_featured_tags,
|
||||
<%= admin_config_label :featured_tags %>
|
||||
<%= admin_config_description Constants::Settings::Campaign::DETAILS[:featured_tags][:description] %>
|
||||
<%= f.text_field :featured_tags,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.campaign_featured_tags.join(","),
|
||||
placeholder: Constants::SiteConfig::DETAILS[:campaign_featured_tags][:placeholder] %>
|
||||
value: Settings::Campaign.featured_tags.join(","),
|
||||
placeholder: Constants::Settings::Campaign::DETAILS[:featured_tags][:placeholder] %>
|
||||
</div>
|
||||
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :campaign_call_to_action, "Campaign Call to Action" %>
|
||||
<%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_call_to_action][:description] %>
|
||||
<%= f.text_field :campaign_call_to_action,
|
||||
<%= admin_config_label :call_to_action, "Campaign Call to Action" %>
|
||||
<%= admin_config_description Constants::Settings::Campaign::DETAILS[:call_to_action][:description] %>
|
||||
<%= f.text_field :call_to_action,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.campaign_call_to_action,
|
||||
placeholder: Constants::SiteConfig::DETAILS[:campaign_call_to_action][:placeholder] %>
|
||||
value: Settings::Campaign.call_to_action,
|
||||
placeholder: Constants::Settings::Campaign::DETAILS[:call_to_action][:placeholder] %>
|
||||
</div>
|
||||
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :campaign_articles_expiry_time, "Campaign article expiry time" %>
|
||||
<%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_articles_expiry_time][:description] %>
|
||||
<%= f.number_field :campaign_articles_expiry_time,
|
||||
<%= admin_config_label :articles_expiry_time, "Campaign article expiry time" %>
|
||||
<%= admin_config_description Constants::Settings::Campaign::DETAILS[:articles_expiry_time][:description] %>
|
||||
<%= f.number_field :articles_expiry_time,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.campaign_articles_expiry_time,
|
||||
placeholder: Constants::SiteConfig::DETAILS[:campaign_articles_expiry_time][:placeholder] %>
|
||||
value: Settings::Campaign.articles_expiry_time,
|
||||
placeholder: Constants::Settings::Campaign::DETAILS[:articles_expiry_time][:placeholder] %>
|
||||
</div>
|
||||
|
||||
<%= render "form_submission", f: f %>
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ Rails.application.routes.draw do
|
|||
resources :reactions, only: [:update]
|
||||
namespace :settings do
|
||||
resources :authentications, only: [:create]
|
||||
resources :campaigns, only: [:create]
|
||||
end
|
||||
namespace :users do
|
||||
resources :gdpr_delete_requests, only: %i[index destroy]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
describe('Campaign Section', () => {
|
||||
beforeEach(() => {
|
||||
cy.testSetup();
|
||||
cy.fixture('users/adminUser.json').as('user');
|
||||
|
||||
cy.get('@user').then((user) => {
|
||||
cy.loginUser(user);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sidebar image setting', () => {
|
||||
it('rejects an invalid image URL', () => {
|
||||
cy.get('@user').then(({ username }) => {
|
||||
cy.visit('/admin/config');
|
||||
cy.get('#new_settings_campaign').as('campaignSectionForm');
|
||||
|
||||
cy.get('@campaignSectionForm').findByText('Campaign').click();
|
||||
cy.get('@campaignSectionForm')
|
||||
.findByPlaceholderText('Used at the top of the campaign sidebar')
|
||||
.type('example.com/image.png');
|
||||
|
||||
cy.get('@campaignSectionForm')
|
||||
.findByPlaceholderText('Confirmation text')
|
||||
.type(
|
||||
`My username is @${username} and this action is 100% safe and appropriate.`,
|
||||
);
|
||||
|
||||
cy.get('@campaignSectionForm')
|
||||
.findByText('Update Site Configuration')
|
||||
.click();
|
||||
|
||||
cy.url().should('contains', '/admin/config');
|
||||
|
||||
cy.findByText(
|
||||
'😭 Validation failed: Sidebar image is not a valid URL',
|
||||
).should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts a valid image URL', () => {
|
||||
cy.get('@user').then(({ username }) => {
|
||||
cy.visit('/admin/config');
|
||||
cy.get('#new_settings_campaign').as('campaignSectionForm');
|
||||
|
||||
cy.get('@campaignSectionForm').findByText('Campaign').click();
|
||||
cy.get('@campaignSectionForm')
|
||||
.findByPlaceholderText('Used at the top of the campaign sidebar')
|
||||
.type('https://example.com/image.png');
|
||||
|
||||
cy.get('@campaignSectionForm')
|
||||
.findByPlaceholderText('Confirmation text')
|
||||
.type(
|
||||
`My username is @${username} and this action is 100% safe and appropriate.`,
|
||||
);
|
||||
|
||||
cy.get('@campaignSectionForm')
|
||||
.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.get('#new_settings_campaign').as('campaignSectionForm');
|
||||
cy.get('#settings_campaign_sidebar_image').should(
|
||||
'have.value',
|
||||
'https://example.com/image.png',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
16
db/migrate/20210405032815_create_settings_campaigns.rb
Normal file
16
db/migrate/20210405032815_create_settings_campaigns.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
class CreateSettingsCampaigns < ActiveRecord::Migration[6.0]
|
||||
def self.up
|
||||
create_table :settings_campaigns do |t|
|
||||
t.string :var, null: false
|
||||
t.text :value, null: true
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :settings_campaigns, :var, unique: true
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :settings_campaigns
|
||||
end
|
||||
end
|
||||
|
|
@ -1058,6 +1058,14 @@ ActiveRecord::Schema.define(version: 2021_04_07_172628) do
|
|||
t.index ["var"], name: "index_settings_authentications_on_var", unique: true
|
||||
end
|
||||
|
||||
create_table "settings_campaigns", force: :cascade do |t|
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
t.datetime "updated_at", precision: 6, null: false
|
||||
t.text "value"
|
||||
t.string "var", null: false
|
||||
t.index ["var"], name: "index_settings_campaigns_on_var", unique: true
|
||||
end
|
||||
|
||||
create_table "site_configs", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
module DataUpdateScripts
|
||||
class MoveCampaignSettings
|
||||
CAMPAIGN_SETTINGS = %w[
|
||||
articles_expiry_time
|
||||
articles_require_approval
|
||||
call_to_action
|
||||
featured_tags
|
||||
hero_html_variant_name
|
||||
sidebar_enabled
|
||||
sidebar_image
|
||||
url
|
||||
].freeze
|
||||
|
||||
def run
|
||||
return if Settings::Campaign.any?
|
||||
|
||||
# All these fields got renamed so we migrate them explicitly
|
||||
CAMPAIGN_SETTINGS.each do |setting|
|
||||
Settings::Campaign.public_send(
|
||||
"#{setting}=",
|
||||
SiteConfig.public_send("campaign_#{setting}"),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -5,7 +5,7 @@ RSpec.describe SiteConfig, type: :model do
|
|||
describe "validating URLs" do
|
||||
let(:url_fields) do
|
||||
%w[
|
||||
campaign_sidebar_image main_social_image logo_png secondary_logo_url
|
||||
main_social_image logo_png secondary_logo_url
|
||||
mascot_image_url mascot_footer_image_url onboarding_background_image
|
||||
]
|
||||
end
|
||||
|
|
@ -22,7 +22,7 @@ RSpec.describe SiteConfig, type: :model do
|
|||
url_fields.each do |attribute|
|
||||
expect do
|
||||
described_class.public_send("#{attribute}=", "example.com")
|
||||
end.to raise_error(/must be a valid URL/)
|
||||
end.to raise_error(/is not a valid URL/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -85,14 +85,6 @@ RSpec.describe "/admin/config", type: :request do
|
|||
expect(Settings::Authentication.providers).to eq([enabled])
|
||||
end
|
||||
|
||||
describe "Campaigns" do
|
||||
it "sets campaign_articles_expiry_time" do
|
||||
post "/admin/config", params: { site_config: { campaign_articles_expiry_time: 4 },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.campaign_articles_expiry_time).to eq(4)
|
||||
end
|
||||
end
|
||||
|
||||
it "strips empty elements" do
|
||||
provider = Authentication::Providers.available.last.to_s
|
||||
enabled = "#{provider}, '', nil"
|
||||
|
|
@ -190,6 +182,16 @@ RSpec.describe "/admin/config", type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
describe "Campaigns" do
|
||||
it "sets articles_expiry_time" do
|
||||
post admin_settings_campaigns_path, params: {
|
||||
settings_campaign: { articles_expiry_time: 4 },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(Settings::Campaign.articles_expiry_time).to eq(4)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Community Content" do
|
||||
it "updates the community_description" do
|
||||
allow(SiteConfig).to receive(:community_description).and_call_original
|
||||
|
|
|
|||
|
|
@ -174,21 +174,21 @@ RSpec.describe "StoriesIndex", type: :request do
|
|||
end
|
||||
|
||||
it "displays hero html when it exists and is set in config" do
|
||||
allow(SiteConfig).to receive(:campaign_hero_html_variant_name).and_return("hero")
|
||||
allow(Settings::Campaign).to receive(:hero_html_variant_name).and_return("hero")
|
||||
|
||||
get root_path
|
||||
expect(response.body).to include(hero_html.html)
|
||||
end
|
||||
|
||||
it "doesn't display when campaign_hero_html_variant_name is not set" do
|
||||
allow(SiteConfig).to receive(:campaign_hero_html_variant_name).and_return("")
|
||||
it "doesn't display when hero_html_variant_name is not set" do
|
||||
allow(Settings::Campaign).to receive(:hero_html_variant_name).and_return("")
|
||||
|
||||
get root_path
|
||||
expect(response.body).not_to include(hero_html.html)
|
||||
end
|
||||
|
||||
it "doesn't display when hero html is not approved" do
|
||||
allow(SiteConfig).to receive(:campaign_hero_html_variant_name).and_return("hero")
|
||||
allow(Settings::Campaign).to receive(:hero_html_variant_name).and_return("hero")
|
||||
hero_html.update_column(:approved, false)
|
||||
|
||||
get root_path
|
||||
|
|
@ -198,7 +198,7 @@ RSpec.describe "StoriesIndex", type: :request do
|
|||
|
||||
context "with campaign_sidebar" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:campaign_featured_tags).and_return("mytag,yourtag")
|
||||
allow(Settings::Campaign).to receive(:featured_tags).and_return("mytag,yourtag")
|
||||
allow(SiteConfig).to receive(:home_feed_minimum_score).and_return(7)
|
||||
|
||||
a_body = "---\ntitle: Super-sheep#{rand(1000)}\npublished: true\ntags: heyheyhey,mytag\n---\n\nHello"
|
||||
|
|
@ -208,52 +208,52 @@ RSpec.describe "StoriesIndex", type: :request do
|
|||
end
|
||||
|
||||
it "doesn't display posts with the campaign tags when sidebar is disabled" do
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_enabled).and_return(false)
|
||||
allow(Settings::Campaign).to receive(:sidebar_enabled).and_return(false)
|
||||
get "/"
|
||||
expect(response.body).not_to include(CGI.escapeHTML("Super-sheep"))
|
||||
end
|
||||
|
||||
it "doesn't display low-score posts" do
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_enabled).and_return(true)
|
||||
allow(SiteConfig).to receive(:campaign_articles_require_approval).and_return(true)
|
||||
allow(Settings::Campaign).to receive(:sidebar_enabled).and_return(true)
|
||||
allow(Settings::Campaign).to receive(:articles_require_approval).and_return(true)
|
||||
get "/"
|
||||
expect(response.body).not_to include(CGI.escapeHTML("Unapproved-post"))
|
||||
end
|
||||
|
||||
it "doesn't display unapproved posts" do
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_enabled).and_return(true)
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_image).and_return("https://example.com/image.png")
|
||||
allow(SiteConfig).to receive(:campaign_articles_require_approval).and_return(true)
|
||||
allow(Settings::Campaign).to receive(:sidebar_enabled).and_return(true)
|
||||
allow(Settings::Campaign).to receive(:sidebar_image).and_return("https://example.com/image.png")
|
||||
allow(Settings::Campaign).to receive(:articles_require_approval).and_return(true)
|
||||
Article.last.update_column(:score, -2)
|
||||
get "/"
|
||||
expect(response.body).not_to include(CGI.escapeHTML("Unapproved-post"))
|
||||
end
|
||||
|
||||
it "displays unapproved post if approval is not required" do
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_enabled).and_return(true)
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_image).and_return("https://example.com/image.png")
|
||||
allow(SiteConfig).to receive(:campaign_articles_require_approval).and_return(false)
|
||||
allow(Settings::Campaign).to receive(:sidebar_enabled).and_return(true)
|
||||
allow(Settings::Campaign).to receive(:sidebar_image).and_return("https://example.com/image.png")
|
||||
allow(Settings::Campaign).to receive(:articles_require_approval).and_return(false)
|
||||
get "/"
|
||||
expect(response.body).to include(CGI.escapeHTML("Unapproved-post"))
|
||||
end
|
||||
|
||||
it "displays only approved posts with the campaign tags" do
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_enabled).and_return(false)
|
||||
allow(Settings::Campaign).to receive(:sidebar_enabled).and_return(false)
|
||||
get "/"
|
||||
expect(response.body).not_to include(CGI.escapeHTML("Super-puper"))
|
||||
end
|
||||
|
||||
it "displays sidebar url if campaign_url is set" do
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_enabled).and_return(true)
|
||||
allow(SiteConfig).to receive(:campaign_url).and_return("https://campaign-lander.com")
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_image).and_return("https://example.com/image.png")
|
||||
it "displays sidebar url if url is set" do
|
||||
allow(Settings::Campaign).to receive(:sidebar_enabled).and_return(true)
|
||||
allow(Settings::Campaign).to receive(:url).and_return("https://campaign-lander.com")
|
||||
allow(Settings::Campaign).to receive(:sidebar_image).and_return("https://example.com/image.png")
|
||||
get "/"
|
||||
expect(response.body).to include('<a href="https://campaign-lander.com"')
|
||||
end
|
||||
|
||||
it "does not display sidebar url if image is not present is set" do
|
||||
allow(SiteConfig).to receive(:campaign_sidebar_enabled).and_return(true)
|
||||
allow(SiteConfig).to receive(:campaign_url).and_return("https://campaign-lander.com")
|
||||
allow(Settings::Campaign).to receive(:sidebar_enabled).and_return(true)
|
||||
allow(Settings::Campaign).to receive(:url).and_return("https://campaign-lander.com")
|
||||
get "/"
|
||||
expect(response.body).not_to include('<a href="https://campaign-lander.com"')
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue