From aafdb53846828107bf6e3c68bc2938017338437c Mon Sep 17 00:00:00 2001
From: natdeanlewissoftwire
<94526761+natdeanlewissoftwire@users.noreply.github.com>
Date: Thu, 11 Jan 2024 10:10:48 +0000
Subject: [PATCH] CLDC-2255 Add homepage notifications (#2131)
* feat: add notification table
* feat: add notification banner, use unread gem for notification management
* feat: add notifications page and remove unread_notification.rb
* feat: add blank homepage, update routing and tests
* feat: add welcome message and thoroughly test routing
* refactor: lint
* feat: update tests
* CLDC-3061 Add guidance page (#2121)
* Add guidance page
* Link to guidance from start page
* feat: test home/start paths explicitly
* feat: add notification table
* feat: add notification banner, use unread gem for notification management
* feat: add notifications page and remove unread_notification.rb
* feat: default p tag around sanitized page content
* feat: add active scope
* feat: use newest active unread/unauthenticated notification and update start page
* feat: add tests of notification behaviour and routing and refactor
* refactor: lint
* feat: update Gemfile.lock
* feat: add timestamps to readmark table
* feat: update gemfile.lock
* refactor: lint
* feat: test notifications page doesn't show notifications and code simplification
* feat: move notification helper methods to notifications_helper.rb
---------
Co-authored-by: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
---
Gemfile | 1 +
Gemfile.lock | 3 +
app/controllers/notifications_controller.rb | 19 +++
app/frontend/styles/_header.scss | 4 +
app/frontend/styles/_unread-notification.scss | 7 +
app/frontend/styles/application.scss | 5 +-
app/helpers/application_helper.rb | 18 ++-
app/helpers/navigation_items_helper.rb | 2 +-
app/helpers/notifications_helper.rb | 17 +++
app/models/notification.rb | 14 ++
app/models/user.rb | 10 ++
app/views/layouts/application.html.erb | 8 +-
.../_notification_banner.html.erb | 23 +++
app/views/notifications/show.html.erb | 17 +++
app/views/start/index.html.erb | 2 +-
config/routes.rb | 4 +
.../20240108145545_create_notification.rb | 14 ++
db/migrate/20240108152935_unread_migration.rb | 25 ++++
db/schema.rb | 24 +++-
spec/factories/notification.rb | 10 ++
spec/features/home_page_spec.rb | 132 +++++++++++++++++-
spec/features/notifications_page_spec.rb | 41 ++++++
spec/features/start_page_spec.rb | 19 ++-
spec/features/test_spec.rb | 2 +-
spec/features/user_spec.rb | 2 +-
spec/views/layouts/application_layout_spec.rb | 31 ++++
26 files changed, 434 insertions(+), 20 deletions(-)
create mode 100644 app/controllers/notifications_controller.rb
create mode 100644 app/frontend/styles/_unread-notification.scss
create mode 100644 app/helpers/notifications_helper.rb
create mode 100644 app/models/notification.rb
create mode 100644 app/views/notifications/_notification_banner.html.erb
create mode 100644 app/views/notifications/show.html.erb
create mode 100644 db/migrate/20240108145545_create_notification.rb
create mode 100644 db/migrate/20240108152935_unread_migration.rb
create mode 100644 spec/factories/notification.rb
create mode 100644 spec/features/notifications_page_spec.rb
diff --git a/Gemfile b/Gemfile
index 4a650a02d..aae99d51e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -64,6 +64,7 @@ gem "auto_strip_attributes"
# Use sidekiq for background processing
gem "sidekiq"
gem "sidekiq-cron"
+gem "unread"
group :development, :test do
# Check gems for known vulnerabilities
diff --git a/Gemfile.lock b/Gemfile.lock
index b7fdb4059..808f2c24a 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -408,6 +408,8 @@ GEM
concurrent-ruby (~> 1.0)
uk_postcode (2.1.8)
unicode-display_width (2.4.2)
+ unread (0.13.0)
+ activerecord (>= 6.1)
view_component (3.9.0)
activesupport (>= 5.2.0, < 8.0)
concurrent-ruby (~> 1.0)
@@ -493,6 +495,7 @@ DEPENDENCIES
timecop (~> 0.9.4)
tzinfo-data
uk_postcode
+ unread
view_component (~> 3.9)
web-console (>= 4.1.0)
webmock
diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb
new file mode 100644
index 000000000..517199e93
--- /dev/null
+++ b/app/controllers/notifications_controller.rb
@@ -0,0 +1,19 @@
+class NotificationsController < ApplicationController
+ def dismiss
+ if current_user.blank?
+ redirect_to root_path
+ else
+ current_user.newest_active_unread_notification.mark_as_read! for: current_user
+ redirect_back(fallback_location: root_path)
+ end
+ end
+
+ def show
+ @notification = current_user&.newest_active_unread_notification || Notification.newest_active_unauthenticated_notification
+ if @notification&.page_content
+ render "show"
+ else
+ redirect_back(fallback_location: root_path)
+ end
+ end
+end
diff --git a/app/frontend/styles/_header.scss b/app/frontend/styles/_header.scss
index 12cfd4e54..924276d5f 100644
--- a/app/frontend/styles/_header.scss
+++ b/app/frontend/styles/_header.scss
@@ -26,3 +26,7 @@
.app-header--orange .govuk-header__container {
border-bottom-color: govuk-colour("orange");
}
+
+.app-header__no-border-bottom {
+ border-bottom: 0;
+}
diff --git a/app/frontend/styles/_unread-notification.scss b/app/frontend/styles/_unread-notification.scss
new file mode 100644
index 000000000..d76b36fa2
--- /dev/null
+++ b/app/frontend/styles/_unread-notification.scss
@@ -0,0 +1,7 @@
+.app-unread-notification {
+ background-color: govuk-colour("blue");
+}
+
+.app-unread-notification p {
+ color: govuk-colour("white");
+}
diff --git a/app/frontend/styles/application.scss b/app/frontend/styles/application.scss
index d405c3960..6309425de 100644
--- a/app/frontend/styles/application.scss
+++ b/app/frontend/styles/application.scss
@@ -26,7 +26,9 @@ $govuk-breakpoints: (
@import "button";
@import "card";
@import "data_box";
+@import "delete-logs-table";
@import "document-list";
+@import "errors";
@import "feedback";
@import "filter";
@import "filter-layout";
@@ -44,8 +46,7 @@ $govuk-breakpoints: (
@import "primary-navigation";
@import "search";
@import "sub-navigation";
-@import "errors";
-@import "delete-logs-table";
+@import "unread-notification";
// App utilities
.app-\!-colour-muted {
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 971dd68d9..01f7734c2 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -10,21 +10,27 @@ module ApplicationHelper
end
def govuk_header_classes(current_user)
- if current_user && current_user.support?
+ if current_user&.support?
"app-header app-header--orange"
+ elsif ((current_user.blank? && Notification.active_unauthenticated_notifications.present?) || current_user&.active_unread_notifications.present?) && !current_page?(notifications_path)
+ "app-header app-header__no-border-bottom"
else
"app-header"
end
end
def govuk_phase_banner_tag(current_user)
- if current_user && current_user.support?
+ if current_user&.support?
{ colour: "orange", text: "Support beta" }
else
{ text: "Beta" }
end
end
+ def notifications_to_display?
+ !current_page?(notifications_path) && (authenticated_user_has_notifications? || unauthenticated_user_has_notifications?)
+ end
+
private
def paginated_title(title, pagy)
@@ -33,4 +39,12 @@ private
title + " (page #{pagy.page} of #{pagy.pages})"
end
+
+ def authenticated_user_has_notifications?
+ current_user&.active_unread_notifications.present?
+ end
+
+ def unauthenticated_user_has_notifications?
+ current_user.blank? && Notification.active_unauthenticated_notifications.present?
+ end
end
diff --git a/app/helpers/navigation_items_helper.rb b/app/helpers/navigation_items_helper.rb
index 18132a8a1..95e8cc9cf 100644
--- a/app/helpers/navigation_items_helper.rb
+++ b/app/helpers/navigation_items_helper.rb
@@ -47,7 +47,7 @@ module NavigationItemsHelper
private
def home_current?(path)
- path == root_path
+ path == root_path || path == notifications_path
end
def lettings_logs_current?(path)
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
new file mode 100644
index 000000000..ab4c8ec21
--- /dev/null
+++ b/app/helpers/notifications_helper.rb
@@ -0,0 +1,17 @@
+module NotificationsHelper
+ def notification_count
+ if current_user.present?
+ current_user.active_unread_notifications.count
+ else
+ Notification.active_unauthenticated_notifications.count
+ end
+ end
+
+ def notification
+ if current_user.present?
+ current_user.newest_active_unread_notification
+ else
+ Notification.newest_active_unauthenticated_notification
+ end
+ end
+end
diff --git a/app/models/notification.rb b/app/models/notification.rb
new file mode 100644
index 000000000..86978ebea
--- /dev/null
+++ b/app/models/notification.rb
@@ -0,0 +1,14 @@
+class Notification < ApplicationRecord
+ acts_as_readable
+
+ scope :active, -> { where("start_date <= ? AND end_date >= ?", Time.zone.now, Time.zone.now) }
+ scope :unauthenticated, -> { where(show_on_unauthenticated_pages: true) }
+
+ def self.active_unauthenticated_notifications
+ active.unauthenticated
+ end
+
+ def self.newest_active_unauthenticated_notification
+ active_unauthenticated_notifications.last
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index bd04ba2b2..aba948425 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,4 +1,6 @@
class User < ApplicationRecord
+ acts_as_reader
+
# Include default devise modules. Others available are:
# :omniauthable
devise :database_authenticatable, :recoverable, :rememberable,
@@ -227,6 +229,14 @@ class User < ApplicationRecord
sales_logs.after_date(FormHandler.instance.sales_earliest_open_for_editing_collection_start_date).duplicate_sets(id).map { |array_str| array_str ? array_str.map(&:to_i) : [] }
end
+ def active_unread_notifications
+ Notification.active.unread_by(self)
+ end
+
+ def newest_active_unread_notification
+ active_unread_notifications.last
+ end
+
protected
# Checks whether a password is needed or not. For validations only.
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 35d3c23a8..1ed5014c3 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -99,6 +99,10 @@
end
end %>
+ <% if notifications_to_display? %>
+ <%= render "notifications/notification_banner" %>
+ <% end %>
+
<% feedback_link = govuk_link_to "giving us your feedback (opens in a new tab)", t("feedback_form"), rel: "noreferrer noopener", target: "_blank" %>
<%= govuk_phase_banner(
@@ -107,7 +111,7 @@
text: "This is a new service – help us improve it by #{feedback_link}".html_safe,
) %>
- <% if !current_user.nil? %>
+ <% if current_user.present? %>
<%= render PrimaryNavigationComponent.new(
items: primary_items(request.path, current_user),
) %>
@@ -122,7 +126,7 @@
<%= govuk_notification_banner(
title_text: "Success",
success: true, title_heading_level: 3,
- title_id: "swanky-notifications"
+ title_id: "flash-notice"
) do |notification_banner|
notification_banner.with_heading(text: flash.notice.html_safe)
if flash[:notification_banner_body]
diff --git a/app/views/notifications/_notification_banner.html.erb b/app/views/notifications/_notification_banner.html.erb
new file mode 100644
index 000000000..230fe458a
--- /dev/null
+++ b/app/views/notifications/_notification_banner.html.erb
@@ -0,0 +1,23 @@
+
+
+
+
+
+ <% if notification_count > 1 && current_user.present? %>
+
Notification 1 of <%= notification_count %>
+ <% end %>
+
<%= notification.title %>
+ <% if notification.page_content.present? %>
+
+ <%= govuk_link_to notification.link_text, notifications_path, class: "govuk-link--inverse govuk-!-font-weight-bold" %>
+
+ <% end %>
+
+ <% if current_user.present? %>
+
+ <%= govuk_link_to "Dismiss", dismiss_notifications_path, class: "govuk-link--inverse" %>
+
+ <% end %>
+
+
+
diff --git a/app/views/notifications/show.html.erb b/app/views/notifications/show.html.erb
new file mode 100644
index 000000000..abdc77044
--- /dev/null
+++ b/app/views/notifications/show.html.erb
@@ -0,0 +1,17 @@
+<% content_for :title, "Notification" %>
+<% content_for :before_content do %>
+ <%= govuk_back_link(href: :back) %>
+<% end %>
+
+
+
+
<%= @notification.title %>
+
+ <%= sanitize @notification.page_content %>
+
+
+
+
+
+ <%= govuk_button_link_to "Back to #{current_user.present? ? 'Home' : 'Start'}", root_path %>
+
diff --git a/app/views/start/index.html.erb b/app/views/start/index.html.erb
index 17e15d34e..a726be277 100644
--- a/app/views/start/index.html.erb
+++ b/app/views/start/index.html.erb
@@ -23,10 +23,10 @@
If you need to set up a new account, speak to your organisation’s CORE data coordinator. If you don’t know who that is, <%= govuk_link_to("contact the helpdesk", GlobalConstants::HELPDESK_URL) %>.
You can <%= govuk_mail_to("dluhc.digital-services@levellingup.gov.uk", "request an account", subject: "CORE: Request a new account") %> if your organisation doesn’t have one.
<%= govuk_link_to guidance_path do %>Guidance for submitting social housing lettings and sales data (CORE)<% end %>
+
-
<%= render partial: "layouts/collection_resources" %>
diff --git a/config/routes.rb b/config/routes.rb
index 94626f34d..06cb4f8d3 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -128,6 +128,10 @@ Rails.application.routes.draw do
end
end
+ resource :notifications do
+ get "dismiss", to: "notifications#dismiss"
+ end
+
resources :organisations do
get "duplicates", to: "duplicate_logs#index"
diff --git a/db/migrate/20240108145545_create_notification.rb b/db/migrate/20240108145545_create_notification.rb
new file mode 100644
index 000000000..dc69a8efe
--- /dev/null
+++ b/db/migrate/20240108145545_create_notification.rb
@@ -0,0 +1,14 @@
+class CreateNotification < ActiveRecord::Migration[7.0]
+ def change
+ create_table :notifications do |t|
+ t.string :title
+ t.string :link_text
+ t.string :page_content
+ t.datetime :start_date
+ t.datetime :end_date
+ t.boolean :show_on_unauthenticated_pages
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20240108152935_unread_migration.rb b/db/migrate/20240108152935_unread_migration.rb
new file mode 100644
index 000000000..25067b439
--- /dev/null
+++ b/db/migrate/20240108152935_unread_migration.rb
@@ -0,0 +1,25 @@
+class UnreadMigration < ActiveRecord::Migration[6.0]
+ def self.up
+ create_table ReadMark, force: true, options: create_options do |t|
+ t.references :readable, polymorphic: { null: false }
+ t.references :reader, polymorphic: { null: false }
+ t.datetime :timestamp, null: false
+ t.timestamps
+ end
+
+ add_index ReadMark, %i[reader_id reader_type readable_type readable_id], name: "read_marks_reader_readable_index", unique: true
+ end
+
+ def self.down
+ drop_table ReadMark
+ end
+
+ def self.create_options
+ options = ""
+ if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) \
+ && ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
+ options = "DEFAULT CHARSET=latin1"
+ end
+ options
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 22d67bb9f..e75f47e60 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2023_12_18_105226) do
+ActiveRecord::Schema[7.0].define(version: 2024_01_08_152935) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -393,6 +393,17 @@ ActiveRecord::Schema[7.0].define(version: 2023_12_18_105226) do
t.string "new_organisation_telephone_number"
end
+ create_table "notifications", force: :cascade do |t|
+ t.string "title"
+ t.string "link_text"
+ t.string "page_content"
+ t.datetime "start_date"
+ t.datetime "end_date"
+ t.boolean "show_on_unauthenticated_pages"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
create_table "organisation_relationships", force: :cascade do |t|
t.integer "child_organisation_id"
t.integer "parent_organisation_id"
@@ -446,6 +457,17 @@ ActiveRecord::Schema[7.0].define(version: 2023_12_18_105226) do
t.index ["old_visible_id"], name: "index_organisations_on_old_visible_id", unique: true
end
+ create_table "read_marks", force: :cascade do |t|
+ t.string "readable_type", null: false
+ t.bigint "readable_id"
+ t.string "reader_type", null: false
+ t.bigint "reader_id"
+ t.datetime "timestamp", precision: nil, null: false
+ t.index ["readable_type", "readable_id"], name: "index_read_marks_on_readable_type_and_readable_id"
+ t.index ["reader_id", "reader_type", "readable_type", "readable_id"], name: "read_marks_reader_readable_index", unique: true
+ t.index ["reader_type", "reader_id"], name: "index_read_marks_on_reader_type_and_reader_id"
+ end
+
create_table "sales_logs", force: :cascade do |t|
t.integer "status", default: 0
t.datetime "saledate"
diff --git a/spec/factories/notification.rb b/spec/factories/notification.rb
new file mode 100644
index 000000000..05d4faa3f
--- /dev/null
+++ b/spec/factories/notification.rb
@@ -0,0 +1,10 @@
+FactoryBot.define do
+ factory :notification do
+ title { "Notification title" }
+ link_text { "Link text" }
+ page_content { "Some html content" }
+ start_date { Time.zone.yesterday }
+ end_date { Time.zone.tomorrow }
+ show_on_unauthenticated_pages { false }
+ end
+end
diff --git a/spec/features/home_page_spec.rb b/spec/features/home_page_spec.rb
index 908961e33..0e8e99ff7 100644
--- a/spec/features/home_page_spec.rb
+++ b/spec/features/home_page_spec.rb
@@ -4,6 +4,124 @@ require_relative "form/helpers"
RSpec.describe "Home Page Features" do
include Helpers
+ context "when there are notifications" do
+ let!(:user) { FactoryBot.create(:user) }
+
+ context "when the notifications are currently active" do
+ before do
+ create(:notification, title: "Notification title 1")
+ create(:notification, title: "Notification title 2")
+ create(:notification, title: "Notification title 3")
+ sign_in user
+ visit(root_path)
+ end
+
+ it "shows the latest notification with count and dismiss link" do
+ expect(page).to have_content("Notification 1 of 3")
+ expect(page).to have_content("Notification title 3")
+ expect(page).to have_link("Dismiss")
+ expect(page).to have_link("Link text")
+ end
+
+ context "when the user clicks a notification link" do
+ before do
+ click_link("Link text")
+ end
+
+ it "takes them to the notification details page" do
+ expect(page).to have_current_path(notifications_path)
+ expect(page).to have_content("Notification title 3")
+ expect(page).to have_content("Some html content")
+ expect(page).to have_link("Back to Home")
+ end
+
+ context "when they return" do
+ before do
+ click_link("Back to Home")
+ end
+
+ it "the notification has not been dismissed" do
+ expect(page).to have_current_path(root_path)
+ expect(page).to have_content("Notification 1 of 3")
+ expect(page).to have_content("Notification title 3")
+ expect(page).to have_link("Dismiss")
+ expect(page).to have_link("Link text")
+ end
+ end
+ end
+
+ context "when the user clicks a dismiss link" do
+ before do
+ click_link("Dismiss")
+ end
+
+ it "dismisses the notification and takes them back" do
+ expect(page).to have_current_path(root_path)
+ expect(page).to have_content("Notification 1 of 2")
+ expect(page).to have_content("Notification title 2")
+ expect(page).to have_link("Dismiss")
+ expect(page).to have_link("Link text")
+ end
+
+ context "when the user dismisses the penultimate notification" do
+ before do
+ click_link("Dismiss")
+ end
+
+ it "no longer displays the count" do
+ expect(page).to have_current_path(root_path)
+ expect(page).not_to have_content("Notification 1 of")
+ expect(page).to have_content("Notification title 1")
+ end
+
+ context "when the user dismisses the final notification" do
+ before do
+ click_link("Dismiss")
+ end
+
+ it "no longer displays any notification" do
+ expect(page).to have_current_path(root_path)
+ expect(page).not_to have_content("Notification")
+ expect(page).not_to have_link("Dismiss")
+ expect(page).not_to have_link("Link_text")
+ end
+ end
+ end
+ end
+
+ context "when another user has dismissed all their notifications" do
+ before do
+ other_user = create(:user)
+ Notification.mark_as_read! :all, for: other_user
+ visit(root_path)
+ end
+
+ it "the first user can still see the notifications" do
+ expect(page).to have_content("Notification 1 of 3")
+ expect(page).to have_content("Notification title 3")
+ expect(page).to have_link("Dismiss")
+ expect(page).to have_link("Link text")
+ end
+ end
+ end
+
+ context "when the notifications are not currently active" do
+ before do
+ create(:notification, end_date: Time.zone.yesterday, title: "Notification title 1")
+ create(:notification, start_date: Time.zone.tomorrow, title: "Notification title 2")
+ sign_in user
+ visit(root_path)
+ end
+
+ it "does not show any notifications" do
+ expect(page).not_to have_content("Notification title")
+ expect(page).not_to have_content("Notification 1 of")
+ expect(page).not_to have_link("Dismiss")
+ expect(page).not_to have_link("Link text")
+ end
+ end
+ end
+
context "when the user is a data provider" do
let(:user) { FactoryBot.create(:user, name: "Provider") }
@@ -13,7 +131,7 @@ RSpec.describe "Home Page Features" do
create_list(:lettings_log, 4, :completed, owning_organisation: user.organisation, created_by: user)
create_list(:lettings_log, 2, :completed)
sign_in user
- visit("/")
+ visit(root_path)
end
it "displays the correct welcome text" do
@@ -26,7 +144,7 @@ RSpec.describe "Home Page Features" do
before do
create_list(:sales_log, 5, :in_progress, owning_organisation: user.organisation, created_by: user)
create_list(:sales_log, 3, :completed, owning_organisation: user.organisation, created_by: user)
- visit("/")
+ visit(root_path)
end
it "displays correct data boxes, counts and links" do
@@ -41,7 +159,7 @@ RSpec.describe "Home Page Features" do
context "when their organisation has never submitted sales logs" do
before do
- visit("/")
+ visit(root_path)
end
it "displays correct data boxes, counts and links" do
@@ -63,7 +181,7 @@ RSpec.describe "Home Page Features" do
create_list(:lettings_log, 2, :completed)
create_list(:scheme, 1, :incomplete, owning_organisation: user.organisation)
sign_in user
- visit("/")
+ visit(root_path)
end
let(:user) { FactoryBot.create(:user, :data_coordinator, name: "Coordinator") }
@@ -78,7 +196,7 @@ RSpec.describe "Home Page Features" do
before do
create_list(:sales_log, 5, :in_progress, owning_organisation: user.organisation)
create_list(:sales_log, 3, :completed, owning_organisation: user.organisation)
- visit("/")
+ visit(root_path)
end
it "displays correct data boxes, counts and links" do
@@ -95,7 +213,7 @@ RSpec.describe "Home Page Features" do
context "when their organisation has never submitted sales logs" do
before do
- visit("/")
+ visit(root_path)
end
it "displays correct data boxes, counts and links" do
@@ -135,7 +253,7 @@ RSpec.describe "Home Page Features" do
click_button("Sign in")
fill_in("code", with: otp)
click_button("Submit")
- visit("/")
+ visit(root_path)
end
it "displays the correct welcome text" do
diff --git a/spec/features/notifications_page_spec.rb b/spec/features/notifications_page_spec.rb
new file mode 100644
index 000000000..97bbeb7eb
--- /dev/null
+++ b/spec/features/notifications_page_spec.rb
@@ -0,0 +1,41 @@
+require "rails_helper"
+require_relative "form/helpers"
+
+RSpec.describe "Notifications Page Features" do
+ include Helpers
+
+ context "when there are notifications" do
+ let!(:user) { FactoryBot.create(:user) }
+
+ context "when the notifications are currently active" do
+ before do
+ create(:notification, title: "Notification title 1")
+ create(:notification, title: "Notification title 2")
+ create(:notification, title: "Notification title 3")
+ sign_in user
+ visit(notifications_path)
+ end
+
+ it "does not show the notification banner" do
+ expect(page).not_to have_content("Notification 1 of")
+ expect(page).not_to have_link("Dismiss")
+ expect(page).not_to have_link("Link text")
+ end
+ end
+
+ context "when the notifications are not currently active" do
+ before do
+ create(:notification, end_date: Time.zone.yesterday, title: "Notification title 1")
+ create(:notification, start_date: Time.zone.tomorrow, title: "Notification title 2")
+ sign_in user
+ visit(notifications_path)
+ end
+
+ it "does not show the notifications banner" do
+ expect(page).not_to have_content("Notification 1 of")
+ expect(page).not_to have_link("Dismiss")
+ expect(page).not_to have_link("Link text")
+ end
+ end
+ end
+end
diff --git a/spec/features/start_page_spec.rb b/spec/features/start_page_spec.rb
index f7c008553..d90a0c1f0 100644
--- a/spec/features/start_page_spec.rb
+++ b/spec/features/start_page_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe "Start Page Features" do
end
it "takes you to the home page" do
- visit("/")
+ visit(root_path)
expect(page).to have_current_path("/")
expect(page).to have_content("Welcome back")
end
@@ -19,7 +19,7 @@ RSpec.describe "Start Page Features" do
context "when the user is not signed in" do
it "takes you to sign in and then to the home page" do
- visit("/")
+ visit(root_path)
click_link("Start now")
expect(page).to have_current_path("/account/sign-in?start=true")
fill_in("user[email]", with: user.email)
@@ -28,5 +28,20 @@ RSpec.describe "Start Page Features" do
expect(page).to have_current_path("/")
expect(page).to have_content("Welcome back")
end
+
+ context "when the unauthenticated user clicks a notification link" do
+ before do
+ create(:notification, show_on_unauthenticated_pages: true)
+ visit(root_path)
+ click_link("Link text")
+ end
+
+ it "takes them to the notification details page" do
+ expect(page).to have_current_path(notifications_path)
+ expect(page).to have_content("Notification title")
+ expect(page).to have_content("Some html content")
+ expect(page).to have_link("Back to Start")
+ end
+ end
end
end
diff --git a/spec/features/test_spec.rb b/spec/features/test_spec.rb
index ef54fa631..6dc977a9b 100644
--- a/spec/features/test_spec.rb
+++ b/spec/features/test_spec.rb
@@ -1,7 +1,7 @@
require "rails_helper"
RSpec.describe "Test Features" do
it "Displays the name of the app" do
- visit("/")
+ visit(root_path)
expect(page).to have_content("Submit social housing lettings and sales data (CORE)")
end
diff --git a/spec/features/user_spec.rb b/spec/features/user_spec.rb
index 61788f89e..6b0c450f2 100644
--- a/spec/features/user_spec.rb
+++ b/spec/features/user_spec.rb
@@ -126,7 +126,7 @@ RSpec.describe "User Features" do
end
it "Can navigate and sign in page with sign in button" do
- visit("/")
+ visit(root_path)
expect(page).to have_link("Sign in")
click_link("Sign in")
fill_in("user[email]", with: user.email)
diff --git a/spec/views/layouts/application_layout_spec.rb b/spec/views/layouts/application_layout_spec.rb
index ac4a10a98..55e97bc20 100644
--- a/spec/views/layouts/application_layout_spec.rb
+++ b/spec/views/layouts/application_layout_spec.rb
@@ -54,4 +54,35 @@ RSpec.describe "layouts/application" do
include_examples "analytics cookie elements", banner: false, scripts: false
end
+
+ context "with a notification present" do
+ context "when notification is shown on unauthenticated pages" do
+ before do
+ create(:notification, title: "Old notification title", show_on_unauthenticated_pages: true)
+ create(:notification, title: "New notification title", show_on_unauthenticated_pages: true)
+ render
+ end
+
+ it "shows the most recent notification without dismiss link or count" do
+ expect(rendered).to have_content("New notification title")
+ expect(rendered).to have_link("Link text")
+ expect(rendered).not_to have_link("Dismiss")
+ expect(rendered).not_to have_content("Notification 1 of")
+ end
+ end
+
+ context "when notification is not shown on unauthenticated pages" do
+ before do
+ create(:notification)
+ render
+ end
+
+ it "does not show the notification banner" do
+ expect(rendered).not_to have_content("Notification title")
+ expect(rendered).not_to have_link("Link text")
+ expect(rendered).not_to have_link("Dismiss")
+ expect(rendered).not_to have_content("Notification 1 of")
+ end
+ end
+ end
end