From b85c8c24584653f93ef809646900158c9dcee5f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Mon, 23 Jan 2023 14:58:04 +0100
Subject: [PATCH] prevent changing the default language or consequences

---
 app/assets/javascripts/admin/communication/websites.js     | 6 ++++--
 app/controllers/admin/communication/websites_controller.rb | 6 ++++--
 app/models/communication/website.rb                        | 7 +++++++
 app/models/communication/website/with_special_pages.rb     | 7 ++++++-
 app/views/admin/communication/websites/_form.html.erb      | 2 +-
 config/locales/communication/en.yml                        | 1 +
 config/locales/communication/fr.yml                        | 1 +
 7 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/app/assets/javascripts/admin/communication/websites.js b/app/assets/javascripts/admin/communication/websites.js
index 677df2eb6..d27e2bf1b 100644
--- a/app/assets/javascripts/admin/communication/websites.js
+++ b/app/assets/javascripts/admin/communication/websites.js
@@ -5,8 +5,10 @@ window.osuny.communication.websites = {
         this.languagesCheckboxes = document.querySelectorAll('.js-languages input[type="checkbox"]');
         this.defaultLanguageSelect = document.querySelector('.js-default-language');
         this.defaultLanguageOptions = this.defaultLanguageSelect.querySelectorAll('option');
-        this.initEvents();
-        this.onChangeCheckbox();
+        if (this.defaultLanguageSelect) {
+            this.initEvents();
+            this.onChangeCheckbox();
+        }
     },
 
     initEvents: function () {
diff --git a/app/controllers/admin/communication/websites_controller.rb b/app/controllers/admin/communication/websites_controller.rb
index faaeff0b6..c32581fdc 100644
--- a/app/controllers/admin/communication/websites_controller.rb
+++ b/app/controllers/admin/communication/websites_controller.rb
@@ -76,10 +76,12 @@ class Admin::Communication::WebsitesController < Admin::Communication::Websites:
   protected
 
   def website_params
-    params.require(:communication_website).permit(
+    attribute_names = [
       :name, :url, :repository, :access_token, :about_type, :about_id, :in_production,
       :git_provider, :git_endpoint, :git_branch, :plausible_url, :default_language_id, language_ids: []
-    )
+    ]
+    attribute_names << :default_language_id unless @website&.persisted?
+    params.require(:communication_website).permit(*attribute_names)
   end
 
   def default_url_options
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index 2022004cc..2f935de55 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -62,6 +62,7 @@ class Communication::Website < ApplicationRecord
                           association_foreign_key: 'language_id'
 
   validates :languages, length: { minimum: 1 }
+  validate :languages_must_include_default_language
 
   scope :ordered, -> { order(:name) }
   scope :in_production, -> { where(in_production: true) }
@@ -96,4 +97,10 @@ class Communication::Website < ApplicationRecord
     dependencies += about.git_dependencies(website) if about.present?
     dependencies
   end
+
+  protected
+
+  def languages_must_include_default_language
+    errors.add(:languages, :must_include_default) unless language_ids.include?(default_language_id)
+  end
 end
diff --git a/app/models/communication/website/with_special_pages.rb b/app/models/communication/website/with_special_pages.rb
index 392639da5..3e7628192 100644
--- a/app/models/communication/website/with_special_pages.rb
+++ b/app/models/communication/website/with_special_pages.rb
@@ -7,7 +7,12 @@ module Communication::Website::WithSpecialPages
   end
 
   def special_page(type, language: default_language)
-    pages.where(type: type.to_s, language_id: language).first
+    special_page = pages.where(type: type.to_s, language_id: language.id).first
+    special_page ||= begin
+      original_special_page = pages.where(type: type.to_s, language_id: default_language_id).first
+      original_special_page.duplicate!(language) if original_special_page.present?
+    end
+    special_page
   end
 
   def create_missing_special_pages
diff --git a/app/views/admin/communication/websites/_form.html.erb b/app/views/admin/communication/websites/_form.html.erb
index 9530351b1..128bce7da 100644
--- a/app/views/admin/communication/websites/_form.html.erb
+++ b/app/views/admin/communication/websites/_form.html.erb
@@ -13,7 +13,7 @@
           <%= f.input :url %>
           <%= render 'admin/communication/abouts', f: f, i18n_key: 'activerecord.attributes.communication/website.about_' %>
           <%= f.association :languages, as: :check_boxes, required: true, wrapper_html: { class: "js-languages" } %>
-          <%= f.association :default_language, include_blank: t('simple_form.include_blanks.defaults.language'), input_html: { class: "js-default-language" } %>
+          <%= f.association :default_language, include_blank: t('simple_form.include_blanks.defaults.language'), input_html: (@website.persisted? ? { disabled: true } : { class: "js-default-language" }) %>
           <%= f.input :in_production %>
         </div>
       </div>
diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml
index 31032486b..6bd173b6c 100644
--- a/config/locales/communication/en.yml
+++ b/config/locales/communication/en.yml
@@ -146,6 +146,7 @@ en:
         communication/website:
           attributes:
             languages:
+              must_include_default: must include at least the default language
               too_short: must include at least one
   admin:
     communication:
diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml
index 9592afc31..d38195185 100644
--- a/config/locales/communication/fr.yml
+++ b/config/locales/communication/fr.yml
@@ -146,6 +146,7 @@ fr:
         communication/website:
           attributes:
             languages:
+              must_include_default: doivent contenir la langue par défaut
               too_short: doivent en comporter une minimum
   admin:
     communication:
-- 
GitLab