diff --git a/app/controllers/admin/settings/campaigns_controller.rb b/app/controllers/admin/settings/campaigns_controller.rb new file mode 100644 index 000000000..aaaa4ce86 --- /dev/null +++ b/app/controllers/admin/settings/campaigns_controller.rb @@ -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 diff --git a/app/controllers/sidebars_controller.rb b/app/controllers/sidebars_controller.rb index 3b9e2fe93..c4ce1b60a 100644 --- a/app/controllers/sidebars_controller.rb +++ b/app/controllers/sidebars_controller.rb @@ -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? diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 807b6bb4b..07d2f1a13 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -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? diff --git a/app/lib/constants/settings/campaign.rb b/app/lib/constants/settings/campaign.rb new file mode 100644 index 000000000..bbac9dad8 --- /dev/null +++ b/app/lib/constants/settings/campaign.rb @@ -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 diff --git a/app/lib/constants/site_config.rb b/app/lib/constants/site_config.rb index f3e3e6a86..0a54d8855 100644 --- a/app/lib/constants/site_config.rb +++ b/app/lib/constants/site_config.rb @@ -4,38 +4,6 @@ module Constants SVG_PLACEHOLDER = "".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 diff --git a/app/models/campaign.rb b/app/models/campaign.rb index 190097713..d698c5ef1 100644 --- a/app/models/campaign.rb +++ b/app/models/campaign.rb @@ -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? diff --git a/app/models/settings/campaign.rb b/app/models/settings/campaign.rb new file mode 100644 index 000000000..8b5191caf --- /dev/null +++ b/app/models/settings/campaign.rb @@ -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 diff --git a/app/models/site_config.rb b/app/models/site_config.rb index 57d9a873c..efeeb1aac 100644 --- a/app/models/site_config.rb +++ b/app/models/site_config.rb @@ -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 diff --git a/app/services/campaigns/settings_upsert.rb b/app/services/campaigns/settings_upsert.rb new file mode 100644 index 000000000..e9c8dc6af --- /dev/null +++ b/app/services/campaigns/settings_upsert.rb @@ -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 diff --git a/app/views/admin/configs/show.html.erb b/app/views/admin/configs/show.html.erb index 9056d2dbd..200ccc85b 100644 --- a/app/views/admin/configs/show.html.erb +++ b/app/views/admin/configs/show.html.erb @@ -363,7 +363,7 @@ <% end %> - <%= form_for(SiteConfig.new, url: admin_config_path) do |f| %> + <%= form_for(Settings::Campaign.new, url: admin_settings_campaigns_path) do |f| %>
<%= render partial: "admin/shared/card_header", locals: { @@ -375,76 +375,76 @@
- <%= 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] %>
- <%= 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] %>
- <%= 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] %>
- <%= 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? %>
- Campaign sidebar image + Campaign sidebar image
<% 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] %>
- <%= 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] %>
- <%= 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] %>
- <%= 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] %>
- <%= 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] %>
<%= render "form_submission", f: f %> diff --git a/config/routes.rb b/config/routes.rb index 856672232..c05443eec 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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] diff --git a/cypress/integration/adminFlows/config/campaignSection.spec.js b/cypress/integration/adminFlows/config/campaignSection.spec.js new file mode 100644 index 000000000..ca58ea704 --- /dev/null +++ b/cypress/integration/adminFlows/config/campaignSection.spec.js @@ -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', + ); + }); + }); + }); +}); diff --git a/db/migrate/20210405032815_create_settings_campaigns.rb b/db/migrate/20210405032815_create_settings_campaigns.rb new file mode 100644 index 000000000..d9370d248 --- /dev/null +++ b/db/migrate/20210405032815_create_settings_campaigns.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index 885b28536..742fd510a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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 diff --git a/lib/data_update_scripts/20210405034117_move_campaign_settings.rb b/lib/data_update_scripts/20210405034117_move_campaign_settings.rb new file mode 100644 index 000000000..43ede4fbb --- /dev/null +++ b/lib/data_update_scripts/20210405034117_move_campaign_settings.rb @@ -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 diff --git a/spec/models/site_config_spec.rb b/spec/models/site_config_spec.rb index fab0ee558..e863291c3 100644 --- a/spec/models/site_config_spec.rb +++ b/spec/models/site_config_spec.rb @@ -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 diff --git a/spec/requests/admin/configs_spec.rb b/spec/requests/admin/configs_spec.rb index 93eae7947..39b94e601 100644 --- a/spec/requests/admin/configs_spec.rb +++ b/spec/requests/admin/configs_spec.rb @@ -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 diff --git a/spec/requests/stories_index_spec.rb b/spec/requests/stories_index_spec.rb index b030c9959..54bf19258 100644 --- a/spec/requests/stories_index_spec.rb +++ b/spec/requests/stories_index_spec.rb @@ -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('