From 263000dfd7f12bc03e76c9c09d00067226412ce6 Mon Sep 17 00:00:00 2001 From: Peter Hamilton Date: Fri, 5 Jan 2024 10:11:39 +0000 Subject: [PATCH] GovOne authentication integration changes (#1020) * WIP * tweak logout path logic * Existing session logic * Opt in WCAG logic * add check for session id token in logout link * QA debug * Avoid duplicate hits on about page * Sanity check * Fix memory issue for QA locally and in pipeline? * Trigger full WCAG check on demand if already deployed and includes changes * Factory and count * Test feature in pipeline * Integrate GovOne to replace existing sessions and skip deprecated specs * Update docs and fix specs * Increase coverage * Fix pa11y and plan to retire old devise functionality * Tidy * Delete old GPaaS debugging var --------- Co-authored-by: jack.coggin --- .github/labeler.yml | 1 + .github/workflows/ci.yml | 7 + .github/workflows/pa11y.yml | 2 +- .github/workflows/qa.yml | 6 +- .yardopts | 2 +- gov_one_login/GOV-ONE-LOGIN.md => GOV_ONE.md | 0 README.md | 7 +- RELEASE.md | 8 +- app/controllers/gov_one_controller.rb | 7 - app/controllers/users/sessions_controller.rb | 10 ++ app/helpers/application_helper.rb | 18 +-- app/helpers/link_helper.rb | 6 + app/models/data_analysis/user_overview.rb | 6 +- app/models/user.rb | 17 ++- app/views/about/_enrol.html.slim | 11 +- .../sessions/gov_one.html.slim} | 11 +- app/views/home/_enrol_buttons.html.slim | 4 - app/views/home/_prompt.html.slim | 7 + app/views/home/index.html.slim | 47 ++---- app/views/learning/_cms_debug.html.slim | 2 - bin/docker-pa11y | 6 +- bin/docker-qa | 2 +- cms/CONTENTFUL.md | 8 +- config/application.rb | 24 +-- .../initializers/content_security_policy.rb | 2 - config/routes.rb | 10 +- config/sitemap.rb | 33 +++-- docker-compose.dev.yml | 4 +- docker-compose.qa.yml | 7 +- docker-entrypoint.pa11y.sh | 18 +-- docker-entrypoint.sh | 16 +- lib/seed_images.rb | 2 +- manifest.yml | 60 -------- spec/factories/users.rb | 6 + spec/helpers/content_helper_spec.rb | 25 ++++ .../data_analysis/user_overview_spec.rb | 42 +++--- spec/rails_helper.rb | 5 +- spec/requests/authentication_spec.rb | 140 ++++++++---------- spec/support/shared/with_user.rb | 22 ++- spec/system/account_page_spec.rb | 40 ++--- .../completing_registration_spec.rb | 25 ++-- spec/system/forgotten_password_spec.rb | 4 + spec/system/front_page_spec.rb | 21 ++- spec/system/gov_one_info_spec.rb | 25 ---- spec/system/gov_one_spec.rb | 32 ++++ spec/system/sign_in_spec.rb | 5 +- spec/system/whats_new_page_spec.rb | 13 +- ui/pages/sign_in.rb | 2 +- uml/deployment.puml | 10 +- 49 files changed, 398 insertions(+), 390 deletions(-) rename gov_one_login/GOV-ONE-LOGIN.md => GOV_ONE.md (100%) delete mode 100644 app/controllers/gov_one_controller.rb rename app/views/{gov_one/show.html.slim => devise/sessions/gov_one.html.slim} (76%) delete mode 100644 app/views/home/_enrol_buttons.html.slim create mode 100644 app/views/home/_prompt.html.slim delete mode 100644 manifest.yml delete mode 100644 spec/system/gov_one_info_spec.rb create mode 100644 spec/system/gov_one_spec.rb diff --git a/.github/labeler.yml b/.github/labeler.yml index ca25b8078..c3cbc7988 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -17,6 +17,7 @@ terraform: frontend: - changed-files: - any-glob-to-any-file: + - app/views/**/*.html.slim - app/assets/images/* - app/assets/stylesheets/**/* - app/javascript/**/* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0b10efcf..af1366b39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,8 +83,15 @@ jobs: - name: Run rubocop run: bundle exec rubocop + # Answer migration feature test # - # name: Run test suite # run: bundle exec rspec # env: # DISABLE_USER_ANSWER: true + # Gov One feature test + - + name: Run test suite + run: bundle exec rspec + env: + GOV_ONE_LOGIN: true diff --git a/.github/workflows/pa11y.yml b/.github/workflows/pa11y.yml index 1737fdb39..26b810ed4 100644 --- a/.github/workflows/pa11y.yml +++ b/.github/workflows/pa11y.yml @@ -17,7 +17,7 @@ on: jobs: test: - if: contains(github.event.pull_request.labels.*.name, 'review') + if: contains(github.event.pull_request.labels.*.name, 'review') && contains(github.event.pull_request.labels.*.name, 'frontend') && contains(github.event.pull_request.labels.*.name, 'a11y') runs-on: ubuntu-latest environment: development env: diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 588568d5c..a7d7403d3 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -38,10 +38,14 @@ jobs: image: selenium/standalone-chrome:latest ports: - 4441:4444 + volumes: + - /dev/shm:/dev/shm firefox: image: selenium/standalone-firefox:latest ports: - 4442:4444 + volumes: + - /dev/shm:/dev/shm steps: - @@ -67,4 +71,4 @@ jobs: name: Use Firefox env: BROWSER: standalone_firefox - run: bundle exec rspec --default-path ui \ No newline at end of file + run: bundle exec rspec --default-path ui diff --git a/.yardopts b/.yardopts index 6f31f194c..b8bb3a932 100644 --- a/.yardopts +++ b/.yardopts @@ -5,9 +5,9 @@ --markup markdown - cms/*.md -gov_one_login/*.md data/*.md uml/*.md adr/*.md RELEASE.md +GOV_ONE.md LICENSE diff --git a/gov_one_login/GOV-ONE-LOGIN.md b/GOV_ONE.md similarity index 100% rename from gov_one_login/GOV-ONE-LOGIN.md rename to GOV_ONE.md diff --git a/README.md b/README.md index c2d92d426..918b2a0e0 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ Manually adding the **"deployed"** label to a pull request in Github will cause This supports manual testing and content review in a production environment. When a feature branch review application is deployed, the URL to access it is added as a comment -in the PR conversation in the format: +in the PR conversation in the format: Review applications are deployed with 3 seeded user accounts that share a restricted password. This facilitates team members demoing content and functionality, so registration is not required. @@ -315,9 +315,10 @@ or in the UK Government digital slack workspace in the `#govuk-notify` channel. --- -# One Login +# GovOne Login - +Register an account on the integration OIDC used in development . +Using this authentication method also requires basic HTTP auth credentials. --- diff --git a/RELEASE.md b/RELEASE.md index 8a99df9e3..21df5010c 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -22,7 +22,7 @@ We use 9 swim lanes on the [Jira][jira] board. - `content` deployment - `ER-456` branch -- +- - [feature deployments][deployments] - meets [definition of done](#definition-of-done) - mark PR as `ready` and [request review](#review-process) @@ -40,14 +40,14 @@ We use 9 swim lanes on the [Jira][jira] board. - `development` deployment - `main` branch -- +- - update accessibility and quality checks as required **7. Approval** - `staging` deployment - `rcx.x.x` release candidate tag -- +- - [open milestones (release candidates)][release-candidates] - seek product owner sign-off @@ -55,7 +55,7 @@ We use 9 swim lanes on the [Jira][jira] board. - `production` deployment - `vx.x.x` version tag -- +- - [close milestone][released-versions] and rename from `rc` to `v` - periodically publish a [release][releases] CHANGELOG diff --git a/app/controllers/gov_one_controller.rb b/app/controllers/gov_one_controller.rb deleted file mode 100644 index 25faf07d0..000000000 --- a/app/controllers/gov_one_controller.rb +++ /dev/null @@ -1,7 +0,0 @@ -class GovOneController < ApplicationController - layout 'hero' - - def show - redirect_to my_modules_path if current_user - end -end diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index aeb2584a5..b079bb626 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -1,6 +1,16 @@ # frozen_string_literal: true class Users::SessionsController < Devise::SessionsController + layout 'hero' if Rails.application.gov_one_login? + + def new + if Rails.application.gov_one_login? + render 'gov_one' + else + super + end + end + protected def after_sign_in_path_for(resource) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a892f5b4a..d7b80bbf6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -11,14 +11,14 @@ def navigation header.with_navigation_item(text: 'Home', href: root_path, classes: %w[dfe-header__navigation-item]) if user_signed_in? header.with_action_link(text: 'My Account', href: user_path, options: { inverse: true }) - header.with_action_link(text: 'Sign out', href: logout_path, options: { id: 'sign-out-desktop', data: { turbo_method: :get }, inverse: true }) + header.with_action_link(text: 'Sign out', href: destroy_user_session_path, options: { id: 'sign-out-desktop', data: { turbo_method: :get }, inverse: true }) header.with_navigation_item(text: 'My modules', href: my_modules_path, classes: %w[dfe-header__navigation-item]) header.with_navigation_item(text: 'Learning log', href: user_notes_path, classes: %w[dfe-header__navigation-items]) if current_user.course_started? header.with_navigation_item(text: 'My account', href: user_path, classes: %w[dfe-header__navigation-item dfe-header-f-mob]) - header.with_navigation_item(text: 'Sign out', href: logout_path, options: { data: { turbo_method: :get } }, classes: %w[dfe-header__navigation-item dfe-header-f-mob], html_attributes: { id: 'sign-out-f-mob' }) + header.with_navigation_item(text: 'Sign out', href: destroy_user_session_path, options: { data: { turbo_method: :get } }, classes: %w[dfe-header__navigation-item dfe-header-f-mob], html_attributes: { id: 'sign-out-f-mob' }) else - header.with_action_link(text: 'Sign in', href: login_path, options: { inverse: true }) - header.with_navigation_item(text: 'Sign in', href: login_path, classes: %w[dfe-header__navigation-item dfe-header-f-mob]) + header.with_action_link(text: 'Sign in', href: new_user_session_path, options: { inverse: true }) + header.with_navigation_item(text: 'Sign in', href: new_user_session_path, classes: %w[dfe-header__navigation-item dfe-header-f-mob]) end end end @@ -59,14 +59,4 @@ def html_title(*parts) def calculate_module_state CalculateModuleState.new(user: current_user).call end - - # @return [String] - def login_path - Rails.application.gov_one_login? ? gov_one_info_path : new_user_session_path - end - - # @return [String] - def logout_path - Rails.application.gov_one_login? ? logout_uri.to_s : destroy_user_session_path - end end diff --git a/app/helpers/link_helper.rb b/app/helpers/link_helper.rb index d83ae3488..d07dad60c 100644 --- a/app/helpers/link_helper.rb +++ b/app/helpers/link_helper.rb @@ -1,4 +1,10 @@ module LinkHelper + # @note Handle active sessions for feature flag Rails.application.gov_one_login? + # @return [String] + def destroy_user_session_path + session[:id_token].present? ? logout_uri.to_s : super + end + # OPTIMIZE: use this helper for all back link logic and consistent location # # @return [String, nil] diff --git a/app/models/data_analysis/user_overview.rb b/app/models/data_analysis/user_overview.rb index 18b50436d..1031cd350 100644 --- a/app/models/data_analysis/user_overview.rb +++ b/app/models/data_analysis/user_overview.rb @@ -19,6 +19,7 @@ def column_names 'Locked Out', 'Confirmed', 'Unconfirmed', + 'GovOne', 'User Defined Roles', 'Started Learning', 'Not Started Learning', @@ -49,13 +50,14 @@ def dashboard locked_out: User.locked_out.count, confirmed: User.confirmed.count, unconfirmed: User.unconfirmed.count, + gov_one: User.gov_one.count, user_defined_roles: User.all.collect(&:role_type_other).uniq.count, started_learning: started_learning, not_started_learning: not_started_learning, with_notes: with_notes_count, - with_notes_percentage: with_notes_percentage, + with_notes_percentage: with_notes_percentage.round(2), without_notes: without_notes_count, - without_notes_percentage: 1 - with_notes_percentage, + without_notes_percentage: (1 - with_notes_percentage).round(2), complete_registration_mail_recipients: CompleteRegistrationMailJob.recipients.count, start_training_mail_recipients: StartTrainingMailJob.recipients.count, continue_training_mail_recipients: ContinueTrainingMailJob.recipients.count, diff --git a/app/models/user.rb b/app/models/user.rb index 4416344e8..237609862 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -31,18 +31,27 @@ def self.find_or_create_from_gov_one(email:, gov_one_id:) user.save! else user = new(email: email, gov_one_id: gov_one_id, confirmed_at: Time.zone.now) - user.save!(validate: false) + user.save!(validate: false) # TODO: validate despite blank password end user end - # Include default devise modules. Others available are: - # :timeoutable, :trackable, :recoverable and :omniauthable attr_accessor :context devise :database_authenticatable, :registerable, :recoverable, :validatable, :rememberable, :confirmable, :lockable, :timeoutable, :secure_validatable, :omniauthable, omniauth_providers: [:openid_connect] + + # FIXME: retire old devise functionality + # if Rails.application.gov_one_login? + # devise :database_authenticatable, :rememberable, :lockable, :timeoutable, + # :omniauthable, omniauth_providers: [:openid_connect] + # else + # devise :database_authenticatable, :registerable, :recoverable, + # :validatable, :rememberable, :confirmable, :lockable, :timeoutable, + # :secure_validatable + # end + devise :pwned_password unless Rails.env.test? has_many :responses @@ -53,6 +62,8 @@ def self.find_or_create_from_gov_one(email:, gov_one_id:) has_many :events, class_name: 'Ahoy::Event' has_many :notes + scope :gov_one, -> { where.not(gov_one_id: nil) } + # account status scope :public_beta_only_registration_complete, -> { registered_since_private_beta.registration_complete } scope :since_public_beta, -> { where(created_at: Rails.application.public_beta_launch_date..Time.zone.now) } diff --git a/app/views/about/_enrol.html.slim b/app/views/about/_enrol.html.slim index 542ad5f91..d1d078cc7 100644 --- a/app/views/about/_enrol.html.slim +++ b/app/views/about/_enrol.html.slim @@ -1,4 +1,13 @@ - unless current_user .light-grey-box class='govuk-!-margin-top-8 govuk-!-margin-bottom-4' = m('about.enrol') - = render 'home/enrol_buttons' + + .govuk-button-group + - if Rails.application.gov_one_login? + = govuk_link_to 'Create an account or sign in', new_user_session_path + + - else + = govuk_button_link_to 'Create an account', new_user_registration_path + .white-space-pre-wrap= ' or ' + = govuk_link_to 'sign in', new_user_session_path + diff --git a/app/views/gov_one/show.html.slim b/app/views/devise/sessions/gov_one.html.slim similarity index 76% rename from app/views/gov_one/show.html.slim rename to app/views/devise/sessions/gov_one.html.slim index f6e82ab15..809f5fe81 100644 --- a/app/views/gov_one/show.html.slim +++ b/app/views/devise/sessions/gov_one.html.slim @@ -1,20 +1,19 @@ - content_for :page_title do - = html_title t('home.title') + = html_title t('account_login.title') - content_for :hero do .govuk-grid-row class='govuk-!-padding-top-9' .govuk-grid-column-three-quarters h1.dfe-heading-xl class='govuk-!-margin-bottom-4' = t('gov_one_info.hero.header') - p.govuk-body-l = t('gov_one_info.hero.body') + p.govuk-body-l + = t('gov_one_info.hero.body') .govuk-grid-row .govuk-grid-column-full - . class='govuk-!-margin-bottom-5' - = m('gov_one_info.body') - hr - + = m('gov_one_info.body') + hr.govuk-section-break.govuk-section-break--visible.govuk-section-break--l = login_button .govuk-grid-row diff --git a/app/views/home/_enrol_buttons.html.slim b/app/views/home/_enrol_buttons.html.slim deleted file mode 100644 index 403a24bf5..000000000 --- a/app/views/home/_enrol_buttons.html.slim +++ /dev/null @@ -1,4 +0,0 @@ -.govuk-button-group - = govuk_button_link_to 'Create an account', new_user_registration_path - .white-space-pre-wrap= ' or ' - = govuk_link_to 'sign in', new_user_session_path diff --git a/app/views/home/_prompt.html.slim b/app/views/home/_prompt.html.slim new file mode 100644 index 000000000..c9b1aa23e --- /dev/null +++ b/app/views/home/_prompt.html.slim @@ -0,0 +1,7 @@ +.prompt.prompt-home + .govuk-grid-row + .govuk-grid-column-one-quarter + i.fa-2x.fa-solid.fa-circle-info aria-describedby='info icon' + + .govuk-grid-column-three-quarters + = m('home.prompt', headings_start_with: 'xl') \ No newline at end of file diff --git a/app/views/home/index.html.slim b/app/views/home/index.html.slim index e8ebba061..3a811e45f 100644 --- a/app/views/home/index.html.slim +++ b/app/views/home/index.html.slim @@ -1,41 +1,28 @@ -- if Rails.application.gov_one_login? - - content_for :page_title do - = html_title t('home.title') +- content_for :page_title do + = html_title t('home.title') - - content_for :hero do - = render 'hero' +- content_for :hero do + = render 'hero' - = render 'learning/cms_debug' - = render 'debug' += render 'learning/cms_debug' += render 'debug' + +- if Rails.application.gov_one_login? # ---------------------------------------- .govuk-grid-row .govuk-grid-column-one-half = m('home.about', headings_start_with: 'xl') - .prompt.prompt-home - .govuk-grid-row - .govuk-grid-column-one-quarter - i.fa-2x.fa-solid.fa-circle-info aria-describedby='info icon' - - .govuk-grid-column-three-quarters - = m('home.prompt', headings_start_with: 'xl') + = render 'prompt' - unless current_user - .govuk-grid-row class="govuk-!-margin-top-9" + .govuk-grid-row class='govuk-!-margin-top-9' .govuk-grid-column-full - = govuk_button_link_to gov_one_info_path, class: "govuk-button--start" do - | #{t('home.gov_one_button')} + = govuk_button_link_to new_user_session_path, class: 'govuk-button--start' do + = t('home.gov_one_button') = render 'chevron' -- else - - content_for :page_title do - = html_title t('home.title') - - - content_for :hero do - = render 'hero' - - = render 'learning/cms_debug' - = render 'debug' +- else # ----------------------------------------------------------------------- .govuk-grid-row .govuk-grid-column-one-half @@ -51,10 +38,4 @@ .white-space-pre-wrap= ' or ' = govuk_link_to 'create an account', new_user_registration_path - .prompt.prompt-home - .govuk-grid-row - .govuk-grid-column-one-quarter - i.fa-2x.fa-solid.fa-circle-info aria-describedby='info icon' - - .govuk-grid-column-three-quarters - = m('home.prompt', headings_start_with: 'xl') + = render 'prompt' diff --git a/app/views/learning/_cms_debug.html.slim b/app/views/learning/_cms_debug.html.slim index 3eb9ec18e..dcf60bd0c 100644 --- a/app/views/learning/_cms_debug.html.slim +++ b/app/views/learning/_cms_debug.html.slim @@ -1,7 +1,5 @@ - if debug? pre.debug_dump - h4 Deployment - | instance: #{ENV['CF_INSTANCE_INDEX']} h4 Contentful | env: #{ContentfulRails.configuration.environment} br diff --git a/bin/docker-pa11y b/bin/docker-pa11y index a3a79e646..a7e71d41f 100755 --- a/bin/docker-pa11y +++ b/bin/docker-pa11y @@ -3,16 +3,18 @@ # Check accessibility of running dev container against latest sitemap # or an external site # -# ./bin/docker-pa11y https://ey-recovery-dev.london.cloudapps.digital +# ./bin/docker-pa11y https://eyrecovery-dev.azurewebsites.net # ------------------------------------------------------------------------------ set -e ./bin/docker-rails eyfs:bot sitemap:refresh:no_ping +BASE_URL=${1-"http://app:3000"} \ + docker-compose \ -f docker-compose.yml \ -f docker-compose.dev.yml \ --project-name recovery \ run \ --name recovery_pa11y \ - --rm pa11y $1 + --rm pa11y $BASE_URL diff --git a/bin/docker-qa b/bin/docker-qa index 275e3494a..a6b0e80a4 100755 --- a/bin/docker-qa +++ b/bin/docker-qa @@ -5,7 +5,7 @@ # @example # $ ./bin/docker-prod # $ TYPE=firefox ./bin/docker-qa -# $ BASE_URL=https://ey-recovery.london.cloudapps.digital USER_PASSWORD=secret ./bin/docker-qa +# $ BASE_URL=https://eyrecovery-review-pr-123.azurewebsites.net USER_PASSWORD=secret ./bin/docker-qa # # ------------------------------------------------------------------------------ set -e diff --git a/cms/CONTENTFUL.md b/cms/CONTENTFUL.md index 16c5a6b57..04c1145aa 100644 --- a/cms/CONTENTFUL.md +++ b/cms/CONTENTFUL.md @@ -87,7 +87,7 @@ Used by developers when editing module content, usually demo content. Used by developers when editing demo module content. -As above replace `http://localhost:3000` with `https://ey-recovery-dev.london.cloudapps.digital` +As above replace `http://localhost:3000` with `https://eyrecovery-dev.azurewebsites.net` **Staging** @@ -117,7 +117,7 @@ As above replace `http://localhost:3000` with `https://staging.child-development - Name: `Release content for Production (delivery)` - Filters: `sys.environment.sys.id` equals `master` -- URL: `POST` to `https://ey-recovery.london.cloudapps.digital/release` +- URL: `POST` to `https://child-development-training.education.gov.uk/release` - Content events triggers: N/A - Other API events: `Release` action `Execute` @@ -125,7 +125,7 @@ As above replace `http://localhost:3000` with `https://staging.child-development - Name: `Publish stand-alone pages for Production (delivery)` - Filters: `sys.environment.sys.id` equals `master` and `sys.contentType.sys.id` in `static` or `resource` -- URL: `POST` to `https://ey-recovery.london.cloudapps.digital/change` +- URL: `POST` to `https://child-development-training.education.gov.uk/change` - Content events triggers: `Publish` of `Entry` if `static` - Other API events: N/A @@ -133,7 +133,7 @@ As above replace `http://localhost:3000` with `https://staging.child-development - Name: `Autosave demo training content for Dev (preview)` - Filters: `sys.environment.sys.id` equals `test` -- URL: `POST` to `https://ey-recovery-dev.london.cloudapps.digital/change` +- URL: `POST` to `https://eyrecovery-dev.azurewebsites.net/change` - Content events triggers: `Autosave` of `Entry` or `Asset` - Other API events: N/A diff --git a/config/application.rb b/config/application.rb index f156a5e3d..e18608d0a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -45,23 +45,23 @@ class Application < Rails::Application config.active_storage.queues.analysis = :default config.active_storage.queues.purge = :default - config.google_cloud_bucket = ENV.fetch('GOOGLE_CLOUD_BUCKET', '#GOOGLE_CLOUD_BUCKET_env_var_missing') + config.google_cloud_bucket = ENV.fetch('GOOGLE_CLOUD_BUCKET', '#GOOGLE_CLOUD_BUCKET_env_var_missing') config.dashboard_update_interval = ENV.fetch('DASHBOARD_UPDATE_INTERVAL', '0 0 * * *') # Midnight daily - config.mail_job_interval = ENV.fetch('MAIL_JOB_INTERVAL', '0 12 * * *') # Noon daily + config.mail_job_interval = ENV.fetch('MAIL_JOB_INTERVAL', '0 12 * * *') # Noon daily + config.user_password = ENV.fetch('USER_PASSWORD', 'Str0ngPa$$w0rd12') config.bot_token = ENV['BOT_TOKEN'] config.feedback_url = ENV.fetch('FEEDBACK_URL', '#FEEDBACK_URL_env_var_missing') config.privacy_policy_url = 'https://www.gov.uk/government/publications/privacy-information-members-of-the-public/privacy-information-members-of-the-public' config.google_analytics_tracking_id = ENV.fetch('TRACKING_ID', '#TRACKING_ID_env_var_missing') config.hotjar_site_id = ENV.fetch('HOTJAR_SITE_ID', '#HOTJAR_SITE_ID_env_var_missing') - config.unlock_in_minutes = ENV.fetch('UNLOCK_IN_MINUTES', '120').to_i - config.user_timeout_minutes = ENV.fetch('TIMEOUT_MINUTES', '25').to_i + # Timeout # user_timeout_warning_minutes and user_timeout_modal_visible value combined must be lower than user_timeout_minutes + config.unlock_in_minutes = ENV.fetch('UNLOCK_IN_MINUTES', '120').to_i + config.user_timeout_minutes = ENV.fetch('TIMEOUT_MINUTES', '25').to_i config.user_timeout_warning_minutes = ENV.fetch('TIMEOUT_WARNING_MINUTES', '20').to_i - config.user_timeout_modal_visible = ENV.fetch('TIMEOUT_MODAL_VISIBLE', '5').to_i - - config.user_password = ENV.fetch('USER_PASSWORD', 'Str0ngPa$$w0rd12') + config.user_timeout_modal_visible = ENV.fetch('TIMEOUT_MODAL_VISIBLE', '5').to_i # Contentful config.contentful_space = ENV.fetch('CONTENTFUL_SPACE', credentials.dig(:contentful, :space)) @@ -70,14 +70,14 @@ class Application < Rails::Application config.contentful_management_access_token = ENV.fetch('CONTENTFUL_MANAGEMENT_TOKEN', credentials.dig(:contentful, :management_access_token)) # TODO: use service account management token config.contentful_environment = ENV.fetch('CONTENTFUL_ENVIRONMENT', credentials.dig(:contentful, :environment)) - # Gov one - config.gov_one_base_uri = credentials.dig(:gov_one, :base_uri) - config.gov_one_private_key = credentials.dig(:gov_one, :private_key) - config.gov_one_client_id = credentials.dig(:gov_one, :client_id) + # Gov One + config.gov_one_base_uri = credentials.dig(:gov_one, :base_uri) + config.gov_one_private_key = credentials.dig(:gov_one, :private_key) + config.gov_one_client_id = credentials.dig(:gov_one, :client_id) # @return [Boolean] def live? - ENV['WORKSPACE'].eql?('production') || ENV['ENVIRONMENT'].eql?('production') + ENV['ENVIRONMENT'].eql?('production') end # @see ContentfulRails.configuration.enable_preview_domain diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 20aa886c8..a39a405e5 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -13,8 +13,6 @@ # # Add URLs in order to import images or javascript from another domain # -# '*.s3.eu-west-2.amazonaws.com', -# 'eyfs-cms-preprod.london.cloudapps.digital', GOVUK_DOMAINS = %w[ *.education.gov.uk ].freeze diff --git a/config/routes.rb b/config/routes.rb index 8f79e608a..2d0f3d532 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,6 @@ get 'health', to: 'home#show' get 'audit', to: 'home#audit' get 'my-modules', to: 'learning#show' # @see User#course - get 'gov-one/info', to: 'gov_one#show' get '404', to: 'errors#not_found', via: :all get '422', to: 'errors#unprocessable_entity', via: :all @@ -14,15 +13,15 @@ devise_for :users, controllers: { sessions: 'users/sessions', - confirmations: 'confirmations', - passwords: 'passwords', - registrations: 'registrations', + confirmations: 'confirmations', # unless Rails.application.gov_one_login? + passwords: 'passwords', # unless Rails.application.gov_one_login? + registrations: 'registrations', # unless Rails.application.gov_one_login? omniauth_callbacks: 'users/omniauth_callbacks', }, path_names: { sign_in: 'sign-in', sign_out: 'sign-out', - sign_up: 'sign-up', + sign_up: 'sign-up', # unless Rails.application.gov_one_login? } # @see TimeoutWarning js component @@ -54,7 +53,6 @@ get 'check-email-confirmation' get 'check-email-password-reset' get 'edit-training-emails' - devise_for :users, controllers: { omniauth_callbacks: 'controllers/users/omniauth_callbacks' } patch 'update-training-emails' resource :close_account, only: %i[new update show], path: 'close' do diff --git a/config/sitemap.rb b/config/sitemap.rb index 397a244bb..23b614763 100644 --- a/config/sitemap.rb +++ b/config/sitemap.rb @@ -44,17 +44,19 @@ add course_overview_path add experts_path - Training::Module.ordered.each do |mod| + Training::Module.live.each do |mod| add about_path(mod.name) end # devise + # unless Rails.application.gov_one_login? add new_user_unlock_path add new_user_confirmation_path add new_user_registration_path - add new_user_session_path + # end add check_email_confirmation_user_path add check_email_password_reset_user_path + add new_user_session_path # private pages # ------------------------------------------ @@ -62,14 +64,11 @@ # account add user_path - # GOV.UK one login - add gov_one_info_path - # edit registration/account add edit_email_user_path add edit_password_user_path add edit_registration_terms_and_conditions_path - add edit_registration_name_path + add edit_registration_name_path # unless Rails.application.gov_one_login? add edit_registration_setting_type_path add edit_registration_setting_type_other_path add edit_registration_local_authority_path @@ -88,16 +87,18 @@ add my_modules_path add user_notes_path - # Course content - Training::Module.ordered.each do |mod| - mod.content.each do |page| - if page.is_question? - add training_module_question_path(mod.name, page.name) - elsif page.assessment_results? - add training_module_assessment_path(mod.name, page.name) - else - add training_module_page_path(mod.name, page.name) - end + # Course common start page + mod = Training::Module.live.first + add training_module_page_path(mod.name, mod.pages.first.name) + + # Course content random module + Training::Module.live.sample.content.each do |page| + if page.is_question? + add training_module_question_path(page.parent.name, page.name) + elsif page.assessment_results? + add training_module_assessment_path(page.parent.name, page.name) + else + add training_module_page_path(page.parent.name, page.name) end end end diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 7287b9819..f46f7e541 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -19,7 +19,7 @@ services: # app config - DATABASE_URL=postgres://postgres:password@db:5432/early_years_foundation_recovery_development - RAILS_ENV=development - - DOMAIN=app:3000 + - DOMAIN=localhost:3000 - RAILS_SERVE_STATIC_FILES=true volumes: - .:/srv @@ -67,7 +67,7 @@ services: target: pa11y image: recovery:pa11y environment: - - DOMAIN=app:3000 + - DOMAIN=localhost:3000 - BOT_TOKEN depends_on: app: diff --git a/docker-compose.qa.yml b/docker-compose.qa.yml index 3fd5fd5ee..ee79373c1 100644 --- a/docker-compose.qa.yml +++ b/docker-compose.qa.yml @@ -1,7 +1,7 @@ # ------------------------------------------------------------------------------ # Seed the production database: # -# $ docker exec -it recovery_prod rails db:seed +# $ docker exec -it recovery_prod rails db:create db:prepare db:seed # --- services: @@ -12,6 +12,7 @@ services: environment: - DATABASE_URL=postgres://postgres:password@db:5432/early_years_foundation_recovery_production - DOMAIN=https://localhost:3000 + - PROXY_CERT=/srv/localhost.crt # overrides - WORKSPACE - USER_PASSWORD @@ -52,6 +53,8 @@ services: chrome: container_name: recovery_chrome image: selenium/standalone-chrome:latest + volumes: + - /dev/shm:/dev/shm ports: - 4441:4444 healthcheck: @@ -62,6 +65,8 @@ services: firefox: container_name: recovery_firefox image: selenium/standalone-firefox:latest + volumes: + - /dev/shm:/dev/shm ports: - 4442:4444 healthcheck: diff --git a/docker-entrypoint.pa11y.sh b/docker-entrypoint.pa11y.sh index aa5262cc1..f53518f73 100755 --- a/docker-entrypoint.pa11y.sh +++ b/docker-entrypoint.pa11y.sh @@ -4,16 +4,10 @@ set -e sed -i "s/token/${BOT_TOKEN}/g" /usr/config.json -if [ ! -z "$1" ]; then - echo "Sitemap using: $1" +echo "Sitemap using: ${1}" - exec pa11y-ci \ - --config /usr/config.json \ - --sitemap http://${DOMAIN}/sitemap.xml \ - --sitemap-find http://${DOMAIN} \ - --sitemap-replace ${1} -else - exec pa11y-ci \ - --config /usr/config.json \ - --sitemap http://${DOMAIN}/sitemap.xml -fi +exec pa11y-ci \ + --config /usr/config.json \ + --sitemap ${1}/sitemap.xml \ + --sitemap-find http://${DOMAIN} \ + --sitemap-replace ${1} diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 7de9e4bc0..33f496e39 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -2,16 +2,16 @@ # ------------------------------------------------------------------------------ set -e -if [ ${RAILS_ENV} != "production" ] +if [ -z ${PROXY_CERT} ] then + echo "No proxy certificate to append" +else + echo "Appending proxy certificate" + cat $PROXY_CERT >> /etc/ssl/certs/ca-certificates.crt +fi - if [ -z ${PROXY_CERT} ] - then - echo "No proxy certificate to append" - else - echo "Appending proxy certificate" - cat $PROXY_CERT >> /etc/ssl/certs/ca-certificates.crt - fi +if [ ${RAILS_ENV} != "production" ] +then # # Development & Test diff --git a/lib/seed_images.rb b/lib/seed_images.rb index 88cc50201..f9e8cce44 100644 --- a/lib/seed_images.rb +++ b/lib/seed_images.rb @@ -23,7 +23,7 @@ def call private # @return [String] - IMG_HOST = 'https://ey-recovery-dev.london.cloudapps.digital'.freeze + IMG_HOST = 'https://eyrecovery-dev.azurewebsites.net'.freeze # @param asset [Contentful::Management::Asset] # @return [String] diff --git a/manifest.yml b/manifest.yml deleted file mode 100644 index b6ef6c728..000000000 --- a/manifest.yml +++ /dev/null @@ -1,60 +0,0 @@ -# -# https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html -# https://docs.cloud.service.gov.uk/deploying_apps.html#deploying-public-apps -# -# $ cf target -s content -# $ cf create-service postgres small-13 ey-recovery-test-db -# $ cf push --var rails_master_key=`cat config/credentials/production.key` --strategy rolling -# $ cf stop ey-recovery-test -# -# ------------------------------------------------------------------------------ ---- -applications: - - # app - name: ey-recovery-test - type: web - memory: 512M - disk_quota: 2G - instances: 1 - - health_check_type: http - health_check_http_endpoint: /health - - command: | - bundle exec rails db:create db:migrate db:seed assets:precompile; \ - bundle exec rails server -b 0.0.0.0 - - docker: - image: ghcr.io/dfe-digital/early-years-foundation-recovery:rc0.6.2 - - routes: - - route: ey-recovery-test.london.cloudapps.digital - - services: - - ey-recovery-test-db - - env: - DASHBOARD_UPDATE: false - CONTENTFUL_PREVIEW: true - GROVER_NO_SANDBOX: true - RAILS_LOG_TO_STDOUT: true - RAILS_SERVE_STATIC_FILES: true - - EDITOR: vi - RAILS_MASTER_KEY: ((rails_master_key)) - - DATABASE_URL: 'postgres://postgres@localhost:5432/db' - DOMAIN: ey-recovery-test.london.cloudapps.digital - - NODE_ENV: production - RAILS_ENV: production - CONTENTFUL_ENVIRONMENT: staging - - RAILS_MAX_THREADS: 5 - WEB_CONCURRENCY: 2 - - # - # jobs - # name: ey-recovery-test-worker - # type: worker - # command: bundle exec que - # no-route: true diff --git a/spec/factories/users.rb b/spec/factories/users.rb index e4a323106..41e50ff5b 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -27,6 +27,12 @@ registration_complete { true } end + factory :gov_one_user do + registered + gov_one_id { 'urn:fdc:gov.uk:2022:23-random-alpha-numeric' } + # password { nil } + end + # Personas ----------------------------------------------------------------- trait :agency_childminder do diff --git a/spec/helpers/content_helper_spec.rb b/spec/helpers/content_helper_spec.rb index 925c37b02..79d2fc9d5 100644 --- a/spec/helpers/content_helper_spec.rb +++ b/spec/helpers/content_helper_spec.rb @@ -1,6 +1,31 @@ require 'rails_helper' describe 'ContentHelper', type: :helper do + describe '#completed_modules_table' do + subject(:html) { helper.completed_modules_table } + + let(:user) { create(:user, :registered) } + + before do + create :event, + name: 'module_complete', + user: user, properties: + { training_module_id: 'alpha' } + + allow(helper).to receive(:current_user).and_return(user) + end + + it 'creates a table' do + expect(html).to include '' + expect(html).to include 'Completed modules' + expect(html).to include 'Module name' + expect(html).to include 'Date completed' + expect(html).to include 'Actions' + expect(html).to have_link 'First Training Module', href: '/modules/alpha' + expect(html).to have_link 'View certificate', href: '/modules/alpha/content-pages/1-3-4' + end + end + describe '#m' do subject(:html) { helper.m(input) } diff --git a/spec/models/data_analysis/user_overview_spec.rb b/spec/models/data_analysis/user_overview_spec.rb index 425069d95..415475297 100644 --- a/spec/models/data_analysis/user_overview_spec.rb +++ b/spec/models/data_analysis/user_overview_spec.rb @@ -17,6 +17,7 @@ 'Locked Out', 'Confirmed', 'Unconfirmed', + 'GovOne', 'User Defined Roles', 'Started Learning', 'Not Started Learning', @@ -34,30 +35,31 @@ let(:rows) do [ { - registration_complete: 4, + registration_complete: 5, registration_incomplete: 1, reregistered: 0, - registered_since_private_beta: 5, + registered_since_private_beta: 6, private_beta_only_registration_incomplete: 0, private_beta_only_registration_complete: 0, registration_events: 0, private_beta_registration_events: 0, public_beta_registration_events: 0, - total: 5, + total: 6, locked_out: 0, - confirmed: 5, + confirmed: 6, unconfirmed: 0, + gov_one: 1, user_defined_roles: 2, started_learning: 3, - not_started_learning: 2, + not_started_learning: 3, with_notes: 2, - with_notes_percentage: 0.4, - without_notes: 3, - without_notes_percentage: 0.6, + with_notes_percentage: 0.33, + without_notes: 4, + without_notes_percentage: 0.67, complete_registration_mail_recipients: 1, start_training_mail_recipients: 1, continue_training_mail_recipients: 0, - new_module_mail_recipients: 5, + new_module_mail_recipients: 6, }, ] end @@ -79,23 +81,25 @@ let(:release) { create(:release) } before do - create(:module_release, release_id: release.id, module_position: 1, name: 'alpha') - create(:module_release, release_id: release.id, module_position: 2, name: 'bravo') - create(:module_release, release_id: release.id, module_position: 3, name: 'charlie') + create :module_release, release_id: release.id, module_position: 1, name: 'alpha' + create :module_release, release_id: release.id, module_position: 2, name: 'bravo' + create :module_release, release_id: release.id, module_position: 3, name: 'charlie' # user#1 - complete_module(alpha, 1.minute) - complete_module(bravo, 1.minute) - complete_module(charlie, 1.minute) + complete_module alpha, 1.minute + complete_module bravo, 1.minute + complete_module charlie, 1.minute # user#2 user#3 with notes - create(:note, user: user_2) - create(:note, user: user_3) + create :note, user: user_2 + create :note, user: user_3 # user#4 complete registration notification - create(:user, :confirmed, confirmed_at: 4.weeks.ago) + create :user, :confirmed, confirmed_at: 4.weeks.ago # user#5 start training notification - create(:user, :registered, confirmed_at: 4.weeks.ago) + create :user, :registered, confirmed_at: 4.weeks.ago + # user#6 + create :gov_one_user end it_behaves_like 'a data export model' diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 26f221ef7..4b379e5e5 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -67,6 +67,9 @@ # enable #travel_to config.include ActiveSupport::Testing::TimeHelpers - # enable ShowMeTheCookies + # enable cookie banner config.include ShowMeTheCookies, type: :system + + # enable OIDC session + config.include Devise::Test::IntegrationHelpers, type: :system if Rails.application.gov_one_login? end diff --git a/spec/requests/authentication_spec.rb b/spec/requests/authentication_spec.rb index 466b3af5c..8d44687c1 100644 --- a/spec/requests/authentication_spec.rb +++ b/spec/requests/authentication_spec.rb @@ -1,115 +1,103 @@ require 'rails_helper' -# TODO: refactor so let=user is the variable and the before block is defined once -# RSpec.describe 'Authentication', type: :request do - describe 'viewing authenticate_user! controller action' do - let(:action_path) { edit_registration_terms_and_conditions_path } - - context 'with User not signed in' do - it 'redirects to sign in page' do - get action_path - expect(response).to redirect_to(new_user_session_path) + describe '#authenticate_user!' do + describe 'a guest' do + before do + get edit_registration_terms_and_conditions_path end - it 'displays message to sign in' do - get action_path + it { expect(response).to redirect_to new_user_session_path } + + it 'must authenticate' do follow_redirect! - expect(response.body).to include('You need to sign in') + expect(response.body).to include 'You need to sign in' end end - context 'with unconfirmed user' do - before { sign_in create(:user) } - - it 'redirects to sign in page' do - get action_path - expect(response).to redirect_to(new_user_session_path) + describe 'a user' do + before do + sign_in user + get edit_registration_terms_and_conditions_path end - it 'displays message that confirmation link email sent' do - get action_path - follow_redirect! - expect(response.body).to include('You have to confirm your email address') - end - end + context 'when unconfirmed' do + let(:user) { create :user } - context 'with partially registered user' do - before { sign_in create(:user, :confirmed) } + it { expect(response).to redirect_to new_user_session_path } - it 'renders page' do - get action_path - expect(response).to have_http_status(:success) + it 'email address must be confirmed' do + follow_redirect! + expect(response.body).to include 'You have to confirm your email address' + end end - end - context 'with registered User' do - before { sign_in create(:user, :registered) } + context 'when partially registered' do + let(:user) { create :user, :confirmed } - it 'renders page' do - get action_path - expect(response).to have_http_status(:success) + it { expect(response).to have_http_status :success } end - end - end - - describe 'viewing :authenticate_registered_user! controller action' do - let(:action_path) { my_modules_path } - context 'with User not signed in' do - it 'redirects to sign in page' do - get action_path - expect(response).to redirect_to(new_user_session_path) - end + context 'when registered' do + let(:user) { create :user, :registered } - it 'displays message to sign in' do - get action_path - follow_redirect! - expect(response.body).to include('You need to sign in') + it { expect(response).to have_http_status :success } end end + end - context 'with unconfirmed user' do - before { sign_in create(:user) } - - it 'redirects to sign in page' do - get action_path - expect(response).to redirect_to(new_user_session_path) + describe '#authenticate_registered_user!' do + describe 'a guest' do + before do + get my_modules_path end - it 'displays message that confirmation link email sent' do - get action_path + it { expect(response).to redirect_to new_user_session_path } + + it 'must authenticate' do follow_redirect! - expect(response.body).to include('You have to confirm your email address') + expect(response.body).to include 'You need to sign in' end end - context 'with partially registered User' do + describe 'a user' do before do - allow(Rails.application).to receive(:gov_one_login?).and_return(true) - sign_in create(:user, :confirmed) + sign_in user + get my_modules_path end - it 'redirects to finish registration' do - get action_path - expect(response).to redirect_to(edit_registration_terms_and_conditions_path) - end + context 'when unconfirmed' do + let(:user) { create :user } - it 'displays message to complete registration' do - get action_path - follow_redirect! - expect(response.body).to include('Please complete registration') + it { expect(response).to redirect_to new_user_session_path } + + it 'email address must be confirmed' do + follow_redirect! + expect(response.body).to include 'You have to confirm your email address' + end end - end - context 'with registered User' do - before do - sign_in create(:user, :registered) + context 'when partially registered' do + let(:user) { create :user, :confirmed } + + it do + if Rails.application.gov_one_login? + expect(response).to redirect_to edit_registration_terms_and_conditions_path + else + expect(response).to redirect_to edit_registration_name_path + end + end + + it 'registration must be completed' do + follow_redirect! + expect(response.body).to include 'Please complete registration' + end end - it 'renders page' do - get action_path - expect(response).to have_http_status(:success) + context 'when registered' do + let(:user) { create :user, :registered } + + it { expect(response).to have_http_status :success } end end end diff --git a/spec/support/shared/with_user.rb b/spec/support/shared/with_user.rb index b5a00e60e..de931312f 100644 --- a/spec/support/shared/with_user.rb +++ b/spec/support/shared/with_user.rb @@ -1,10 +1,20 @@ RSpec.shared_context 'with user' do - let(:user) { create(:user, :registered) } + if Rails.application.gov_one_login? + let(:user) { create(:gov_one_user) } - before do - visit '/users/sign-in' - fill_in 'Email address', with: user.email - fill_in 'Password', with: user.password - click_button 'Sign in' + before do + sign_in user + visit '/users/sign-in' + end + + else + let(:user) { create(:user, :registered) } + + before do + visit '/users/sign-in' + fill_in 'Email address', with: user.email + fill_in 'Password', with: user.password + click_button 'Sign in' + end end end diff --git a/spec/system/account_page_spec.rb b/spec/system/account_page_spec.rb index ac3a0547d..7b769584d 100644 --- a/spec/system/account_page_spec.rb +++ b/spec/system/account_page_spec.rb @@ -1,36 +1,26 @@ require 'rails_helper' RSpec.describe 'Account page', type: :system do - subject(:user) { create :user, :registered } - include_context 'with user' - context 'when gov_one login is disabled' do - before do - allow(Rails.application).to receive(:gov_one_login?).and_return(false) - visit '/my-account' - end - - it 'displays account details and password options' do - expect(page).to have_text('Manage your account') - expect(page).to have_css('a', text: 'Change name') - expect(page).to have_css('a', text: 'Change password') - expect(page).to have_css('a', text: 'Change setting details') - expect(page).to have_css('a', text: 'Change email preferences') - expect(page).to have_text('Closing your account') - end + before do + visit '/my-account' end - context 'when gov_one login is enabled' do - before do - allow(Rails.application).to receive(:gov_one_login?).and_return(true) - visit '/my-account' - end + it 'displays account details' do + expect(page).to have_text 'Manage your account' + expect(page).to have_link 'Change name' - it 'password options are not listed and helper text is displayed' do - expect(page).to have_text('Manage your account') - expect(page).not_to have_css('a', text: 'Change password') - expect(page).to have_content('Changing your name on this account will not affect your Gov.UK One Login') + if Rails.application.gov_one_login? + expect(page).not_to have_link 'Change password' + expect(page).to have_content 'Changing your name on this account will not affect your Gov.UK One Login' + else + expect(page).to have_link 'Change password' end + + expect(page).to have_link 'Change setting details' + expect(page).to have_link 'Change email preferences' + + expect(page).to have_text 'Closing your account' end end diff --git a/spec/system/confirmed_user/completing_registration_spec.rb b/spec/system/confirmed_user/completing_registration_spec.rb index 105e843c9..cc97ba85d 100644 --- a/spec/system/confirmed_user/completing_registration_spec.rb +++ b/spec/system/confirmed_user/completing_registration_spec.rb @@ -1,23 +1,22 @@ require 'rails_helper' -RSpec.describe 'Confirmed users completing registration' do - before do - allow(Rails.application).to receive(:gov_one_login?).and_return(true) - end - +RSpec.describe 'Confirmed users' do include_context 'with user' + let(:user) { create :user, :confirmed } - it 'requires name and a setting type and email preferences and a complete' do - expect(page).to have_text('Terms and conditions') - click_button 'Continue' - expect(page).to have_text('There is a problem') - .and have_text('You must accept the terms and conditions and privacy policy to create an account.') + it 'complete registration' do + if Rails.application.gov_one_login? + expect(page).to have_text('Terms and conditions') + click_button 'Continue' + expect(page).to have_text('There is a problem') + .and have_text('You must accept the terms and conditions and privacy policy to create an account.') - expect(page).to have_text('Agree to our terms and conditions') + expect(page).to have_text('Agree to our terms and conditions') - check 'I confirm that I accept the terms and conditions and privacy policy.' - click_button 'Continue' + check 'I confirm that I accept the terms and conditions and privacy policy.' + click_button 'Continue' + end expect(page).to have_text('About you') click_button 'Continue' diff --git a/spec/system/forgotten_password_spec.rb b/spec/system/forgotten_password_spec.rb index d16ed5974..eca71c72c 100644 --- a/spec/system/forgotten_password_spec.rb +++ b/spec/system/forgotten_password_spec.rb @@ -5,6 +5,10 @@ let(:token) { user.send_reset_password_instructions } let(:password) { 'ABCDE123xyh!@' } + before do + skip if Rails.application.gov_one_login? + end + context 'when choosing a new password' do before do visit edit_user_password_path + "?reset_password_token=#{token}" diff --git a/spec/system/front_page_spec.rb b/spec/system/front_page_spec.rb index b72275cc3..acd6b931f 100644 --- a/spec/system/front_page_spec.rb +++ b/spec/system/front_page_spec.rb @@ -6,17 +6,30 @@ it 'logged in content' do visit '/' + expect(page).to have_text 'Learn more' - expect(page).not_to have_text 'Learn more and enrol' - expect(page).not_to have_text 'Sign in to continue learning' + + if Rails.application.gov_one_login? + expect(page).not_to have_text 'Learn more about this training' + expect(page).not_to have_text 'Start your training now' + else + expect(page).not_to have_text 'Learn more and enrol' + expect(page).not_to have_text 'Sign in to continue learning' + end end end context 'with an unauthenticated visitor' do it 'log in content' do visit '/' - expect(page).to have_text('Learn more and enrol') - .and have_text('Sign in to continue learning') + + if Rails.application.gov_one_login? + expect(page).to have_text 'Learn more about this training' + expect(page).to have_text 'Start your training now' + else + expect(page).to have_text 'Learn more and enrol' + expect(page).to have_text 'Sign in to continue learning' + end end end end diff --git a/spec/system/gov_one_info_spec.rb b/spec/system/gov_one_info_spec.rb deleted file mode 100644 index 4107f9c25..000000000 --- a/spec/system/gov_one_info_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'Gov One Info' do - before do - allow(Rails.application).to receive(:gov_one_login?).and_return(false) - visit '/gov-one/info' - end - - context 'with an unauthenticated visitor' do - it 'displays the correct content' do - expect(page).to have_css('h1', text: 'How to access this training course') - expect(page).to have_css('p', text: 'This service uses GOV.UK One Login which is managed by the Government Digital Service.') - expect(page).to have_css('p', text: 'You will be asked to sign in to your account, or create a One Login account, in this service') - expect(page).to have_css('a', text: 'Continue to GOV.UK One Login') - end - end - - context 'with an authenticated user' do - include_context 'with user' - - it 'redirects to the my modules page' do - expect(page).to have_current_path('/my-modules') - end - end -end diff --git a/spec/system/gov_one_spec.rb b/spec/system/gov_one_spec.rb new file mode 100644 index 000000000..86c9a9580 --- /dev/null +++ b/spec/system/gov_one_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +RSpec.describe 'Gov One' do + before do + skip unless Rails.application.gov_one_login? + end + + context 'with an unauthenticated visitor' do + before do + visit '/users/sign-in' + end + + it 'displays the correct content' do + expect(page).to have_text 'How to access this training course' + expect(page).to have_text 'This service uses GOV.UK One Login which is managed by the Government Digital Service.' + expect(page).to have_text 'You will be asked to sign in to your account, or create a One Login account, in this service' + expect(page).to have_text 'Continue to GOV.UK One Login' + end + end + + context 'with an authenticated user' do + include_context 'with user' + + before do + visit '/users/sign-in' + end + + it 'redirects to the my modules page' do + expect(page).to have_current_path '/my-modules' + end + end +end diff --git a/spec/system/sign_in_spec.rb b/spec/system/sign_in_spec.rb index 790d6c79e..3e0039c74 100644 --- a/spec/system/sign_in_spec.rb +++ b/spec/system/sign_in_spec.rb @@ -5,7 +5,8 @@ let(:password) { Rails.configuration.user_password } before do - allow(Rails.application).to receive(:gov_one_login?).and_return(true) + skip if Rails.application.gov_one_login? + visit '/users/sign-in' fill_in 'Email address', with: email_address fill_in 'Password', with: password @@ -46,7 +47,7 @@ context 'and enters valid credentials' do it 'signs in successfully' do - expect(page).to have_text('Agree to our terms and conditions') # extra registration + expect(page).to have_text 'About you' # extra registration end end diff --git a/spec/system/whats_new_page_spec.rb b/spec/system/whats_new_page_spec.rb index 7fc194638..4c9ecdc1d 100644 --- a/spec/system/whats_new_page_spec.rb +++ b/spec/system/whats_new_page_spec.rb @@ -23,10 +23,15 @@ before do click_on 'sign-out-desktop' - visit '/users/sign-in' - fill_in 'Email address', with: user.email - fill_in 'Password', with: user.password - click_button 'Sign in' + if Rails.application.gov_one_login? + sign_in user + visit '/users/sign-in' + else + visit '/users/sign-in' + fill_in 'Email address', with: user.email + fill_in 'Password', with: user.password + click_button 'Sign in' + end end it 'does not appear' do diff --git a/ui/pages/sign_in.rb b/ui/pages/sign_in.rb index d960d6fcc..dd7b46a0c 100644 --- a/ui/pages/sign_in.rb +++ b/ui/pages/sign_in.rb @@ -16,7 +16,7 @@ def with_email_and_password(email = nil, password = nil) wait_until_header_visible email ||= 'completed@example.com' - password ||= Rails.configuration.user_password + password ||= ENV.fetch('USER_PASSWORD', 'Str0ngPa$$w0rd12') email_field.set(email) password_field.set(password) diff --git a/uml/deployment.puml b/uml/deployment.puml index ec635d6b5..667248d33 100644 --- a/uml/deployment.puml +++ b/uml/deployment.puml @@ -63,15 +63,15 @@ rectangle "Early Years Recovery Deployment" { } rectangle "ey-recovery-staging" as preprod <> { - artifact "ey-recovery-staging.london.cloudapps.digital" as rc1 <> - artifact "ey-recovery-dev.london.cloudapps.digital" as main <> + artifact "staging.child-development-training.education.gov.uk" as rc1 <> + artifact "eyrecovery-dev.azurewebsites.net" as main <> } ' artifact or node? or device? rectangle "ey-recovery-content" as feature <> { - artifact "ey-recovery-pr-123.london.cloudapps.digital" as 123 <> - artifact "ey-recovery-pr-124.london.cloudapps.digital" as 124 <> - artifact "ey-recovery-pr-125.london.cloudapps.digital" as 125 <> + artifact "eyrecovery-review-pr-123.azurewebsites.net" as 123 <> + artifact "eyrecovery-review-pr-124.azurewebsites.net" as 124 <> + artifact "eyrecovery-review-pr-125.azurewebsites.net" as 125 <> } } }