Skip to content
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

Allow registration when service is closed #1146

Open
wants to merge 1 commit 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
4 changes: 2 additions & 2 deletions app/constraints/has_flipper_access.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
class HasFlipperAccess
def self.matches?(request)
current_user_id = request.session["user_id"]
current_user_id = request.session["admin_id"]

current_user = User.find_by(id: current_user_id)
current_user = Admin.find_by(id: current_user_id)

current_user.present? && current_user.flipper_access?
end
Expand Down
21 changes: 21 additions & 0 deletions app/controllers/admin/closed_registration_users_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Admin::ClosedRegistrationUsersController < SuperAdminController
def index
@users = ClosedRegistrationUser.all
@user = ClosedRegistrationUser.new
end

def new
@user = ClosedRegistrationUser.new
end

def create
@user = ClosedRegistrationUser.new(params[:closed_registration_user].permit(:email))
if @user.save
flash[:success] = "New closed registration user created"
redirect_to admin_closed_registration_users_path
else
flash[:error] = "Can not create a user"
render :index
end
end
end
6 changes: 6 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ class ApplicationController < ActionController::Base
default_form_builder GOVUKDesignSystemFormBuilder::FormBuilder

before_action :set_sentry_user
before_action :set_feature_flag_users

private

Expand Down Expand Up @@ -41,4 +42,9 @@ def current_admin
Admin.find_by(id: session[:admin_id])
end
helper_method :current_admin

def set_feature_flag_users
users = User.where(email: ClosedRegistrationUser.pluck(:email))
users.each { |u| Flipper.enable_actor(Feature::REGISTRATION_OPEN, u) }
end
end
11 changes: 10 additions & 1 deletion app/controllers/registration_wizard_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class RegistrationWizardController < ApplicationController
before_action :registration_closed
before_action :set_wizard
before_action :set_form
before_action :check_end_of_journey, only: %i[update]
Expand Down Expand Up @@ -49,12 +50,20 @@ def check_end_of_journey
end
end

def registration_closed
return if request.path == registration_wizard_show_path(:closed)

if Feature.registration_closed?(current_user)
redirect_to registration_wizard_show_path(:closed)
end
end

def store
session["registration_store"] ||= {}
end

def wizard_params
return {} if Feature.registration_closed?
return {} if Feature.registration_closed?(current_user)

params.fetch(:registration_wizard, {}).permit(RegistrationWizard.permitted_params_for_step(params[:step].underscore))
end
Expand Down
5 changes: 5 additions & 0 deletions app/models/admin.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
class Admin < ApplicationRecord
validates :full_name, presence: true, length: { maximum: 64 }
validates :email, presence: true, length: { maximum: 64 }

# Whether this user has admin access to the feature flagging interface
def flipper_access?
super_admin?
end
end
2 changes: 2 additions & 0 deletions app/models/closed_registration_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class ClosedRegistrationUser < ApplicationRecord
end
1 change: 0 additions & 1 deletion app/models/registration_wizard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class InvalidStep < StandardError; end
attr_reader :current_step, :params, :store, :request, :current_user

def initialize(current_step:, store:, request:, current_user:, params: {})
current_step = :closed if Feature.registration_closed?
set_current_step(current_step)

@current_user = current_user
Expand Down
5 changes: 0 additions & 5 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,6 @@ def ecf_sync_jobs
.order(run_at: :asc)
end

# Whether this user has admin access to the feature flagging interface
def flipper_access?
admin? && super_admin?
end

def flipper_id
"User;#{retrieve_or_persist_feature_flag_id}"
end
Expand Down
8 changes: 4 additions & 4 deletions app/services/feature.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class Feature
REGISTRATION_OPEN_DATE = Time.zone.parse("6 June 2022 12:00")

REGISTRATION_CLOSED_KEY = "Registration closed".freeze
REGISTRATION_OPEN = "Registration open".freeze
REGISTRATION_DISABLED = "Registration disabled".freeze

FEATURE_FLAG_KEYS = [
REGISTRATION_CLOSED_KEY,
REGISTRATION_OPEN,
].freeze

class << self
Expand All @@ -27,8 +27,8 @@ def trn_required?
true
end

def registration_closed?
Flipper.enabled?(REGISTRATION_CLOSED_KEY)
def registration_closed?(user)
!Flipper.enabled?(REGISTRATION_OPEN, user)
end

def registration_disabled?
Expand Down
4 changes: 4 additions & 0 deletions app/views/admin/_layout.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,9 @@
<% component.with_nav_item(path: admin_settings_path) do %>
<%= t(".settings") %>
<% end %>

<% component.with_nav_item(path: "/admin/closed_registration_users") do %>
<%= "Closed registration users" %>
<% end %>
<% end %>
<% end %>
50 changes: 50 additions & 0 deletions app/views/admin/closed_registration_users/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
<%= render "admin/layout", title: "Closed registration users" %>

<h2 class="govuk-heading-l">Add new email</h2>
<%= form_for [:admin, @user] do |f| %>
<%= f.govuk_error_summary %>
<%= f.govuk_text_field :email, legend: { text: 'Provide course start date' } %>
<%= f.govuk_submit "Save" %>
<% end %>

<h2 class="govuk-heading-l">Currently allowed emails</h2>

<table class="govuk-table">
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<th scope="col" class="govuk-table__header">User</th>
<th scope="col" class="govuk-table__header">Has account</th>
<th scope="col" class="govuk-table__header">Last application date</th>
</tr>
</thead>

<tbody class="govuk-table__body">
<% @users.each do |user| %>
<tr class="govuk-table__row">
<td class="govuk-table__cell"><%= user.email %></td>
<td class="govuk-table__cell">
<% service_user = User.find_by(email: user.email) %>
<% if service_user.present? %>
<strong class="govuk-tag govuk-tag--green">
Yes
</strong>
<% else %>
<strong class="govuk-tag govuk-tag--red">
No
</strong>
<% end %>
</td>
<td class="govuk-table__cell">
<% if service_user.present? %>
<%= service_user.applications.order("created_at DESC").first.try(:created_at) %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>

</div>
</div>
13 changes: 13 additions & 0 deletions app/views/admin/closed_registration_users/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<h1>Admin::LateRegistrants#new</h1>
<p>Find me in app/views/admin/late_registrants/new.html.erb</p>

<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
<%= render "admin/layout", title: "Settings" %>
<%= form_for [:admin, @user] do |f| %>
<%= f.govuk_error_summary %>
<%= f.govuk_text_field :email, legend: { text: 'Provide course start date' } %>
<%= f.govuk_submit "Save" %>
<% end %>
</div>
</div>
63 changes: 63 additions & 0 deletions app/views/pages/closed_registration_exception.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<%= render "pages/choose_an_npq_and_provider_content" %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl">Register for a national professional qualification (NPQ)</h1>

<p class="govuk-body">
You need to know which NPQ you want to do and who your provider is. If you have not chosen
yet, <%= govuk_link_to("find out about NPQ courses", "https://www.gov.uk/guidance/national-professional-qualification-npq-courses") %>.

</p>

<div class="govuk-panel govuk-panel--confirmation">
<div class="govuk-panel__body">
Exceptional access to NPQ reqistration - contact support first
</div>
</div>

<p class="govuk-body">Use this service to:</p>

<ul class="govuk-list govuk-list--bullet">
<li>register for an NPQ or <%= localise_sentence_embedded_course_name(Course.ehco) %> starting before <%= application_course_start_date %></li>
<li>check your registration details, if you already registered</li>
<li>check your course outcome, if you have completed your course</li>
</ul>

<p class="govuk-body">You also need to apply separately with your training provider. They’ll send you an application form by email once you’ve registered.</p>

<h2 class="govuk-heading-m">Before you start</h2>


<p class="govuk-body">
You need to know which NPQ you want to do and who your provider is. If you have not chosen
yet, <%= govuk_link_to("find out about NPQ courses", "https://www.gov.uk/guidance/national-professional-qualification-npq-courses") %>.

</p>

<p class="govuk-body">
You also need a teacher reference number (TRN) to register for an NPQ, even if you’re not a
teacher. <%= govuk_link_to("Learn about TRNs", "https://www.gov.uk/guidance/teacher-reference-number-trn") %>
including how to request one if you do not have one.
</p>

<p class="govuk-body">
If you work in early years or
childcare, <%= govuk_link_to("check if your workplace is registered with Ofsted", "https://reports.ofsted.gov.uk/childcare") %>
and get their Ofsted unique reference number (URN) if they have one.
</p>

<p class="govuk-body">
Before registering for an NPQ you’ll be asked to create a DfE Identity account or sign in to your account.
</p>

<% if Feature.registration_enabled? %>
<%=
render(
'shared/get_an_identity/redirect_button',
button_text: "Start now"
)
%>
<% end %>

</div>
</div>
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
get "/privacy-policy", to: redirect("https://www.gov.uk/government/publications/privacy-information-education-providers-workforce-including-teachers/privacy-information-education-providers-workforce-including-teachers#NPQ"), as: :privacy_policy
get "/accessibility-statement", to: "pages#show", page: "accessibility"
get "/choose-an-npq-and-provider", to: "pages#show", page: "choose_an_npq_and_provider"
get "/closed_registration_exception", to: "pages#show", page: "closed_registration_exception"

resource :cookie_preferences do
member do
Expand Down Expand Up @@ -72,6 +73,7 @@
end

resources "settings"
resources :closed_registration_users
end

get "/admin", to: "admin#show"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CreateClosedRegistrationUsers < ActiveRecord::Migration[7.1]
def change
create_table :closed_registration_users do |t|
t.string :email

t.timestamps
end
end
end
6 changes: 6 additions & 0 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@
t.index ["user_id"], name: "index_applications_on_user_id"
end

create_table "closed_registration_users", force: :cascade do |t|
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "cohorts", force: :cascade do |t|
t.integer "start_year", null: false
t.datetime "registration_start_date", null: false
Expand Down
52 changes: 49 additions & 3 deletions spec/features/service_closed_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require "rails_helper"

RSpec.feature "Service is hard closed", type: :feature do
include_context "Stub Get An Identity Omniauth Responses"
include Helpers::AdminLogin
include Helpers::JourneyAssertionHelper
include Helpers::JourneyStepHelper

scenario "Service close date has passed" do
close_registration!
Expand Down Expand Up @@ -32,13 +34,57 @@
expect(page).to have_content("Registration for NPQs has closed temporarily")
end

context "when service is closed" do
include_context "Stub Get An Identity Omniauth Responses"

let(:super_admin) { create(:super_admin) }
let(:email) { "[email protected]" }
let(:user_email) { email }

before { close_registration! }

scenario "Allow user to register" do
visit "/"
expect(page).to have_content("Registration for NPQs has closed temporarily")

sign_in_as(super_admin)

click_link("Closed registration user")
fill_in("Email", with: email)
click_on("Save")

expect(page).to have_content("New closed registration user created")

click_link("Sign out")

visit "/closed_registration_exception"

click_on("Start now")

expect_page_to_have(path: "/registration/course-start-date", submit_form: true) do
expect(page).to have_text("NPQ start dates are usually every February and October.")
end
end

scenario "When user is not whitelisted" do
visit "/"
expect(page).to have_content("Registration for NPQs has closed temporarily")

visit "/closed_registration_exception"

click_on("Start now")

expect_page_to_have(path: "/registration/closed")
end
end

private

def close_registration!
Flipper.enable(Feature::REGISTRATION_CLOSED_KEY)
Flipper.disable(Feature::REGISTRATION_OPEN)
end

def open_registration!
Flipper.disable(Feature::REGISTRATION_CLOSED_KEY)
Flipper.enable(Feature::REGISTRATION_OPEN)
end
end
Loading
Loading