diff --git a/app/models/brand.rb b/app/models/brand.rb index 4673d45c8..b35e46a4c 100644 --- a/app/models/brand.rb +++ b/app/models/brand.rb @@ -14,6 +14,7 @@ class Brand < ApplicationRecord attr_accessor :logo_file, :favicon_file, :opengraph_image_file before_validation :set_slug, on: :create + before_validation :normalise_colours validates :slug, format: { with: /\A[a-z0-9]+(?:-[a-z0-9]+)*\z/, allow_blank: true } validates :name, presence: true @@ -43,6 +44,17 @@ def set_slug self.slug = name.parameterize if slug.blank? && name.present? end + def normalise_colours + self.header_background_colour = normalise_colour(header_background_colour) + self.border_colour = normalise_colour(border_colour) + end + + def normalise_colour(value) + return value if value.blank? + + "##{value.strip.downcase.delete_prefix('#')}" + end + # the slug is derived from the name, so errors are added to name rather # than slug, which has no field in the new brand form def name_must_generate_available_slug diff --git a/app/views/brands/edit.html.erb b/app/views/brands/edit.html.erb index f448e91ae..c754f570a 100644 --- a/app/views/brands/edit.html.erb +++ b/app/views/brands/edit.html.erb @@ -19,9 +19,9 @@ <%= f.govuk_text_field :logo_link, label: { size: 'm' } %> - <%= f.govuk_text_field :header_background_colour, label: { size: 'm' }, width: 5 %> + <%= f.govuk_text_field :header_background_colour, label: { size: 'm' }, width: 5, prefix_text: "#", value: @brand.header_background_colour&.delete_prefix("#") %> - <%= f.govuk_text_field :border_colour, label: { size: 'm' }, width: 5 %> + <%= f.govuk_text_field :border_colour, label: { size: 'm' }, width: 5, prefix_text: "#", value: @brand.border_colour&.delete_prefix("#") %> <%= f.govuk_text_field :copyright_holder, label: { size: 'm' } %> diff --git a/app/views/brands/new.html.erb b/app/views/brands/new.html.erb index 35f10ed79..8b8efdb3e 100644 --- a/app/views/brands/new.html.erb +++ b/app/views/brands/new.html.erb @@ -16,9 +16,9 @@ <%= f.govuk_text_field :logo_link, label: { size: 'm' } %> - <%= f.govuk_text_field :header_background_colour, label: { size: 'm' }, width: 5 %> + <%= f.govuk_text_field :header_background_colour, label: { size: 'm' }, width: 5, prefix_text: "#", value: @brand.header_background_colour&.delete_prefix("#") %> - <%= f.govuk_text_field :border_colour, label: { size: 'm' }, width: 5 %> + <%= f.govuk_text_field :border_colour, label: { size: 'm' }, width: 5, prefix_text: "#", value: @brand.border_colour&.delete_prefix("#") %> <%= f.govuk_text_field :copyright_holder, label: { size: 'm' } %> diff --git a/config/locales/en.yml b/config/locales/en.yml index d4a7e5568..a3976a2fb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -162,14 +162,14 @@ en: attributes: border_colour: blank: Enter the header and footer border colour - invalid: 'Header and footer border colour must be a hex colour code, like #206c49' + invalid: Header and footer border colour must be a hex colour code, like 206c49 copyright_holder: blank: Enter the copyright holder favicon_file: invalid_file_type: The favicon must be an ICO or PNG file header_background_colour: blank: Enter the header background colour - invalid: 'Header background colour must be a hex colour code, like #206c49' + invalid: Header background colour must be a hex colour code, like 206c49 logo_alt_text: blank: Enter the logo alt text logo_file: @@ -1026,10 +1026,10 @@ en: account_name_input: name: You do not need to include a title or any middle names. brand: - border_colour: 'Enter a hex colour code. For example, #206c49' + border_colour: Enter a hex colour code. For example, 206c49 copyright_holder: Shown in the copyright notice in the form’s footer. favicon_file: Upload an ICO or PNG file. Shown in the browser tab. - header_background_colour: 'Enter a hex colour code. For example, #206c49' + header_background_colour: Enter a hex colour code. For example, 206c49 logo_alt_text: Describes the logo for people using screen readers. Usually the organisation’s name. logo_file: Upload a PNG or JPEG file. Shown in the header of the form. logo_link: The web address people go to when they select the logo. Usually the organisation’s website. diff --git a/spec/models/brand_spec.rb b/spec/models/brand_spec.rb index c944e3170..2d96151c3 100644 --- a/spec/models/brand_spec.rb +++ b/spec/models/brand_spec.rb @@ -66,17 +66,20 @@ end %i[header_background_colour border_colour].each do |attribute| - it "is invalid when the #{attribute.to_s.humanize.downcase} is not a lowercase 6-digit hex colour code" do - ["ffffff", "#FFFFFF", "#fff", "#gggggg", "white"].each do |colour| + it "is invalid when the #{attribute.to_s.humanize.downcase} is not a 6-digit hex colour code" do + ["#fff", "#gggggg", "white"].each do |colour| brand.public_send("#{attribute}=", colour) expect(brand).to be_invalid expect(brand.errors).to be_of_kind(attribute, :invalid) end end - it "is valid when the #{attribute.to_s.humanize.downcase} is a lowercase 6-digit hex colour code" do - brand.public_send("#{attribute}=", "#0b0c0c") - expect(brand).to be_valid + it "is valid when the #{attribute.to_s.humanize.downcase} is a 6-digit hex colour code" do + ["#0b0c0c", "0b0c0c", "#0B0C0C", "0B0C0C"].each do |colour| + brand.public_send("#{attribute}=", colour) + expect(brand).to be_valid + expect(brand.public_send(attribute)).to eq "#0b0c0c" + end end end diff --git a/spec/requests/brands_controller_spec.rb b/spec/requests/brands_controller_spec.rb index f96075306..027aebdbc 100644 --- a/spec/requests/brands_controller_spec.rb +++ b/spec/requests/brands_controller_spec.rb @@ -228,6 +228,20 @@ end end + context "when a colour is uppercase and has no leading #" do + before do + params[:brand][:border_colour] = "206C49" + end + + it "creates a brand with the colour normalised" do + expect { + post path, params: params + }.to change(Brand, :count).by(1) + + expect(Brand.last.border_colour).to eq "#206c49" + end + end + context "when a brand with the same name already exists" do before do create :brand, name: "Testshire Council"