Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/controllers/api/brands_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Api::BrandsController < ApplicationController
def show
expires_in 5.minutes, public: true
render json: brand.as_json(only: %i[name slug])
render json: brand.as_json(only: %i[name slug header_background_colour border_colour logo_alt_text logo_link copyright_holder])
end

private
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/brands_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ def set_brand
end

def brand_params
params.require(:brand).permit(:name, :slug)
params.require(:brand).permit(:name, :slug, :header_background_colour, :border_colour, :logo_alt_text, :logo_link, :copyright_holder)
end

def update_brand_params
params.require(:brand).permit(:name)
params.require(:brand).permit(:name, :header_background_colour, :border_colour, :logo_alt_text, :logo_link, :copyright_holder)
end
end
3 changes: 3 additions & 0 deletions app/models/brand.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ class Brand < ApplicationRecord

validates :slug, presence: true, uniqueness: true, format: { with: /\A[a-z0-9]+(?:-[a-z0-9]+)*\z/, allow_blank: true }
validates :name, presence: true
validates :header_background_colour, :border_colour, presence: true, format: { with: /\A#[0-9a-f]{6}\z/, allow_blank: true }
validates :logo_link, presence: true, format: { with: %r{\Ahttps?://.*\z}, allow_blank: true }
validates :logo_alt_text, :copyright_holder, presence: true
end
10 changes: 10 additions & 0 deletions app/views/brands/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@

<%= f.govuk_text_field :name, label: { size: 'm' } %>

<%= f.govuk_text_field :logo_alt_text, label: { size: 'm' } %>

<%= 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 :border_colour, label: { size: 'm' }, width: 5 %>

<%= f.govuk_text_field :copyright_holder, label: { size: 'm' } %>

<%= f.govuk_submit t("save_and_continue") %>
<% end %>
</div>
Expand Down
10 changes: 10 additions & 0 deletions app/views/brands/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@

<%= f.govuk_text_field :slug, label: { size: 'm' } %>

<%= f.govuk_text_field :logo_alt_text, label: { size: 'm' } %>

<%= 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 :border_colour, label: { size: 'm' }, width: 5 %>

<%= f.govuk_text_field :copyright_holder, label: { size: 'm' } %>

<%= f.govuk_submit t("save_and_continue") %>
<% end %>
</div>
Expand Down
25 changes: 25 additions & 0 deletions app/views/brands/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,31 @@
row.with_value { @brand.slug }
end

summary_list.with_row do |row|
row.with_key { t('brands.show.summary.logo_alt_text') }
row.with_value { @brand.logo_alt_text }
end

summary_list.with_row do |row|
row.with_key { t('brands.show.summary.logo_link') }
row.with_value { @brand.logo_link }
end

summary_list.with_row do |row|
row.with_key { t('brands.show.summary.header_background_colour') }
row.with_value { @brand.header_background_colour }
end

summary_list.with_row do |row|
row.with_key { t('brands.show.summary.border_colour') }
row.with_value { @brand.border_colour }
end

summary_list.with_row do |row|
row.with_key { t('brands.show.summary.copyright_holder') }
row.with_value { @brand.copyright_holder }
end

summary_list.with_row do |row|
row.with_key { t('brands.show.summary.created_at') }
row.with_value { l(@brand.created_at.to_date, format: :long) }
Expand Down
37 changes: 36 additions & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,23 @@ en:
models:
brand:
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'
copyright_holder:
blank: Enter the copyright holder
header_background_colour:
blank: Enter the header background colour
invalid: 'Header background colour must be a hex colour code, like #206c49'
logo_alt_text:
blank: Enter the logo alt text
logo_link:
blank: Enter the logo link
invalid: Enter the logo link in the correct format, starting with https://
name:
blank: Enter a brand name
slug:
blank: Enter a slug
invalid: Slug must only include lowercase letters a to z, numbers and hyphens
taken: There is already a brand with this slug
draft_question:
Expand Down Expand Up @@ -308,12 +324,17 @@ en:
no_results: No brands found.
table_caption: Brands
table_headings:
name: Name
name: Brand name
slug: Slug
show:
edit_brand: Edit this brand
summary:
border_colour: Header and footer border colour
copyright_holder: Copyright holder
created_at: Created
header_background_colour: Header background colour
logo_alt_text: Logo alt text
logo_link: Logo link
slug: Slug
success_messages:
create: The brand has been created
Expand Down Expand Up @@ -991,6 +1012,13 @@ en:
hint:
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'
copyright_holder: Shown in the copyright notice in the form’s footer.
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_link: The web address people go to when they select the logo. Usually the organisation’s website.
name: Used to identify the brand. Not shown to people filling in forms.
forms_copy_input:
name: The form name will be shown at the top of each page of the form. Use a name that describes what the form will help people to do. For example ‘Apply for a juggling licence’.
page:
Expand Down Expand Up @@ -1058,6 +1086,13 @@ en:
account_terms_of_use_input:
agreed_options:
'1': I agree to these terms
brand:
border_colour: Header and footer border colour
copyright_holder: Copyright holder
header_background_colour: Header background colour
logo_alt_text: Logo alt text
logo_link: Logo link
name: Brand name
forms_batch_submissions_input:
batch_frequencies_options:
daily: Get a daily CSV of submissions
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20260812141413_add_branding_attributes_to_brands.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class AddBrandingAttributesToBrands < ActiveRecord::Migration[8.1]
def change
change_table :brands, bulk: true do |t|
t.string :header_background_colour
t.string :border_colour
t.string :logo_alt_text
t.string :logo_link
t.string :copyright_holder
end
end
end
7 changes: 6 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 18 additions & 2 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,24 @@
# Character.create(name: "Luke", movie: movies.first)

if (HostingEnvironment.local_development? || HostingEnvironment.review?) && Brand.none?
Brand.create!(slug: "cheshire-east", name: "Cheshire East Council")
Brand.create!(slug: "south-gloucestershire", name: "South Gloucestershire Council")
Brand.create!(
slug: "toadstool-town",
name: "Toadstool Town Council",
header_background_colour: "#ffffff",
border_colour: "#206c49",
logo_alt_text: "Toadstool Town Council",
logo_link: "https://www.toadstooltown.example.com",
copyright_holder: "Toadstool Town Council",
)
Brand.create!(
slug: "dragonfly-district",
name: "Dragonfly District Council",
header_background_colour: "#ffffff",
border_colour: "#4b0082",
logo_alt_text: "Dragonfly District Council",
logo_link: "https://www.dragonflydistrict.example.com",
copyright_holder: "Dragonfly District Council",
)
end

if (HostingEnvironment.local_development? || HostingEnvironment.review?) && User.none?
Expand Down
5 changes: 5 additions & 0 deletions spec/factories/models/brands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
factory :brand do
sequence(:slug) { |n| "brand-#{n}" }
name { slug.titleize }
header_background_colour { "#ffffff" }
border_colour { "#206c49" }
logo_alt_text { name }
logo_link { "https://www.#{slug}.example.com" }
copyright_holder { name }
end
end
42 changes: 42 additions & 0 deletions spec/models/brand_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,48 @@
expect(brand.errors).to be_of_kind(:slug, :taken)
end

%i[header_background_colour border_colour logo_alt_text logo_link copyright_holder].each do |attribute|
it "is invalid without a #{attribute.to_s.humanize.downcase}" do
brand.public_send("#{attribute}=", nil)
expect(brand).to be_invalid
expect(brand.errors).to be_of_kind(attribute, :blank)
end
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|
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
end
end

it "is invalid when the logo link does not start with http:// or https://" do
["www.example.com", "example.com", "ftp://example.com"].each do |url|
brand.logo_link = url
expect(brand).to be_invalid
expect(brand.errors).to be_of_kind(:logo_link, :invalid)
end
end

it "is invalid when the logo link contains more than one line" do
brand.logo_link = "https://www.example.com\nmalicious"
expect(brand).to be_invalid
expect(brand.errors).to be_of_kind(:logo_link, :invalid)
end

it "is valid when the logo link starts with https://" do
brand.logo_link = "https://www.example.com"
expect(brand).to be_valid
end

it "is an error to insert a brand with an existing slug" do
existing_brand = create(:brand)

Expand Down
16 changes: 15 additions & 1 deletion spec/requests/api/brands_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@

describe "#show" do
context "when the brand exists" do
let(:brand) { create :brand, name: "Golden Zephyr", slug: "golden-zephyr" }
let(:brand) do
create :brand,
name: "Golden Zephyr",
slug: "golden-zephyr",
header_background_colour: "#ffffff",
border_colour: "#206c49",
logo_alt_text: "Golden Zephyr Council",
logo_link: "https://www.goldenzephyr.example.com",
copyright_holder: "Golden Zephyr Council"
end

before do
get "/api/v2/brands/#{brand.id}", headers:
Expand All @@ -19,6 +28,11 @@
expect(response.parsed_body).to eq({
"name" => "Golden Zephyr",
"slug" => "golden-zephyr",
"header_background_colour" => "#ffffff",
"border_colour" => "#206c49",
"logo_alt_text" => "Golden Zephyr Council",
"logo_link" => "https://www.goldenzephyr.example.com",
"copyright_holder" => "Golden Zephyr Council",
})
end

Expand Down
Loading