Skip to content
Merged
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 @@ -6,6 +6,7 @@ class ApplicationController < ActionController::Base
before_action :authenticate
before_action :access_cms_header
before_action :access_cms_footer
before_action :access_cms_site_wide_notification

def authenticate
return unless ENV["BASIC_AUTH_PASSWORD"]
Expand All @@ -27,6 +28,21 @@ def access_cms_footer
@cms_footer = 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
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 @@ -22,6 +22,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 @@ -195,6 +196,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.generate_data }
attribute(:startTime) { Faker::Time.backward(days: 2) }
attribute(:endTime) { Faker::Time.backward(days: 1) }
end
end
end
end
end
end
1 change: 1 addition & 0 deletions app/services/cms/providers/strapi/queries/base_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ 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
}.freeze
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 @@ -75,6 +75,7 @@ def self.get(resource_id = nil, preview: false, preview_key: nil)
client.one(self, resource_id)
end
end

new(**data)
end

Expand Down
2 changes: 2 additions & 0 deletions app/views/components/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,6 @@
</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 @@ -101,11 +101,13 @@ def page
driven_by selenium_driver
stub_strapi_header
stub_strapi_footer
stub_strapi_site_wide_banner
end

config.before(:each, type: :request) do
stub_strapi_header
stub_strapi_footer
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 @@ -239,6 +239,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