Skip to content

Site Wide Banner #2403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
17 changes: 17 additions & 0 deletions app/components/cms/site_wide_banner_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class Cms::SiteWideBannerComponent < ViewComponent::Base
erb_template <<~ERB
<div class="cms-site-wide-banner-component">
<span class="govuk-body-s"><%= render @current_notification.text_content.render %></span>
</div>
ERB

def initialize(current_notification:)
@current_notification = current_notification
end

def render?
@current_notification
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.cms-site-wide-banner-component {
text-align: center;
background-color: $black;
padding: 10px;

span {
color: $white;
}
}
16 changes: 16 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class ApplicationController < ActionController::Base

before_action :authenticate
before_action :access_cms_header
before_action :access_cms_site_wide_notification

def authenticate
return unless ENV["BASIC_AUTH_PASSWORD"]
Expand All @@ -20,6 +21,21 @@ def access_cms_header
@cms_header = nil
end

def access_cms_site_wide_notification
@cms_site_wide_banner = Cms::Collections::SiteWideBanner.all_records

current_time = Time.now.utc

active_banners = @cms_site_wide_banner.select do |banner|
start_time = Time.parse(banner.start_time.value)
end_time = Time.parse(banner.end_time.value)

current_time >= start_time && current_time <= end_time
end

@current_notification = active_banners.first
end

def authenticate_user!
redirect_to(helpers.create_account_url) unless current_user
end
Expand Down
33 changes: 33 additions & 0 deletions app/services/cms/collections/site_wide_banner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module Cms
module Collections
class SiteWideBanner < Resource
def self.is_collection = true

def self.resource_attribute_mappings
[
{model: Models::Text::RichHeader, key: :textContent, param_name: :text_content},
{model: Models::Data::TextField, key: :startTime, param_name: :start_time},
{model: Models::Data::TextField, key: :endTime, param_name: :end_time}
]
end

def self.collection_attribute_mappings
[
{model: Models::Text::RichHeader, key: :textContent, param_name: :text_content},
{model: Models::Data::TextField, key: :startTime, param_name: :start_time},
{model: Models::Data::TextField, key: :endTime, param_name: :end_time}
]
end

def self.cache_expiry
5.minutes
end

def self.graphql_key = "siteWideBanners"

def self.resource_key = "site-wide-banners"

def self.sort = "startTime:desc"
end
end
end
17 changes: 17 additions & 0 deletions app/services/cms/models/collections/site_wide_banner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Cms
module Models
module Collections
class SiteWideBanner
attr_reader :text_content

def initialize(text_content:)
@text_content = text_content
end

def render
Cms::SiteWideBannerComponent.new(text_content:)
end
end
end
end
end
5 changes: 5 additions & 0 deletions app/services/cms/providers/strapi/factories/model_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module ModelFactory
Models::Meta::Seo => :to_seo,
Models::Meta::SimpleTitle => :to_simple_title,
Models::Data::Slug => :to_slug,
Models::Text::RichHeader => :to_rich_header,
Models::Text::TextBlock => :to_text_block,
Models::Text::TextBlockWithoutWrapper => :to_text_block_without_wrapper,
Models::Data::TextField => :to_text_field,
Expand Down Expand Up @@ -159,6 +160,10 @@ def self.to_question_bank_forms(strapi_data, _all_data)
}
end

def self.to_rich_header(strapi_data, _all_data)
{blocks: process_block_data(strapi_data)}
end

def self.to_seo(strapi_data, _all_data)
{
title: strapi_data[:title],
Expand Down
3 changes: 3 additions & 0 deletions app/services/cms/providers/strapi/factories/query_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ def self.generate_parameters(collection_class, query)
filter[:publishDate] = {key_type("lt") => DateTime.now.strftime}
filter[:featured] = {key_type("eq") => query[:featured]} if query&.dig(:featured)
filter[:blog_tags] = {slug: {key_type("eq") => query[:tag]}} if query&.dig(:tag)
elsif collection_class == Cms::Collections::SiteWideBanner
current_time = DateTime.now.strftime
filter[:endTime] = {key_type("gte") => current_time}
end
filter
end
Expand Down
1 change: 1 addition & 0 deletions app/services/cms/providers/strapi/graphql_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def one(resource_class, resource_id = nil, preview: false, preview_key: nil)
data = clean_aliases(response.original_hash)

results = data[:data][resource_class.graphql_key.to_sym][:data]

raise ActiveRecord::RecordNotFound if results.empty?

record = if resource_class.is_collection
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Cms
module Providers
module Strapi
module Mocks
module Collections
class SiteWideBanner < StrapiMock
attribute(:textContent) { Text::RichBlocks.as_model }
attribute(:startTime) { Faker::Time.backward(days: 2) }
attribute(:endTime) { Faker::Time.forward(days: 2) }
end
end
end
end
end
end
4 changes: 3 additions & 1 deletion app/services/cms/providers/strapi/queries/base_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ class BaseQuery
Models::Meta::PageTitle => PageTitle,
Models::Meta::Seo => Seo,
Models::Meta::SimpleTitle => SimpleField,
Models::Text::RichHeader => SimpleField,
Models::Text::TextBlock => SimpleField,
Models::Text::TextBlockWithoutWrapper => SimpleField
Models::Text::TextBlockWithoutWrapper => SimpleField,
Models::Collections::SiteWideBanner => SiteWideBanner
}.freeze

def initialize(collection_class, resource_filter = "slug")
Expand Down
17 changes: 17 additions & 0 deletions app/services/cms/providers/strapi/queries/site_wide_banner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Cms
module Providers
module Strapi
module Queries
class SiteWideBanner
def self.embed(name)
<<~GRAPHQL.freeze
textContent
startTime
endTime
GRAPHQL
end
end
end
end
end
end
1 change: 1 addition & 0 deletions app/services/cms/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def self.get(resource_id = nil, preview: false, preview_key: nil)
client.one(self, resource_id)
end
end

new(**data)
end

Expand Down
3 changes: 2 additions & 1 deletion app/views/components/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@
<%= render model.render %>
<% end %>
<% end %>

</div>
</nav>
</div>

<%= render Cms::SiteWideBannerComponent.new(current_notification: @current_notification) %>
</header>
30 changes: 30 additions & 0 deletions spec/components/cms/site_wide_banner_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require "rails_helper"

RSpec.describe Cms::SiteWideBannerComponent, type: :component do
context "with banner present" do
let(:current_notification) { Cms::Collections::SiteWideBanner.all_records.first }

before do
stub_strapi_site_wide_banner
render_inline(described_class.new(current_notification:))
end

it "renders the component" do
expect(page).to have_css(".cms-site-wide-banner-component")
end

it "renders the text" do
expect(page).to have_css("span")
end
end

context "when no banner present" do
before do
render_inline(described_class.new(current_notification: nil))
end

it "does not render the component" do
expect(page).to_not have_css(".cms-site-wide-banner-component")
end
end
end
2 changes: 2 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ def page
config.before(:each, type: :system) do
driven_by selenium_driver
stub_strapi_header
stub_strapi_site_wide_banner
end

config.before(:each, type: :request) do
stub_strapi_header
stub_strapi_site_wide_banner
end

config.after(:each, js: true, type: :system) do |_spec|
Expand Down
14 changes: 14 additions & 0 deletions spec/services/cms/collections/site_wide_banner_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require "rails_helper"

RSpec.describe Cms::Collections::SiteWideBanner do
it "should have 5 minute cache expiry" do
expect(described_class.cache_expiry).to eq(5.minutes)
end

it "should have correct resource_key" do
expect(described_class.resource_key).to eq("site-wide-banners")
end

it_should_behave_like "a strapi graphql collection single query", %w[textContent startTime endTime]
it_should_behave_like "a strapi graphql collection all query", %w[textContent startTime endTime]
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require "rails_helper"

RSpec.describe Cms::Providers::Strapi::Queries::SiteWideBanner do
it_should_behave_like "a strapi graphql embed", {
required_fields: %w[
startTime
endTime
textContent
]
}
end
2 changes: 1 addition & 1 deletion spec/support/cms/providers/strapi/schema.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions spec/support/cms/providers/strapi/strapi_stubs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ def stub_strapi_homepage(homepage: Cms::Mocks::Singles::Homepage.generate_raw_da
end
end

def stub_strapi_site_wide_banner(banner: Array.new(3) { Cms::Mocks::Collections::SiteWideBanner.generate_raw_data })
if as_graphql
stub_strapi_graphql_collection_query("siteWideBanners", banner)
end
end

def stub_strapi_schema
stub_request(:post, /^https:\/\/strapi.teachcomputing.org\/graphql/)
.with(body: /IntrospectionQuery/)
Expand Down
24 changes: 24 additions & 0 deletions spec/views/components/_header_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,28 @@
expect(rendered).not_to have_css(".govuk-header__navigation-item", text: "Your progress")
end
end

context "when site wide banner is not active" do
before do
stub_strapi_site_wide_banner
assign(:current_notification, nil)
render
end

it "does not render the cms site wide banner component" do
expect(rendered).not_to have_css(".cms-site-wide-banner-component")
end
end

context "when site wide banner is active" do
before do
stub_strapi_site_wide_banner
assign(:current_notification, Cms::Collections::SiteWideBanner.all_records.first)
render
end

it "does render the cms site wide banner component" do
expect(rendered).to have_css(".cms-site-wide-banner-component")
end
end
end
1 change: 1 addition & 0 deletions spec/views/layouts/application.html_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
RSpec.describe("layouts/application", type: :view) do
before do
stub_strapi_header
stub_strapi_site_wide_banner
render
end

Expand Down