If you are unsure whether the course(s) you teach is eligible, please email:
%{email}
Select all that apply
+ errors: + inclusion: Select all the courses you teach otherwise select you do not teach any of these courses + building_construction_courses: + <<: *courses + question: Which building and construction courses do you teach? + options: + esfa_buildingconstruction: ESFA-funded qualifications at level 3 and below in the %{link} sector subject area + tlevel_building: T Level in building services engineering for construction + tlevel_onsiteconstruction: T Level in onsite construction + tlevel_design_surveying: T Level in design, surveying and planning for construction + level2_3_apprenticeship: Level 2 or level 3 apprenticeships in the %{link} + none: I do not teach any of these courses + chemistry_courses: + <<: *courses + question: Which chemistry courses do you teach? + options: + alevel_chemistry: A or AS level chemistry + gcse_chemistry: GCSE chemistry + ib_certificate_chemistry: International baccalaureate middle years programme or certificate in chemistry + none: I do not teach any of these courses + computing_courses: + <<: *courses + question: Which computing courses do you teach? + options: + esfa_digitalpractitioners: ESFA-funded qualifications at level 3 and below in the %{link} sector subject area + esfa_digitalusers: ESFA-funded qualifications at level 3 and below in the %{link} sector subject area + digitalskills_quals: Digital functional skills qualifications and essential digital skills qualifications + tlevel_digitalsupport: T Level in digital support services + tlevel_digitalbusiness: T Level in digital business services + tlevel_digitalproduction: T Level in digital production, design and development + ib_certificate_compsci: International baccalaureate certificate in computer science + level2_3_apprenticeship: Level 2 or level 3 apprenticeships in the %{link} + none: I do not teach any of these courses + early_years_courses: + <<: *courses + question: Which early years courses do you teach? + options: + eylevel2: Early years practitioner (level 2) apprenticeship + eylevel3: Early years educator (level 3) apprenticeship + eytlevel: T Level in education and early years (early years educator) + coursetoeyq: A course that leads to an %{link} which enables providers to count the recipient in staff:child ratios + none: I do not teach any of these courses + engineering_manufacturing_courses: + <<: *courses + question: Which engineering and manufacturing courses do you teach? + options: + esfa_engineering: ESFA-funded qualifications at level 3 and below in the %{link} sector subject area + esfa_manufacturing: ESFA-funded qualifications at level 3 and below in the %{link} sector subject area + esfa_transportation: ESFA-funded qualifications at level 3 and below in the %{link} sector subject area + tlevel_design: T Level in design and development for engineering and manufacturing + tlevel_maintenance: T Level in maintenance, installation and repair for engineering and manufacturing + tlevel_engineering: T Level in engineering, manufacturing, processing and control + level2_3_apprenticeship: Level 2 or level 3 apprenticeships in the %{link} + none: I do not teach any of these courses + maths_courses: + <<: *courses + question: Which maths courses do you teach? + options: + esfa: ESFA-funded qualifications at level 3 and below in the %{link} sector subject area + gcse_maths: Maths GCSE, functional skills qualifications and %{link} approved for teaching to 16 to 19-year-olds who meet the condition of funding + none: I do not teach any of these courses + physics_courses: + <<: *courses + question: Which physics courses do you teach? + options: + alevel_physics: A or AS level physics + gcse_physics: GCSE physics + ib_certificate_physics: International baccalaureate middle years programme or certificate in physics + none: I do not teach any of these courses teaching_qualification: question: Do you have a teaching qualification? hint: Your response will be noted for future claims. If you don’t have a teaching qualification yet, make sure that you enrol on one or complete one in the next 12 months. @@ -900,10 +991,26 @@ en: question: Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)? errors: inclusion: Select yes if at least half your timetabled teaching hours are spent teaching 16-19-year-olds, including those up to 25 with an Education, Health and Care Plan + eligible: + heading: You’re eligible for a financial incentive payment + gender: + questions: + payroll_gender: "How is your gender recorded on your employer’s payroll system?" + errors: + select_gender: "Select the gender recorded on your employer’s payroll system or select whether you do not know" + hours_teaching_eligible_subjects: + question: Do you spend at least half of your timetabled teaching hours teaching these eligible courses? + errors: + inclusion: Select yes if you spend at least half of your timetabled teaching hours teaching these eligible courses check_your_answers: part_one: primary_heading: Check your answers confirmation_notice: By selecting continue you are confirming that, to the best of your knowledge, the details you are providing are correct. + heading_send_application: Now send your application + statement: + By submitting this you are confirming that, to the best of your knowledge, the details you are providing are + correct. + btn_text: Accept and send activerecord: errors: models: diff --git a/config/routes.rb b/config/routes.rb index 4da66505fb..5e6f52161c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -119,6 +119,7 @@ def matches?(request) resources :journey_configurations, only: [:index, :edit, :update] resources :levelling_up_premium_payments_awards, only: [:index, :create] + resource :eligible_fe_providers, only: [:create, :show], path: "eligible-further-education-providers" get "refresh-session", to: "sessions#refresh", as: :refresh_session diff --git a/db/data/20240709134609_add_irp_journey_configuration.rb b/db/data/20240709134609_add_irp_journey_configuration.rb new file mode 100644 index 0000000000..4de8023067 --- /dev/null +++ b/db/data/20240709134609_add_irp_journey_configuration.rb @@ -0,0 +1,6 @@ +# Run me with `rails runner db/data/20240709134609_add_irp_journey_configuration.rb` + +Journeys::Configuration.create!( + routing_name: Journeys::GetATeacherRelocationPayment::ROUTING_NAME, + current_academic_year: AcademicYear.current +) diff --git a/db/migrate/20240709110147_add_award_amount_to_international_relocation_payments_eligibilities.rb b/db/migrate/20240709110147_add_award_amount_to_international_relocation_payments_eligibilities.rb new file mode 100644 index 0000000000..8f318d409b --- /dev/null +++ b/db/migrate/20240709110147_add_award_amount_to_international_relocation_payments_eligibilities.rb @@ -0,0 +1,5 @@ +class AddAwardAmountToInternationalRelocationPaymentsEligibilities < ActiveRecord::Migration[7.0] + def change + add_column :international_relocation_payments_eligibilities, :award_amount, :decimal, precision: 7, scale: 2 + end +end diff --git a/db/migrate/20240710080536_create_eligible_fe_providers.rb b/db/migrate/20240710080536_create_eligible_fe_providers.rb new file mode 100644 index 0000000000..85a94026a4 --- /dev/null +++ b/db/migrate/20240710080536_create_eligible_fe_providers.rb @@ -0,0 +1,14 @@ +class CreateEligibleFeProviders < ActiveRecord::Migration[7.0] + def change + create_table :eligible_fe_providers, id: :uuid do |t| + t.integer :ukprn, null: false + t.text :academic_year, limit: 9, null: false + t.decimal :max_award_amount, precision: 7, scale: 2 + t.decimal :lower_award_amount, precision: 7, scale: 2 + + t.timestamps + end + + add_index :eligible_fe_providers, [:academic_year, :ukprn] + end +end diff --git a/db/schema.rb b/db/schema.rb index 96d92f0c84..dd8e02e8db 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: 2024_07_02_105328) do +ActiveRecord::Schema[7.0].define(version: 2024_07_10_080536) do # These are extensions that must be enabled in order to support this database enable_extension "pg_trgm" enable_extension "pgcrypto" @@ -175,6 +175,16 @@ t.index ["teacher_reference_number"], name: "index_ecp_eligibility_trn" end + create_table "eligible_fe_providers", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.integer "ukprn", null: false + t.text "academic_year", null: false + t.decimal "max_award_amount", precision: 7, scale: 2 + t.decimal "lower_award_amount", precision: 7, scale: 2 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["academic_year", "ukprn"], name: "index_eligible_fe_providers_on_academic_year_and_ukprn" + end + create_table "file_uploads", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "uploaded_by_id" t.text "body" diff --git a/db/seeds.rb b/db/seeds.rb index ad90eac8c1..09580403c4 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -17,6 +17,10 @@ Rake::Task["db:fixtures:load"].invoke end +if ENV["ENVIRONMENT_NAME"].start_with?("review") + SchoolDataImporterJob.perform_later if School.count < 100 +end + if Rails.env.development? require "./lib/factory_helpers" diff --git a/docs/connecting-to-azure.md b/docs/connecting-to-azure.md index 587db9ce93..b104dc4371 100644 --- a/docs/connecting-to-azure.md +++ b/docs/connecting-to-azure.md @@ -7,12 +7,6 @@ Kubernetes infrastructure in Azure. Follow these instructions to [run a Rake task](#run-a-rake-task) or [open a Rails console](#open-a-rails-console). -> [!NOTE] These instructions are for connecting to the `test` Kubernetes cluster -> which powers our **Test and PR review environments**. -> -> We don't have a production environment yet – but when we do, we will update -> these instructions accordingly. - ## 1. Authenticate to the Kubernetes cluster You'll need to configure your command line console so it can connect to the @@ -49,19 +43,21 @@ but you may need to re-authenticate every once in a while. brew install Azure/kubelogin/kubelogin ``` -4. Then run: +4. Then run one of these commands: ```shell - make test-aks get-cluster-credentials + make test-aks get-cluster-credentials # for test and review apps + make production-aks get-cluster-credentials CONFIRM_PRODUCTION=yes # for production ``` 5. Assuming everything worked correctly, you should now be able to access the Kubernetes cluster using the `kubectl` command. - > You can test you have access by running this command: + > You can test you have access by running one of these commands: > > ```shell - > kubectl -n srtl-development get deployments + > kubectl -n srtl-test get deployments # for test and review apps + > kubectl -n srtl-production get deployments # for production > ``` > > You should see a list of Kubernetes deployments. @@ -107,25 +103,55 @@ For a list of all test deployments, run: kubectl -n srtl-test get deployments ``` +### Production app + +Our production app is under the `srtl-production` namespace within the +`production` cluster. + +For a list of all test deployments, run: + +```shell +kubectl -n srtl-production get deployments +``` + +> Accessing production deployments requires a +> [PIM (Privileged Identity Management) request](docs/privileged-identity-management-requests.md). + ## 3. Connect to a running container -The following commands will connect to a review app. To connect to the test app, -replace `srtl-development` with `srtl-test` then target the test deployment. +To run the following commands, replace `NAMESPACE` with one of: + +```shell +srtl-production # for production +srtl-test # for test +srtl-development # for review apps +``` + +Replace `DEPLOYMENT_NAME` with the deployment you want to target e.g. +`claim-additional-payments-for-teaching-test-worker`. ### Open a Rails console Open an interactive Rails console using this command: ```shell -kubectl -n srtl-development exec -it deployment/claim-additional-payments-for-teaching-review-123-worker -- rails console +kubectl -n ${NAMESPACE} exec -it deployment/${DEPLOYMENT_NAME} -- rails console ``` +Alternatively, you can run the following script: + +```shell +bin/azure-console ${ENVIRONMENT} +``` + +Where environment is one of `production`, `test` or `review-PR_NUMBER`. + ### Open a shell console Open an interactive Linux shell using this command: ```shell -kubectl -n srtl-development exec -it deployment/claim-additional-payments-for-teaching-review-123-worker -- sh +kubectl -n ${NAMESPACE} exec -it deployment/${DEPLOYMENT_NAME} -- sh ``` ### Run a Rake task @@ -133,13 +159,13 @@ kubectl -n srtl-development exec -it deployment/claim-additional-payments-for-te Run Rake tasks using this command: ```shell -kubectl -n srtl-development exec -it deployment/claim-additional-payments-for-teaching-review-123-worker -- rake [TASK_TO_RUN] +kubectl -n ${NAMESPACE} exec -it deployment/${DEPLOYMENT_NAME} -- rake ${TASK_TO_RUN} ``` Or list all available Rake tasks with: ```shell -kubectl -n srtl-development exec -it deployment/claim-additional-payments-for-teaching-review-123-worker -- rake -T +kubectl -n ${NAMESPACE} exec -it deployment/${DEPLOYMENT_NAME} -- rake -T ``` ## Useful links diff --git a/docs/first-line-support-developer-runbook.md b/docs/first-line-support-developer-runbook.md index 8c53021d31..f240cab053 100644 --- a/docs/first-line-support-developer-runbook.md +++ b/docs/first-line-support-developer-runbook.md @@ -20,13 +20,13 @@ If you want to do one of these tasks and you don’t have what you need, see the 1. Log in to https://portal.azure.com with your `@digital.education.gov.uk` email address. - 2. Search for `s118-teacherpaymentsservice-production`. + 2. Search for `s189-teacher-services-cloud-production`. 3. Click “My permissions”. 4. If you see something like - > You are a member of the group 's118-teacherpaymentservice-Delivery Team - > USR (null)' which has been assigned the role 'Reader' (type BuiltInRole) - > and has access to subscription s118-teacherpaymentsservice-production + > You are a member of the group 's189 SRTL delivery team ()' which has been + > assigned the role 'Reader' (type BuiltInRole) and has access to + > s189-teacher-services-cloud-production then you have what you need. @@ -45,11 +45,10 @@ If you want to do one of these tasks and you don’t have what you need, see the 2. Fix the bug. 3. Describe the fix in [`CHANGELOG.md`](../CHANGELOG.md). -4. Open a pull request into `master`, and get it reviewed. -5. Merge the pull request. -6. If possible, verify that the fix works on the - [development environment](../README.md#development). -7. Do a release. See [`release-process.md`](release-process.md). +4. Open a pull request into `master`. +5. Deploy a review app by adding the 'Deploy' tag to your PR and get it + reviewed. +6. Merge the pull request. ### I want to pull some data from the production database @@ -97,13 +96,13 @@ there is a claim window open, which is around September – March. 1. Log in to https://portal.azure.com with your `@digital.education.gov.uk` email address. - 2. Search for `s118-teacherpaymentsservice-production`. + 2. Search for `s189-teacher-services-cloud-production`. 3. Click “My permissions”. 4. If you see something like - > You are a member of the group 's118-teacherpaymentservice-Delivery Team - > USR (null)' which has been assigned the role 'Reader' (type BuiltInRole) - > and has access to subscription s118-teacherpaymentsservice-production` + > You are a member of the group 's189 SRTL delivery team ()' which has been + > assigned the role 'Reader' (type BuiltInRole) and has access to + > s189-teacher-services-cloud-production then you have what you need. @@ -130,6 +129,7 @@ who raised the support ticket. 4. Identify the latest `PayrollRun` object (double check that the dates are as expected), set `downloaded_at` and `downloaded_by_id` to `nil` and save the object: + ```ruby payroll = PayrollRun.last payroll.downloaded_at = nil @@ -149,8 +149,17 @@ who raised the support ticket. permissions required to access production resources. See [`privileged-identity-management-requests.md`](privileged-identity-management-requests.md). 2. Ask another developer to approve the PIM request. -3. Search for `s118p01-app-worker-aci` within the Azure portal. -4. Click "Restart" -Alternatively, instead of doing it via the web interface, you can run -`az container restart --name s118p01-app-worker-aci --resource-group s118p01-app`. +Then run: + +```bash +kubectl -n srtl-production rollout restart deployment claim-additional-payments-for-teaching-production-worker +``` + +If you need more detailed information about the rollout status, you can describe +the deployment: + +```bash +kubectl -n srtl-test describe deployment +claim-additional-payments-for-teaching-production-worker +``` diff --git a/docs/logging.md b/docs/logging.md index e3c5b58331..dc4d8ceee9 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -1,33 +1,24 @@ # Logging -# Application-level logging in logit.io +The application logs to STDOUT in JSON format using [Semantic Logger](https://github.com/reidmorrison/rails_semantic_logger). -The application sends all Rails logs to [logit.io](https://logit.io/). This -gives us a hosted ELK stack. ELK stands for Elasticsearch, Logstash, Kibana. -It’s a open-source stack frequently used for log aggregation and visualisation. +# AKS/container logs -Kibana is the tool that you’ll use to explore the logs. +Logs are available via the standard Azure/AKS tooling. -To view the production logs in Kibana: - -1. Log in to logit.io. -2. Click on the “DfE Claim” account. -3. Find the “Production” stack and click “Launch Kibana”. - -## Missing logs in logit.io +The `az` Azure command line tool and `kubectl` have some useful commands for interacting with +logs. -At the time of writing (2020-03-26), we have a problem where some log messages -seem to be missing from logit.io. We are trying to fix this in -[this Trello card](https://trello.com/c/JN44De4l/1330-understand-why-expected-logs-arent-in-logit). +```sh +kubectl -n srtl-test get pods +kubectl -n srtl-test logs claim-additional-payments-for-teaching-test-web-123456 +``` -# Azure logs +You will need PIM elevated privileges to view logs for production. -We should aim for logit.io to be the single place developers need to look to -find logs. However, it’s useful to know about some of the logs that are -available from Azure. +# Logit.io -The `az` Azure command line tool has some useful commands for interacting with -logs. +Logs are shipped to [Logit.io](https://logit.io/) automatically by AKS. You will need an account to access this service. ## App Service @@ -38,27 +29,6 @@ There is some about the logs available for an App Service. Here we go over some of the ways to extract these logs. -### Docker logs - -To view Docker logs in production, you will need to elevate your privileges -using a [PIM request](privileged-identity-management-requests.md). - -You can use the `az webapp log` commands to tail and download the logs. - -Here’s an example command that will live tail the container logs and Docker host -logs, for `production`: - -``` -az webapp log tail --name s118p01-app-as --resource-group s118p01-app --subscription s118-teacherpaymentsservice-production -``` - -Or, you can download them with a browser: - -- production Docker logs from the instances currently in the App Service: - https://s118p01-app-as.scm.azurewebsites.net/api/logs/docker -- production Docker logs from current and previous instances: - https://s118d01-app-as.scm.azurewebsites.net/api/vfs/LogFiles/ - ### Application Insights The Rails application uses the `application_insights` gem, which sends @@ -72,22 +42,3 @@ To view these logs: 3. Click “Logs” under “Monitoring” on the left. 4. You can now execute queries. For example, to view all requests, type `requests` in the query field, and click Run. - -## Container Instances - -The container instances perform other tasks like running a background job -worker. The logs are lost after a deploy. You don’t need PIM-elevated privileges -to view the container instance logs. - -To view the logs for a container instance, we can use `az container logs`: - -``` -az container logs --name s118p01-app-worker-aci --resource-group s118p01-app --subscription s118-teacherpaymentsservice-production -``` - -Or, you can view them in a browser: - -1. Visit `https://portal.azure.com`. -2. Search for `s118p01-app-worker-aci`. -3. Click “Containers” on the left. -4. Click “Logs”. diff --git a/docs/school-check-data.md b/docs/school-check-data.md index 5517e23d42..d6bca1b552 100644 --- a/docs/school-check-data.md +++ b/docs/school-check-data.md @@ -20,47 +20,41 @@ which need this email sending is a developer task, documented below. 3. Have a second developer join you to observe, and connect to the production console using - ``` + ```shell bin/azure-console production ``` -4. Activate the Rails console in sandbox mode with - - ``` - bin/rails console --sandbox - ``` +4. Create a new instance of `Claim::SchoolCheckEmailDataExport` with -5. Create a new instance of `Claim::SchoolCheckEmailDataExport` with - - ``` + ```shell exporter = Claim::SchoolCheckEmailDataExport.new("A1B2C345,D6E7F890,G1H2I345...") ``` substituting the claim references for the string you copied from the spreadsheet in step 2. -6. Generate the CSV data of claims needing checking by running +5. Generate the CSV data of claims needing checking by running - ``` + ```shell puts exporter.csv_string ``` You may need to press the space bar to make your terminal render to the end of the output. -7. Copy the output and save as a CSV file with the name +6. Copy the output and save as a CSV file with the name `school-check-batch_ddmmyyyy.csv` -8. Securely transfer the file to the relevant service operator to follow the +7. Securely transfer the file to the relevant service operator to follow the rest of the school check process. The best way we’ve found to do this is to create a [new Google Sheets document](https://sheets.new/), private to yourself and shared only with the service operator. -9. From the CSV file, copy the claim references (and no other details) and +8. From the CSV file, copy the claim references (and no other details) and append them to the first worksheet in the [School Check Email - Sent Claims spreadsheet](https://docs.google.com/spreadsheets/d/1mxMND-SqOjK7yyYp0EaEJOOCUYFkqLJ1ZIwPLuSVKfM/edit#gid=1926551388) so that they will be excluded the next time the process is run. Trim any remaining empty cells from the bottom of the column -10. After the service operator has sent the school check emails, delete the - personal data from your machine and Google Sheets. +9. After the service operator has sent the school check emails, delete the + personal data from your machine and Google Sheets. diff --git a/filebeat.yml b/filebeat.yml deleted file mode 100644 index 376aaaef85..0000000000 --- a/filebeat.yml +++ /dev/null @@ -1,104 +0,0 @@ -###################### Filebeat Configuration ######################### - -#=========================== Filebeat inputs ============================= - -filebeat.inputs: - -# Each - is an input. Most options can be set at the input level, so -# you can use different inputs for various configurations. -# Below are the input specific configurations. - -- type: log - enabled: true - paths: - - /app/log/*.json - encoding: utf-8 - ignore_older: 3h - json.keys_under_root: true - json.add_error_key: true - - -#============================= Filebeat modules =============================== - -filebeat.config.modules: - # Glob pattern for configuration loading - # path: ${path.config}/modules.d/*.yml - - # Set to true to enable config reloading - # reload.enabled: true - - # Period on which files under path should be checked for changes - # reload.period: 10s - #filebeat.modules: - # - module: system - - -#================================ General ===================================== - -# The name of the shipper that publishes the network data. It can be used to group -# all the transactions sent by a single shipper in the web interface. -#name: - -# The tags of the shipper are included in their own field with each -# transaction published. -#tags: ["service-X", "web-tier"] - -# Optional fields that you can specify to add additional information to the -# output. -fields: - env: "${ENVIRONMENT_NAME}" - -#================================ Outputs ===================================== - -# Configure what output to use when sending the data collected by the beat. - -#----------------------------- Logstash output -------------------------------- -output.logstash: - # The Logstash hosts - hosts: ["${LOGSTASH_HOST}:${LOGSTASH_PORT}"] - loadbalance: true - ssl.enabled: true - - # Optional SSL. By default is off. - # List of root certificates for HTTPS server verifications - #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client Certificate Key - #ssl.key: "/etc/pki/client/cert.key" - -#================================ Processors ===================================== - -# Configure processors to enhance or manipulate events generated by the beat. - -#processors: -# - add_host_metadata: ~ -# - add_cloud_metadata: ~ - -#================================ Logging ===================================== - -# Sets log level. The default log level is info. -# Available log levels are: error, warning, info, debug -#logging.level: debug - -# At debug level, you can selectively enable logging only for some components. -# To enable all selectors use ["*"]. Examples of other selectors are "beat", -# "publish", "service". -#logging.selectors: ["*"] - -#============================== Xpack Monitoring =============================== -# filebeat can export internal metrics to a central Elasticsearch monitoring -# cluster. This requires xpack monitoring to be enabled in Elasticsearch. The -# reporting is disabled by default. - -# Set to true to enable the monitoring reporter. -#xpack.monitoring.enabled: false - -# Uncomment to send the metrics to Elasticsearch. Most settings from the -# Elasticsearch output are accepted here as well. Any setting that is not set is -# automatically inherited from the Elasticsearch output configuration, so if you -# have the Elasticsearch output configured, you can simply uncomment the -# following line. -#xpack.monitoring.elasticsearch: diff --git a/lib/csv_importer/base.rb b/lib/csv_importer/base.rb index a891b6260d..dd0b593675 100644 --- a/lib/csv_importer/base.rb +++ b/lib/csv_importer/base.rb @@ -4,17 +4,18 @@ module CsvImporter class Base include CsvImporter::Config - attr_reader :errors, :rows + attr_reader :errors, :rows, :deleted_row_count def initialize(file) @errors = [] @rows = parse_csv_file(file) + @deleted_row_count = 0 check_headers if rows && with_headers? end def run - target_data_model.delete_all unless append_only + @deleted_row_count = delete_all_scope.delete_all unless append_only rows.each_slice(batch_size).with_index(1) do |batch_rows, i| Rails.logger.info "Processing #{target_data_model.to_s.titleize} batch #{i}" @@ -31,6 +32,10 @@ def run private + def delete_all_scope + target_data_model + end + def with_headers? parse_headers && mandatory_headers&.is_a?(Array) && mandatory_headers&.any? end diff --git a/package.json b/package.json index cfc18dfd8d..b404d76223 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,6 @@ "govuk-frontend": "^5.4.0" }, "devDependencies": { - "prettier": "^3.3.2" + "prettier": "^3.3.3" } } diff --git a/spec/factories/eligible_fe_providers.rb b/spec/factories/eligible_fe_providers.rb new file mode 100644 index 0000000000..32269cff59 --- /dev/null +++ b/spec/factories/eligible_fe_providers.rb @@ -0,0 +1,8 @@ +FactoryBot.define do + factory :eligible_fe_provider do + ukprn { rand(10_000_000..19_000_000) } + academic_year { AcademicYear.current } + max_award_amount { [4_000, 5_000, 6_000].sample } + lower_award_amount { [2_000, 2_500, 3_000].sample } + end +end diff --git a/spec/factories/journeys/get_a_teacher_relocation_payment/get_a_teacher_relocation_payment_answers.rb b/spec/factories/journeys/get_a_teacher_relocation_payment/get_a_teacher_relocation_payment_answers.rb index a52b2c0e0a..38411a027a 100644 --- a/spec/factories/journeys/get_a_teacher_relocation_payment/get_a_teacher_relocation_payment_answers.rb +++ b/spec/factories/journeys/get_a_teacher_relocation_payment/get_a_teacher_relocation_payment_answers.rb @@ -70,7 +70,7 @@ bank_account_number { rand(10000000..99999999) } end - trait :with_employment_details do + trait :with_headteacher_details do school_headteacher_name { "Seymour Skinner" } end @@ -78,6 +78,7 @@ with_teacher_application_route with_state_funded_secondary_school with_current_school + with_headteacher_details with_one_year_contract with_subject with_start_date diff --git a/spec/factories/policies/international_relocation_payments/eligibilities.rb b/spec/factories/policies/international_relocation_payments/eligibilities.rb index d1ba1ef6f4..01adc6b455 100644 --- a/spec/factories/policies/international_relocation_payments/eligibilities.rb +++ b/spec/factories/policies/international_relocation_payments/eligibilities.rb @@ -1,7 +1,9 @@ FactoryBot.define do factory :international_relocation_payments_eligibility, class: "Policies::InternationalRelocationPayments::Eligibility" do + award_amount { Policies::InternationalRelocationPayments.award_amount } + trait :eligible_home_office do - passport_number { "123456789" } + passport_number { Faker::Number.unique.number(digits: 9).to_s } nationality { "French" } end @@ -11,6 +13,7 @@ eligible_home_office eligible_school eligible_subject + eligible_start_date end trait :eligible_school do diff --git a/spec/features/admin/eligible_fe_providers_spec.rb b/spec/features/admin/eligible_fe_providers_spec.rb new file mode 100644 index 0000000000..c3b16789c3 --- /dev/null +++ b/spec/features/admin/eligible_fe_providers_spec.rb @@ -0,0 +1,40 @@ +require "rails_helper" + +RSpec.feature "Admin of eligible FE providers" do + scenario "manage eligible FE providers" do + when_further_education_payments_journey_configuration_exists + sign_in_as_service_operator + + click_link "Manage services" + click_link "Change Claim incentive payments for further education teachers" + + select "2024/2025", from: "eligible-fe-providers-upload-academic-year-field" + attach_file "eligible-fe-providers-upload-file-field", eligible_fe_providers_csv_file.path + click_button "Upload CSV" + + expect(page).to have_select "eligible-fe-providers-upload-academic-year-field", selected: "2024/2025" + + select "2024/2025", from: "eligible-fe-providers-download-academic-year-field" + click_button "Download CSV" + + downloaded_csv = page.body + + expect(downloaded_csv).to eql(eligible_fe_providers_csv_file.read) + end + + def eligible_fe_providers_csv_file + return @eligible_fe_providers_csv_file if @eligible_fe_providers_csv_file + + @eligible_fe_providers_csv_file = Tempfile.new + @eligible_fe_providers_csv_file.write EligibleFeProvidersImporter.mandatory_headers.join(",") + "\n" + + 3.times do + hash = attributes_for(:eligible_fe_provider) + @eligible_fe_providers_csv_file.write "#{hash[:ukprn]},#{hash[:max_award_amount].to_f},#{hash[:lower_award_amount].to_f}\n" + end + + @eligible_fe_providers_csv_file.rewind + + @eligible_fe_providers_csv_file + end +end diff --git a/spec/features/further_education_payments/college_not_found_spec.rb b/spec/features/further_education_payments/college_not_found_spec.rb index 89075664c2..51deb47bcc 100644 --- a/spec/features/further_education_payments/college_not_found_spec.rb +++ b/spec/features/further_education_payments/college_not_found_spec.rb @@ -38,8 +38,4 @@ expect(page).to have_content("Which FE provider are you employed by?") expect(page).to have_content("No results match that search term. Try again.") end - - def when_further_education_payments_journey_configuration_exists - create(:journey_configuration, :further_education_payments) - end end diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index 0d6cfda610..917a308c6c 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -18,6 +18,7 @@ expect(page).to have_content("Which FE provider are you employed by?") fill_in "Which FE provider are you employed by?", with: college.name within("#claim-provision-search-field__listbox") do + sleep(1) # seems to aid in success, as if click happens before event is bound find("li", text: college.name).click end click_button "Continue" @@ -42,10 +43,13 @@ check("Building and construction") click_button "Continue" - expect(page).to have_content("FE building and construction courses goes here") + expect(page).to have_content("Which building and construction courses do you teach?") + check "T Level in building services engineering for construction" click_button "Continue" - expect(page).to have_content("FE teaching courses goes here") + expect(page).to have_content("Do you spend at least half of your timetabled teaching hours teaching these eligible courses?") + expect(page).to have_content("T Level in building services engineering for construction") + choose("Yes") click_button "Continue" expect(page).to have_content("Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)?") @@ -69,15 +73,72 @@ expect(page).to have_content("Check your answers") click_button "Continue" - expect(page).to have_content("FE check your answers goes here") - click_button "Continue" - expect(page).to have_content("You’re eligible for a financial incentive payment") expect(page).to have_content("Apply now") - end + click_button "Apply now" + + expect(page).to have_content("FE ONE LOGIN PLACEHOLDER") + click_button "Continue" + + expect(page).to have_content("How we will use the information you provide in your application") + click_button "Continue" - def when_further_education_payments_journey_configuration_exists - create(:journey_configuration, :further_education_payments) + expect(page).to have_content("Personal details") + fill_in "First name", with: "John" + fill_in "Last name", with: "Doe" + fill_in "Day", with: "28" + fill_in "Month", with: "2" + fill_in "Year", with: "1988" + fill_in "National Insurance number", with: "PX321499A" + click_on "Continue" + + expect(page).to have_content("What is your home address?") + click_link("Enter your address manually") + + expect(page).to have_content("What is your address?") + fill_in "House number or name", with: "57" + fill_in "Building and street", with: "Walthamstow Drive" + fill_in "Town or city", with: "Derby" + fill_in "County", with: "City of Derby" + fill_in "Postcode", with: "DE22 4BS" + click_on "Continue" + + expect(page).to have_content("Email address") + fill_in "Email address", with: "johndoe@example.com" + click_on "Continue" + + expect(page).to have_content("Enter the 6-digit passcode") + mail = ActionMailer::Base.deliveries.last + otp_in_mail_sent = mail[:personalisation].decoded.scan(/\b[0-9]{6}\b/).first + fill_in "claim-one-time-password-field", with: otp_in_mail_sent + click_on "Confirm" + + expect(page).to have_content("Would you like to provide your mobile number?") + choose "No" + click_on "Continue" + + expect(page).to have_content("What account do you want the money paid into?") + choose "Personal bank account" + click_on "Continue" + + expect(page).to have_content("Enter your personal bank account details") + fill_in "Name on your account", with: "Jo Bloggs" + fill_in "Sort code", with: "123456" + fill_in "Account number", with: "87654321" + click_on "Continue" + + expect(page).to have_content("How is your gender recorded on your employer’s payroll system?") + choose "Female" + click_on "Continue" + + expect(page).to have_content("What is your teacher reference number (TRN)?") + fill_in "claim-teacher-reference-number-field", with: "1234567" + click_on "Continue" + + expect(page).to have_content("Check your answers before sending your application") + click_on "Accept and send" + + expect(page).to have_content("You applied for a further education financial incentive payment") end def and_college_exists diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index 559fe01436..a07e28fe5a 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -24,15 +24,7 @@ click_button "Continue" expect(page).to have_content("What type of contract do you have with #{college.name}?") - choose("Fixed-term contract") - click_button "Continue" - - expect(page).to have_content("Does your fixed-term contract cover the full #{AcademicYear.current.to_s(:long)} academic year?") - choose("No") - click_button "Continue" - - expect(page).to have_content("Have you taught at #{college.name} for at least one academic term?") - choose("Yes, I have taught at #{college.name} for at least one academic term") + choose("Permanent contract") click_button "Continue" expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") @@ -45,12 +37,51 @@ expect(page).to have_content("Which subject areas do you teach?") check("Building and construction") + check("Chemistry") + check("Computing, including digital and ICT") + check("Early years") + check("Engineering and manufacturing, including transport engineering and electronics") + check("Maths") + check("Physics") + click_button "Continue" + + expect(page).to have_content("Which building and construction courses do you teach?") + check "T Level in building services engineering for construction" + click_button "Continue" + + expect(page).to have_content("Which chemistry courses do you teach?") + check "GCSE chemistry" + click_button "Continue" + + expect(page).to have_content("Which computing courses do you teach?") + check "T Level in digital support services" + click_button "Continue" + + expect(page).to have_content("Which early years courses do you teach?") + check "T Level in education and early years (early years educator)" + click_button "Continue" + + expect(page).to have_content("Which engineering and manufacturing courses do you teach?") + check "T Level in design and development for engineering and manufacturing" click_button "Continue" - expect(page).to have_content("FE building and construction courses goes here") + expect(page).to have_content("Which maths courses do you teach?") + check("claim-maths-courses-esfa-field") click_button "Continue" - expect(page).to have_content("FE teaching courses goes here") + expect(page).to have_content("Which physics courses do you teach?") + check "A or AS level physics" + click_button "Continue" + + expect(page).to have_content("Do you spend at least half of your timetabled teaching hours teaching these eligible courses?") + expect(page).to have_content("T Level in building services engineering for construction") + expect(page).to have_content("GCSE chemistry") + expect(page).to have_content("T Level in digital support services") + expect(page).to have_content("T Level in education and early years (early years educator)") + expect(page).to have_content("T Level in design and development for engineering and manufacturing") + expect(page).to have_content("ESFA-funded qualifications at level 3 and below in the") + expect(page).to have_content("A or AS level physics") + choose("Yes") click_button "Continue" expect(page).to have_content("Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)?") @@ -74,15 +105,72 @@ expect(page).to have_content("Check your answers") click_button "Continue" - expect(page).to have_content("FE check your answers goes here") - click_button "Continue" - expect(page).to have_content("You’re eligible for a financial incentive payment") expect(page).to have_content("Apply now") - end + click_button "Apply now" + + expect(page).to have_content("FE ONE LOGIN PLACEHOLDER") + click_button "Continue" + + expect(page).to have_content("How we will use the information you provide in your application") + click_button "Continue" + + expect(page).to have_content("Personal details") + fill_in "First name", with: "John" + fill_in "Last name", with: "Doe" + fill_in "Day", with: "28" + fill_in "Month", with: "2" + fill_in "Year", with: "1988" + fill_in "National Insurance number", with: "PX321499A" + click_on "Continue" + + expect(page).to have_content("What is your home address?") + click_link("Enter your address manually") + + expect(page).to have_content("What is your address?") + fill_in "House number or name", with: "57" + fill_in "Building and street", with: "Walthamstow Drive" + fill_in "Town or city", with: "Derby" + fill_in "County", with: "City of Derby" + fill_in "Postcode", with: "DE22 4BS" + click_on "Continue" + + expect(page).to have_content("Email address") + fill_in "Email address", with: "johndoe@example.com" + click_on "Continue" + + expect(page).to have_content("Enter the 6-digit passcode") + mail = ActionMailer::Base.deliveries.last + otp_in_mail_sent = mail[:personalisation].decoded.scan(/\b[0-9]{6}\b/).first + fill_in "claim-one-time-password-field", with: otp_in_mail_sent + click_on "Confirm" + + expect(page).to have_content("Would you like to provide your mobile number?") + choose "No" + click_on "Continue" + + expect(page).to have_content("What account do you want the money paid into?") + choose "Personal bank account" + click_on "Continue" + + expect(page).to have_content("Enter your personal bank account details") + fill_in "Name on your account", with: "Jo Bloggs" + fill_in "Sort code", with: "123456" + fill_in "Account number", with: "87654321" + click_on "Continue" + + expect(page).to have_content("How is your gender recorded on your employer’s payroll system?") + choose "Female" + click_on "Continue" + + expect(page).to have_content("What is your teacher reference number (TRN)?") + fill_in "claim-teacher-reference-number-field", with: "1234567" + click_on "Continue" + + expect(page).to have_content("Check your answers before sending your application") + click_on "Accept and send" - def when_further_education_payments_journey_configuration_exists - create(:journey_configuration, :further_education_payments) + expect(page).to have_content("You applied for a further education financial incentive payment") end def and_college_exists diff --git a/spec/features/further_education_payments/ineligible_paths_spec.rb b/spec/features/further_education_payments/ineligible_paths_spec.rb index 652513e2ef..9e5197ef8c 100644 --- a/spec/features/further_education_payments/ineligible_paths_spec.rb +++ b/spec/features/further_education_payments/ineligible_paths_spec.rb @@ -55,8 +55,49 @@ expect(page).to have_content("You are not eligible for a financial incentive payment yet") end + scenario "when lacking subjects" do + when_further_education_payments_journey_configuration_exists + and_college_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose "Permanent contract" + click_button "Continue" + + expect(page).to have_content("On average, how many hours per week") + choose "More than 12 hours per week" + click_button "Continue" + + expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") + choose "September 2023 to August 2024" + click_button "Continue" + + expect(page).to have_content("Which subject areas do you teach?") + check "I do not teach any of these subjects" + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("you must teach an eligible FE subject") + end + scenario "when variable contract and just one academic term taught" do when_further_education_payments_journey_configuration_exists + and_college_exists visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) expect(page).to have_link("Start now") @@ -85,8 +126,427 @@ expect(page).to have_content("You are not eligible for a financial incentive payment yet") end - def when_further_education_payments_journey_configuration_exists - create(:journey_configuration, :further_education_payments) + scenario "when teaches non eligible course in applicable subject area" do + when_further_education_payments_journey_configuration_exists + and_college_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose "Permanent contract" + click_button "Continue" + + expect(page).to have_content("On average, how many hours per week") + choose "More than 12 hours per week" + click_button "Continue" + + expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") + choose "September 2023 to August 2024" + click_button "Continue" + + expect(page).to have_content("Which subject areas do you teach?") + check "Building and construction" + click_button "Continue" + + expect(page).to have_content("Which building and construction courses do you teach?") + check "I do not teach any of these courses" + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("you must teach an eligible FE course") + end + + scenario "when not a recent FE teacher" do + when_further_education_payments_journey_configuration_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose("Permanent contract") + click_button "Continue" + + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose("More than 12 hours per week") + click_button "Continue" + + expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") + choose("I started before September #{current_academic_year.start_year - 4}") + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("you must be in the first 5 years of") + end + + scenario "when teacher is subject to performance measures" do + when_further_education_payments_journey_configuration_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose "Permanent contract" + click_button "Continue" + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose "More than 12 hours per week" + click_button "Continue" + + expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") + choose "September 2023 to August 2024" + click_button "Continue" + + expect(page).to have_content("Which subject areas do you teach?") + check "Building and construction" + click_button "Continue" + + expect(page).to have_content("Which building and construction courses do you teach?") + check "T Level in onsite construction" + click_button "Continue" + + expect(page).to have_content("Do you spend at least half of your timetabled teaching hours teaching these eligible courses?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Do you have a teaching qualification?") + choose("Yes") + click_button "Continue" + + expect(page).to have_content("Have any performance measures been started against you?") + within all(".govuk-fieldset")[0] do + choose("Yes") + end + expect(page).to have_content("Are you currently subject to disciplinary action?") + within all(".govuk-fieldset")[1] do + choose("No") + end + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("you must not currently be subject to any") + end + + scenario "when teacher is subject to disciplinary action" do + when_further_education_payments_journey_configuration_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose "Permanent contract" + click_button "Continue" + + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose "More than 12 hours per week" + click_button "Continue" + + expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") + choose "September 2023 to August 2024" + click_button "Continue" + + expect(page).to have_content("Which subject areas do you teach?") + check "Building and construction" + click_button "Continue" + + expect(page).to have_content("Which building and construction courses do you teach?") + check "T Level in onsite construction" + click_button "Continue" + + expect(page).to have_content("Do you spend at least half of your timetabled teaching hours teaching these eligible courses?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Do you have a teaching qualification?") + choose("Yes") + click_button "Continue" + + expect(page).to have_content("Have any performance measures been started against you?") + within all(".govuk-fieldset")[0] do + choose("No") + end + expect(page).to have_content("Are you currently subject to disciplinary action?") + within all(".govuk-fieldset")[1] do + choose("Yes") + end + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("you must not currently be subject to any") + end + + scenario "when lacks teaching qualification and no enrol plan" do + when_further_education_payments_journey_configuration_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose "Permanent contract" + click_button "Continue" + + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose "More than 12 hours per week" + click_button "Continue" + + expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") + choose "September 2023 to August 2024" + click_button "Continue" + + expect(page).to have_content("Which subject areas do you teach?") + check "Building and construction" + click_button "Continue" + + expect(page).to have_content("Which building and construction courses do you teach?") + check "T Level in onsite construction" + click_button "Continue" + + expect(page).to have_content("Do you spend at least half of your timetabled teaching hours teaching these eligible courses?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Do you have a teaching qualification?") + choose "No, and I do not plan to enrol on one in the next 12 months" + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("plan to enrol on a teaching qualification in the next 12 months") + end + + scenario "when permanent contract and not enough hours" do + when_further_education_payments_journey_configuration_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose "Permanent contract" + click_button "Continue" + + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose("Less than 2.5 hours per week") + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("teach at least 2.5 hours per week") + end + + scenario "when fixed-term contract and not enough hours" do + when_further_education_payments_journey_configuration_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose "Fixed-term contract" + click_button "Continue" + + expect(page).to have_content("Does your fixed-term contract cover the full #{current_academic_year.to_s(:long)} academic year?") + choose "Yes, it covers the full #{current_academic_year.to_s(:long)} academic year" + click_button "Continue" + + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose "More than 12 hours per week" + click_button "Continue" + + expect(page).to have_content("Are you timetabled to teach at least 2.5 hours per week at #{college.name} next term?") + choose("No, I’m not timetabled to teach at least 2.5 hours per week at #{college.name} next term") + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("teach at least 2.5 hours per week") + end + + scenario "when variable contract and not enough hours" do + when_further_education_payments_journey_configuration_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose("Variable hours contract") + click_button "Continue" + + expect(page).to have_content("Have you taught at #{college.name} for at least one academic term?") + choose("Yes, I have taught at #{college.name} for at least one academic term") + click_button "Continue" + + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose("More than 12 hours per week") + click_button "Continue" + + expect(page).to have_content("Are you timetabled to teach at least 2.5 hours per week at #{college.name} next term?") + choose("No, I’m not timetabled to teach at least 2.5 hours per week at #{college.name} next term") + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("teach at least 2.5 hours per week") + end + + scenario "when less that 50% teaching hours to FE" do + when_further_education_payments_journey_configuration_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Which FE provider are you employed by?") + fill_in "Which FE provider are you employed by?", with: college.name + click_button "Continue" + + expect(page).to have_content("Select the college you teach at") + choose college.name + click_button "Continue" + + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose("Permanent contract") + click_button "Continue" + + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose("More than 12 hours per week") + click_button "Continue" + + expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") + choose("September 2023 to August 2024") + click_button "Continue" + + expect(page).to have_content("Which subject areas do you teach?") + check "Building and construction" + click_button "Continue" + + expect(page).to have_content("Which building and construction courses do you teach?") + check "T Level in onsite construction" + click_button "Continue" + + expect(page).to have_content("Do you spend at least half of your timetabled teaching hours teaching these eligible courses?") + choose "Yes" + click_button "Continue" + + expect(page).to have_content("Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)?") + choose "No" + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("half of your timetabled teaching hours must include") end def and_college_exists diff --git a/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb b/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb index 73944cbeb0..637c37c219 100644 --- a/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb +++ b/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb @@ -68,6 +68,7 @@ ) and_i_complete_the_state_funded_secondary_school_step_with(option: "Yes") and_i_complete_the_current_school_step(create(:school, phase: :secondary)) + and_i_complete_the_headteacher_step and_i_complete_the_contract_details_step_with(option: "No") then_i_see_the_ineligible_page end @@ -81,6 +82,7 @@ ) and_i_complete_the_state_funded_secondary_school_step_with(option: "Yes") and_i_complete_the_current_school_step(create(:school, phase: :secondary)) + and_i_complete_the_headteacher_step and_i_complete_the_contract_details_step_with(option: "Yes") and_i_complete_the_contract_start_date_step_with( date: Policies::InternationalRelocationPayments::PolicyEligibilityChecker @@ -98,6 +100,7 @@ ) and_i_complete_the_state_funded_secondary_school_step_with(option: "Yes") and_i_complete_the_current_school_step(create(:school, phase: :secondary)) + and_i_complete_the_headteacher_step and_i_complete_the_contract_details_step_with(option: "Yes") and_i_complete_the_contract_start_date_step_with( date: contract_start_date @@ -115,6 +118,7 @@ ) and_i_complete_the_state_funded_secondary_school_step_with(option: "Yes") and_i_complete_the_current_school_step(create(:school, phase: :secondary)) + and_i_complete_the_headteacher_step and_i_complete_the_contract_details_step_with(option: "Yes") and_i_complete_the_contract_start_date_step_with( date: contract_start_date @@ -133,6 +137,7 @@ ) and_i_complete_the_state_funded_secondary_school_step_with(option: "Yes") and_i_complete_the_current_school_step(create(:school, phase: :secondary)) + and_i_complete_the_headteacher_step and_i_complete_the_contract_details_step_with(option: "Yes") and_i_complete_the_contract_start_date_step_with( date: contract_start_date diff --git a/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb b/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb index c034ea0e6c..89a253c0e0 100644 --- a/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb +++ b/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb @@ -32,6 +32,7 @@ ) and_i_complete_the_state_funded_secondary_school_step_with(option: "Yes") and_i_complete_the_current_school_step(school) + and_i_complete_the_headteacher_step and_i_complete_the_contract_details_step_with(option: "Yes") and_i_complete_the_contract_start_date_step_with( date: contract_start_date @@ -47,7 +48,6 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") - and_i_complete_the_headteacher_step and_i_complete_the_personal_details_step and_i_complete_the_postcode_step and_i_complete_the_email_address_step @@ -64,7 +64,6 @@ it "submits an application", js: true do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") - and_i_complete_the_headteacher_step and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step @@ -81,7 +80,6 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") - and_i_complete_the_headteacher_step and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step @@ -98,7 +96,6 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") - and_i_complete_the_headteacher_step and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step @@ -131,6 +128,10 @@ def then_the_check_your_answers_part_one_page_shows_my_answers "Which school are you currently employed to teach at? #{school.name}" ) + expect(page).to have_text( + "Enter the name of the headteacher of the school where you are employed as a teacher Seymour Skinner" + ) + expect(page).to have_text( "Are you employed on a contract lasting at least one year? Yes" ) @@ -179,10 +180,6 @@ def then_the_check_your_answers_part_page_shows_my_answers(school, mobile_number "Enter your passport number, as it appears on your passport 123456789" ) - expect(page).to have_text( - "Enter the name of the headteacher of the school where you are employed as a teacher Seymour Skinner" - ) - if mobile_number expect(page).to have_text("Mobile number 01234567890") else diff --git a/spec/forms/form_spec.rb b/spec/forms/form_spec.rb index c54c9df484..de7e53d8b9 100644 --- a/spec/forms/form_spec.rb +++ b/spec/forms/form_spec.rb @@ -163,6 +163,53 @@ def initialize(journey_session) end end + describe "#t" do + let(:form) { TestSlugForm.new(journey:, journey_session:, params:) } + let(:args) { {} } + let(:key) { "some_key" } + + before do + allow(I18n).to receive(:t) + form.t(key, args) + end + + context "no args" do + it do + expect(I18n).to have_received(:t).with("test_i18n_ns.forms.test_slug.some_key", {default: :"forms.test_slug.some_key"}) + end + end + + context "override i18n_form_namespace" do + let(:args) { {i18n_form_namespace: "overriden_ns"} } + + it do + expect(I18n).to have_received(:t).with("test_i18n_ns.forms.overriden_ns.some_key", {default: :"forms.overriden_ns.some_key"}) + end + end + end + + describe "#t - actually use something from en.yml" do + let(:params) { ActionController::Parameters.new({}) } + + subject(:form) { GenderForm.new(journey:, journey_session:, params:) } + + context "FE journey overrides gender form in en.yml" do + let(:journey) { Journeys::FurtherEducationPayments } + + it "calls the i18n namespaced version" do + expect(form.t("questions.payroll_gender")).to eq("How is your gender recorded on your employer’s payroll system?") + end + end + + context "TSLR journey uses the base gender form in en.yml" do + let(:journey) { Journeys::TeacherStudentLoanReimbursement } + + it "calls the base version" do + expect(form.t("questions.payroll_gender")).to eq("How is your gender recorded on your school’s payroll system?") + end + end + end + describe "#permitted_params" do let(:claim_params) { {first_name: "test-value"} } diff --git a/spec/forms/journeys/further_education_payments/building_construction_courses_form_spec.rb b/spec/forms/journeys/further_education_payments/building_construction_courses_form_spec.rb new file mode 100644 index 0000000000..f1fc475eba --- /dev/null +++ b/spec/forms/journeys/further_education_payments/building_construction_courses_form_spec.rb @@ -0,0 +1,55 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::BuildingConstructionCoursesForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:building_construction_courses) { [""] } + + let(:params) do + ActionController::Parameters.new( + claim: { + building_construction_courses: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + it do + is_expected.not_to( + allow_value([""]) + .for(:building_construction_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + + context "when non-existent injection option selected" do + it do + is_expected.not_to( + allow_value(["foo"]) + .for(:building_construction_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + end + + describe "#save" do + let(:building_construction_courses) { ["esfa_buildingconstruction", "tlevel_building"] } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.building_construction_courses }.to(building_construction_courses) + ) + end + end +end diff --git a/spec/forms/journeys/further_education_payments/chemistry_courses_form_spec.rb b/spec/forms/journeys/further_education_payments/chemistry_courses_form_spec.rb new file mode 100644 index 0000000000..32c09a230a --- /dev/null +++ b/spec/forms/journeys/further_education_payments/chemistry_courses_form_spec.rb @@ -0,0 +1,55 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::ChemistryCoursesForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:chemistry_courses) { [""] } + + let(:params) do + ActionController::Parameters.new( + claim: { + chemistry_courses: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + it do + is_expected.not_to( + allow_value([""]) + .for(:chemistry_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + + context "when non-existent injection option selected" do + it do + is_expected.not_to( + allow_value(["foo"]) + .for(:chemistry_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + end + + describe "#save" do + let(:chemistry_courses) { ["alevel_chemistry", "gcse_chemistry"] } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.chemistry_courses }.to(chemistry_courses) + ) + end + end +end diff --git a/spec/forms/journeys/further_education_payments/computing_courses_form_spec.rb b/spec/forms/journeys/further_education_payments/computing_courses_form_spec.rb new file mode 100644 index 0000000000..441cd22d10 --- /dev/null +++ b/spec/forms/journeys/further_education_payments/computing_courses_form_spec.rb @@ -0,0 +1,55 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::ComputingCoursesForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:computing_courses) { [""] } + + let(:params) do + ActionController::Parameters.new( + claim: { + computing_courses: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + it do + is_expected.not_to( + allow_value([""]) + .for(:computing_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + + context "when non-existent injection option selected" do + it do + is_expected.not_to( + allow_value(["foo"]) + .for(:computing_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + end + + describe "#save" do + let(:computing_courses) { ["digitalskills_quals", "tlevel_digitalsupport"] } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.computing_courses }.to(computing_courses) + ) + end + end +end diff --git a/spec/forms/journeys/further_education_payments/early_years_courses_form_spec.rb b/spec/forms/journeys/further_education_payments/early_years_courses_form_spec.rb new file mode 100644 index 0000000000..6a20f65c70 --- /dev/null +++ b/spec/forms/journeys/further_education_payments/early_years_courses_form_spec.rb @@ -0,0 +1,55 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::EarlyYearsCoursesForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:early_years_courses) { [""] } + + let(:params) do + ActionController::Parameters.new( + claim: { + early_years_courses: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + it do + is_expected.not_to( + allow_value([""]) + .for(:early_years_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + + context "when non-existent injection option selected" do + it do + is_expected.not_to( + allow_value(["foo"]) + .for(:early_years_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + end + + describe "#save" do + let(:early_years_courses) { ["eylevel2", "eylevel3"] } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.early_years_courses }.to(early_years_courses) + ) + end + end +end diff --git a/spec/forms/journeys/further_education_payments/engineering_manufacturing_courses_form_spec.rb b/spec/forms/journeys/further_education_payments/engineering_manufacturing_courses_form_spec.rb new file mode 100644 index 0000000000..2fd862376a --- /dev/null +++ b/spec/forms/journeys/further_education_payments/engineering_manufacturing_courses_form_spec.rb @@ -0,0 +1,55 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::EngineeringManufacturingCoursesForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:engineering_manufacturing_courses) { [""] } + + let(:params) do + ActionController::Parameters.new( + claim: { + engineering_manufacturing_courses: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + it do + is_expected.not_to( + allow_value([""]) + .for(:engineering_manufacturing_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + + context "when non-existent injection option selected" do + it do + is_expected.not_to( + allow_value(["foo"]) + .for(:engineering_manufacturing_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + end + + describe "#save" do + let(:engineering_manufacturing_courses) { ["esfa_engineering", "esfa_manufacturing"] } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.engineering_manufacturing_courses }.to(engineering_manufacturing_courses) + ) + end + end +end diff --git a/spec/forms/journeys/further_education_payments/hours_teaching_eligible_subjects_form_spec.rb b/spec/forms/journeys/further_education_payments/hours_teaching_eligible_subjects_form_spec.rb new file mode 100644 index 0000000000..1a5de36329 --- /dev/null +++ b/spec/forms/journeys/further_education_payments/hours_teaching_eligible_subjects_form_spec.rb @@ -0,0 +1,58 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::HoursTeachingEligibleSubjectsForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + + let(:params) do + ActionController::Parameters.new( + claim: { + hours_teaching_eligible_subjects: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + let(:hours_teaching_eligible_subjects) { nil } + + it do + is_expected.not_to( + allow_value(nil) + .for(:hours_teaching_eligible_subjects) + .with_message("Select yes if you spend at least half of your timetabled teaching hours teaching these eligible courses") + ) + end + end + + describe "#save" do + context "Yes" do + let(:hours_teaching_eligible_subjects) { true } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.hours_teaching_eligible_subjects } + .to(true) + ) + end + end + + context "No" do + let(:hours_teaching_eligible_subjects) { false } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.hours_teaching_eligible_subjects } + .to(false) + ) + end + end + end +end diff --git a/spec/forms/journeys/further_education_payments/maths_courses_form_spec.rb b/spec/forms/journeys/further_education_payments/maths_courses_form_spec.rb new file mode 100644 index 0000000000..f427b4f8c3 --- /dev/null +++ b/spec/forms/journeys/further_education_payments/maths_courses_form_spec.rb @@ -0,0 +1,55 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::MathsCoursesForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:maths_courses) { [""] } + + let(:params) do + ActionController::Parameters.new( + claim: { + maths_courses: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + it do + is_expected.not_to( + allow_value([""]) + .for(:maths_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + + context "when non-existent injection option selected" do + it do + is_expected.not_to( + allow_value(["foo"]) + .for(:maths_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + end + + describe "#save" do + let(:maths_courses) { ["gcse_maths"] } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.maths_courses }.to(maths_courses) + ) + end + end +end diff --git a/spec/forms/journeys/further_education_payments/physics_courses_form_spec.rb b/spec/forms/journeys/further_education_payments/physics_courses_form_spec.rb new file mode 100644 index 0000000000..3b9bc198ab --- /dev/null +++ b/spec/forms/journeys/further_education_payments/physics_courses_form_spec.rb @@ -0,0 +1,55 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::PhysicsCoursesForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:physics_courses) { [""] } + + let(:params) do + ActionController::Parameters.new( + claim: { + physics_courses: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + it do + is_expected.not_to( + allow_value([""]) + .for(:physics_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + + context "when non-existent injection option selected" do + it do + is_expected.not_to( + allow_value(["foo"]) + .for(:physics_courses) + .with_message("Select all the courses you teach otherwise select you do not teach any of these courses") + ) + end + end + end + + describe "#save" do + let(:physics_courses) { ["alevel_physics", "gcse_physics"] } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.physics_courses }.to(physics_courses) + ) + end + end +end diff --git a/spec/forms/journeys/further_education_payments/subjects_taught_form_spec.rb b/spec/forms/journeys/further_education_payments/subjects_taught_form_spec.rb index 22f5c75266..355d60dca5 100644 --- a/spec/forms/journeys/further_education_payments/subjects_taught_form_spec.rb +++ b/spec/forms/journeys/further_education_payments/subjects_taught_form_spec.rb @@ -2,7 +2,9 @@ RSpec.describe Journeys::FurtherEducationPayments::SubjectsTaughtForm, type: :model do let(:journey) { Journeys::FurtherEducationPayments } - let(:journey_session) { create(:further_education_payments_session) } + let(:journey_session) { create(:further_education_payments_session, answers:) } + let(:answers) { build(:further_education_payments_answers, answers_hash) } + let(:answers_hash) { {} } let(:subjects_taught) { [] } let(:params) do @@ -48,12 +50,70 @@ end describe "#save" do - let(:subjects_taught) { ["chemistry", "mathematics"] } + let(:subjects_taught) { ["chemistry", "maths"] } it "updates the journey session" do expect { expect(subject.save).to be(true) }.to( - change { journey_session.reload.answers.subjects_taught }.to(["chemistry", "mathematics"]) + change { journey_session.reload.answers.subjects_taught }.to(["chemistry", "maths"]) ) end + + context "when changing some answers" do + let(:answers_hash) do + { + subjects_taught: %w[maths physics], + maths_courses: %w[esfa], + physics_courses: %w[alevel_physics] + } + end + + let(:subjects_taught) { %w[chemistry maths] } + + it "resets dependent answers" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.subjects_taught }.to(subjects_taught) + .and(change { journey_session.reload.answers.physics_courses }.to([]) + .and(not_change { journey_session.reload.answers.maths_courses })) + ) + end + end + + context "when changing all answers" do + let(:answers_hash) do + { + subjects_taught: %w[ + building_construction + chemistry + computing + early_years + engineering_manufacturing + maths + physics + ], + building_construction_courses: %w[none], + chemistry_courses: %w[none], + computing_courses: %w[none], + early_years_courses: %w[none], + engineering_manufacturing_courses: %w[none], + maths_courses: %w[none], + physics_courses: %w[none] + } + end + + let(:subjects_taught) { %w[none] } + + it "resets dependent answers" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.subjects_taught }.to(subjects_taught) + .and(change { journey_session.reload.answers.building_construction_courses }.to([]) + .and(change { journey_session.reload.answers.chemistry_courses }.to([]) + .and(change { journey_session.reload.answers.computing_courses }.to([]) + .and(change { journey_session.reload.answers.early_years_courses }.to([]) + .and(change { journey_session.reload.answers.engineering_manufacturing_courses }.to([]) + .and(change { journey_session.reload.answers.maths_courses }.to([]) + .and(change { journey_session.reload.answers.physics_courses }.to([])))))))) + ) + end + end end end diff --git a/spec/forms/journeys/further_education_payments/teaching_hours_per_week_next_term_form_spec.rb b/spec/forms/journeys/further_education_payments/teaching_hours_per_week_next_term_form_spec.rb new file mode 100644 index 0000000000..c197b64fdb --- /dev/null +++ b/spec/forms/journeys/further_education_payments/teaching_hours_per_week_next_term_form_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::TeachingHoursPerWeekNextTermForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session, answers:) } + let(:answers) { build(:further_education_payments_answers, answers_hash) } + let(:college) { create(:school) } + let(:answers_hash) do + {school_id: college.id} + end + let(:teaching_hours_per_week_next_term) { nil } + + let(:params) do + ActionController::Parameters.new( + claim: { + teaching_hours_per_week_next_term: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + it do + is_expected.not_to( + allow_value(nil) + .for(:teaching_hours_per_week_next_term) + .with_message("Select yes if you are timetabled to teach at least 2.5 hours next term otherwise select you are not") + ) + end + end + + describe "#save" do + let(:teaching_hours_per_week_next_term) { "at_least_2_5" } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.teaching_hours_per_week_next_term }.to(teaching_hours_per_week_next_term) + ) + end + end +end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb index f9bbba704f..6d7c52ab0c 100644 --- a/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb @@ -88,6 +88,10 @@ eligibility_answers.each do |attribute, value| expect(eligibility.public_send(attribute)).to eq(value) end + + expect(eligibility.award_amount).to eq( + Policies::InternationalRelocationPayments.award_amount + ) end end end diff --git a/spec/models/eligible_fe_providers_importer_spec.rb b/spec/models/eligible_fe_providers_importer_spec.rb new file mode 100644 index 0000000000..d865dc5775 --- /dev/null +++ b/spec/models/eligible_fe_providers_importer_spec.rb @@ -0,0 +1,88 @@ +require "rails_helper" + +RSpec.describe EligibleFeProvidersImporter do + subject { described_class.new(file, academic_year) } + + let(:academic_year) { AcademicYear.current } + let(:file) { Tempfile.new } + let(:correct_headers) { described_class.mandatory_headers.join(",") + "\n" } + + def to_row(hash) + [ + hash[:ukprn], + hash[:max_award_amount], + hash[:lower_award_amount] + ].join(",") + "\n" + end + + describe "#run" do + context "when incorrect headers" do + before do + file.write "incorrect,headers,here,here" + file.close + end + + it "has errors" do + subject.run + + expect(subject.errors).to be_present + expect(subject.errors).to include("The selected file is missing some expected columns: ukprn, max_award_amount, lower_award_amount") + end + end + + context "when csv has no rows" do + before do + file.write correct_headers + file.close + end + + it "has no errors" do + subject.run + + expect(subject.errors).to be_empty + end + + it "does not add any any records" do + expect { subject.run }.not_to change { EligibleFeProvider.count } + end + + context "when there are existing records" do + before do + create(:eligible_fe_provider) + create(:eligible_fe_provider, academic_year: AcademicYear.next) + end + + it "deletes existing records for academic year" do + expect { subject.run }.to change { EligibleFeProvider.count }.to(1) + end + end + end + + context "with valid data" do + before do + file.write correct_headers + + 3.times do + file.write to_row(attributes_for(:eligible_fe_provider)) + end + + file.close + end + + it "imports new records" do + expect { subject.run }.to change { EligibleFeProvider.count }.by(3) + end + + context "when there are existing records" do + before do + create(:eligible_fe_provider) + create(:eligible_fe_provider, academic_year: AcademicYear.next) + end + + it "deletes them with new records" do + expect { subject.run }.to change { EligibleFeProvider.count }.by(2) + end + end + end + end +end diff --git a/spec/models/journeys/further_education_payments/answers_presenter_spec.rb b/spec/models/journeys/further_education_payments/answers_presenter_spec.rb index 892202376c..86dfcfa0e0 100644 --- a/spec/models/journeys/further_education_payments/answers_presenter_spec.rb +++ b/spec/models/journeys/further_education_payments/answers_presenter_spec.rb @@ -14,7 +14,7 @@ let(:contract_type) { "permanent" } let(:teaching_hours_per_week) { "more_than_12" } let(:further_education_teaching_start_year) { 2023 } - let(:subjects_taught) { ["chemistry", "mathematics"] } + let(:subjects_taught) { ["chemistry", "maths"] } let(:half_teaching_hours) { true } let(:teaching_qualification) { "yes" } let(:subject_to_formal_performance_action) { false } @@ -44,7 +44,7 @@ ["What type of contract do you have with #{college.name}?", "Permanent contract", "contract-type"], ["On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?", "More than 12 hours per week", "teaching-hours-per-week"], ["Which academic year did you start teaching in further education (FE) in England?", "September 2023 to August 2024", "further-education-teaching-start-year"], - ["Which subject areas do you teach?", "Chemistry
Mathematics
", "subjects-taught"], + ["Which subject areas do you teach?", "Chemistry
Maths
", "subjects-taught"], ["Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)?", "Yes", "half-teaching-hours"], ["Do you have a teaching qualification?", "Yes", "teaching-qualification"], ["Have any performance measures been started against you?", "No", "poor-performance"], @@ -66,7 +66,7 @@ end context "subjects-taught - just one" do - let(:subjects_taught) { %w[building_and_construction] } + let(:subjects_taught) { %w[building_construction] } it { is_expected.to include([ @@ -78,12 +78,12 @@ end context "subjects-taught - all of them" do - let(:subjects_taught) { %w[building_and_construction chemistry computing early_years engineering_and_manufacturing mathematics physics] } + let(:subjects_taught) { %w[building_construction chemistry computing early_years engineering_manufacturing maths physics] } it { is_expected.to include([ "Which subject areas do you teach?", - "Building and construction
Chemistry
Computing, including digital and ICT
Early years
Engineering and manufacturing, including transport engineering and electronics
Mathematics
Physics
", + "Building and construction
Chemistry
Computing, including digital and ICT
Early years
Engineering and manufacturing, including transport engineering and electronics
Maths
Physics
", "subjects-taught" ]) } diff --git a/spec/models/journeys/get_a_teacher_relocation_payment/answers_presenter_spec.rb b/spec/models/journeys/get_a_teacher_relocation_payment/answers_presenter_spec.rb index 3e8f58f4ed..1afd702632 100644 --- a/spec/models/journeys/get_a_teacher_relocation_payment/answers_presenter_spec.rb +++ b/spec/models/journeys/get_a_teacher_relocation_payment/answers_presenter_spec.rb @@ -16,6 +16,7 @@ :with_teacher_application_route, :with_state_funded_secondary_school, :with_current_school, + :with_headteacher_details, :with_one_year_contract, :with_start_date, :with_subject, @@ -32,15 +33,20 @@ "I am employed as a teacher in a school in England", "application-route" ], + [ + "Are you employed by an English state secondary school?", + "Yes", + "state-funded-secondary-school" + ], [ "Which school are you currently employed to teach at?", answers.current_school.name, "current-school" ], [ - "Are you employed by an English state secondary school?", - "Yes", - "state-funded-secondary-school" + "Enter the name of the headteacher of the school where you are employed as a teacher", + "Seymour Skinner", + "headteacher-details" ], [ "Are you employed on a contract lasting at least one year?", @@ -97,25 +103,4 @@ ) end end - - describe "#employment_answers" do - subject { presenter.employment_answers } - - let(:answers) do - build( - :get_a_teacher_relocation_payment_answers, - :with_employment_details - ) - end - - it do - is_expected.to include( - [ - "Enter the name of the headteacher of the school where you are employed as a teacher", - "Seymour Skinner", - "headteacher-details" - ] - ) - end - end end diff --git a/spec/models/policies/further_education_payments/policy_eligibility_checker_spec.rb b/spec/models/policies/further_education_payments/policy_eligibility_checker_spec.rb index 5b93b7917e..99c90d21d3 100644 --- a/spec/models/policies/further_education_payments/policy_eligibility_checker_spec.rb +++ b/spec/models/policies/further_education_payments/policy_eligibility_checker_spec.rb @@ -25,11 +25,39 @@ build(:further_education_payments_answers, taught_at_least_one_term: false) end - it "is ineligble as :lack_teaching_responsibilities" do + it "is ineligble as :must_teach_at_least_one_term" do expect(subject).to be_ineligible expect(subject.status).to eql(:ineligible) expect(subject.ineligibility_reason).to eql(:must_teach_at_least_one_term) end end + + context "when ineligible as lacking subjects taught" do + let(:answers) do + build(:further_education_payments_answers, subjects_taught: ["none"]) + end + + it "is ineligble as :subject" do + expect(subject).to be_ineligible + expect(subject.status).to eql(:ineligible) + expect(subject.ineligibility_reason).to eql(:subject) + end + end + + context "when all courses are ineligible" do + let(:answers) do + build( + :further_education_payments_answers, + subjects_taught: ["building_construction"], + building_construction_courses: ["none"] + ) + end + + it "is ineligble as :lack_teaching_responsibilities" do + expect(subject).to be_ineligible + expect(subject.status).to eql(:ineligible) + expect(subject.ineligibility_reason).to eql(:courses) + end + end end end diff --git a/spec/models/policies/international_relocation_payments/eligibility_admin_answers_presenter_spec.rb b/spec/models/policies/international_relocation_payments/eligibility_admin_answers_presenter_spec.rb index 7dba901327..291234d846 100644 --- a/spec/models/policies/international_relocation_payments/eligibility_admin_answers_presenter_spec.rb +++ b/spec/models/policies/international_relocation_payments/eligibility_admin_answers_presenter_spec.rb @@ -1,13 +1,60 @@ require "rails_helper" RSpec.describe Policies::InternationalRelocationPayments::EligibilityAdminAnswersPresenter, type: :model do - let(:claim) { build(:claim, :submittable, policy: Policies::InternationalRelocationPayments, academic_year: "2021/2022") } + describe "#answers" do + subject { described_class.new(eligibility).answers } - subject(:presenter) { described_class.new(claim.eligibility) } + let(:school) { create(:school) } - describe "#answers" do - it "returns an array of questions and answers for displaying to service operator" do - expect(presenter.answers).to eq [[I18n.t("admin.current_school"), presenter.display_school(claim.eligibility.current_school)]] + let(:eligibility) do + build( + :international_relocation_payments_eligibility, + nationality: "American", + passport_number: "123456789", + current_school: school, + subject: "physics", + school_headteacher_name: "Principal Skinner", + start_date: Date.new(2024, 3, 1), + visa_type: "British National (Overseas) visa", + date_of_entry: Date.new(2024, 2, 1) + ) + end + + it do + is_expected.to include( + [ + "Nationality", + "American" + ], + [ + "Passport number", + "123456789" + ], + [ + "Current school", + /#{school.name}/ + ], + [ + "Subject", + "Physics" + ], + [ + "School headteacher name", + "Principal Skinner" + ], + [ + "Contract start date", + "1 March 2024" + ], + [ + "Visa type", + "British National (Overseas) visa" + ], + [ + "Date of entry", + "1 February 2024" + ] + ) end end end diff --git a/spec/smoke/start_a_claim_spec.rb b/spec/smoke/start_a_claim_spec.rb deleted file mode 100644 index f334c41f75..0000000000 --- a/spec/smoke/start_a_claim_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -require "rails_helper" - -RSpec.describe "Start a claim", :smoke, type: :feature do - # To test this locally you will need to add to your .env file: - # - # SMOKE_TEST_APP_HOST - # BASIC_AUTH_USERNAME - # BASIC_AUTH_PASSWORD - - scenario "User starts a claim" do - visit url_with_basic_auth - expect(page).to have_text("Teachers: claim back your student loan repayments") - end - - def url_with_basic_auth - host = ENV.fetch("SMOKE_TEST_APP_HOST") - path = new_claim_path(Journeys::TeacherStudentLoanReimbursement::ROUTING_NAME) - uri = URI.join(host, path) - - uri.user = ENV.fetch("BASIC_AUTH_USERNAME", nil) - uri.password = ENV.fetch("BASIC_AUTH_PASSWORD", nil) - uri.to_s - end -end diff --git a/spec/smoke/visit_admin_spec.rb b/spec/smoke/visit_admin_spec.rb new file mode 100644 index 0000000000..c9d66cd904 --- /dev/null +++ b/spec/smoke/visit_admin_spec.rb @@ -0,0 +1,30 @@ +require "rails_helper" + +RSpec.describe "Visit admin", :smoke, type: :feature do + # To test this locally you will need to add to your .env file: + # + # SMOKE_TEST_APP_HOST + # BASIC_AUTH_USERNAME + # BASIC_AUTH_PASSWORD + + scenario "User visits admin" do + visit url_with_basic_auth + expect(page).to have_text(I18n.t("service_name")) + end + + def url_with_basic_auth + host = ENV.fetch("SMOKE_TEST_APP_HOST") + path = admin_root_path + uri = URI.join(host, path) + + username = ENV.fetch("BASIC_AUTH_USERNAME", nil) + password = ENV.fetch("BASIC_AUTH_PASSWORD", nil) + + if username.present? && password.present? + uri.user = username + uri.password = password + end + + uri.to_s + end +end diff --git a/spec/support/steps/journey_configuration.rb b/spec/support/steps/journey_configuration.rb new file mode 100644 index 0000000000..af552fccb5 --- /dev/null +++ b/spec/support/steps/journey_configuration.rb @@ -0,0 +1,3 @@ +def when_further_education_payments_journey_configuration_exists + create(:journey_configuration, :further_education_payments) +end diff --git a/terraform/application/application.tf b/terraform/application/application.tf index 9818895f82..d4afd87ec6 100644 --- a/terraform/application/application.tf +++ b/terraform/application/application.tf @@ -13,10 +13,10 @@ module "application_configuration" { config_variables = merge( local.app_env_values, { - ENVIRONMENT_NAME = var.environment - PGSSLMODE = local.postgres_ssl_mode + ENVIRONMENT_NAME = var.environment + PGSSLMODE = local.postgres_ssl_mode CANONICAL_HOSTNAME = local.canonical_hostname - }) + }) secret_variables = { DATABASE_URL = module.postgres.url } @@ -39,7 +39,9 @@ module "web_application" { docker_image = var.docker_image command = var.startup_command - replicas = var.web_replicas + replicas = var.web_replicas + + enable_logit = var.enable_logit } module "worker_application" { @@ -58,4 +60,8 @@ module "worker_application" { docker_image = var.docker_image command = var.worker_command + + replicas = var.worker_replicas + + enable_logit = var.enable_logit } diff --git a/terraform/application/config/production.tfvars.json b/terraform/application/config/production.tfvars.json new file mode 100644 index 0000000000..51b2bc1096 --- /dev/null +++ b/terraform/application/config/production.tfvars.json @@ -0,0 +1,22 @@ +{ + "cluster": "production", + "namespace": "srtl-production", + "config": "production", + "environment": "production", + "canonical_hostname": "www.claim-additional-teaching-payment.service.gov.uk", + "web_replicas": 2, + "worker_replicas": 2, + "startup_command": ["/bin/sh", "-c", "bin/rails server -b 0.0.0.0"], + "worker_command": ["/bin/sh", "-c", "bin/bundle exec bin/delayed_job run -n 1"], + "postgres_flexible_server_sku": "GP_Standard_D2ds_v4", + "postgres_enable_high_availability": true, + "enable_postgres_backup_storage": true, + "azure_maintenance_window": { + "day_of_week": 0, + "start_hour": 3, + "start_minute": 0 + }, + "enable_monitoring": true, + "statuscake_contact_groups": [195955, 282453], + "external_url": "https://www.claim-additional-teaching-payment.service.gov.uk/healthcheck" +} diff --git a/terraform/application/config/production_Terrafile b/terraform/application/config/production_Terrafile new file mode 100644 index 0000000000..5b2b118f00 --- /dev/null +++ b/terraform/application/config/production_Terrafile @@ -0,0 +1,3 @@ +aks: + source: "https://github.com/DFE-Digital/terraform-modules" + version: "stable" diff --git a/terraform/application/config/production_app_env.yml b/terraform/application/config/production_app_env.yml new file mode 100644 index 0000000000..65f3b3fe10 --- /dev/null +++ b/terraform/application/config/production_app_env.yml @@ -0,0 +1,19 @@ +--- +DFE_SIGN_IN_API_CLIENT_ID: teacherpayments +DFE_SIGN_IN_API_ENDPOINT: https://api.signin.education.gov.uk +DFE_SIGN_IN_IDENTIFIER: teacherpayments +DFE_SIGN_IN_ISSUER: https://oidc.signin.education.gov.uk:443 +DFE_SIGN_IN_REDIRECT_BASE_URL: https://www.claim-additional-teaching-payment.service.gov.uk + +DQT_API_URL: https://teacher-qualifications-api.education.gov.uk/v1 +DQT_BASE_URL: https://api-customerengagement.platform.education.gov.uk/dqt-crm/v1/ + +HMRC_API_BASE_URL: https://api.service.hmrc.gov.uk +HMRC_API_BANK_VALIDATION_ENABLED: true + +ORDNANCE_SURVEY_API_BASE_URL: https://api.os.uk + +TID_BASE_URL: https://claim-additional-teaching-payment.service.gov.uk/additional-payments/claim +TID_SIGN_IN_API_ENDPOINT: https://teaching-identity.education.gov.uk/ +TID_SIGN_IN_CLIENT_ID: claim +TID_SIGN_IN_ISSUER: https://teaching-identity.education.gov.uk/ diff --git a/terraform/application/config/review.tfvars.json b/terraform/application/config/review.tfvars.json index 39f0b0d215..496c0b3474 100644 --- a/terraform/application/config/review.tfvars.json +++ b/terraform/application/config/review.tfvars.json @@ -5,5 +5,6 @@ "deploy_azure_backing_services": false, "enable_postgres_ssl": false, "startup_command": ["/bin/sh", "-c", "bin/rails server -b 0.0.0.0"], - "worker_command": ["/bin/sh", "-c", "bin/bundle exec bin/delayed_job run -n 4"] + "worker_command": ["/bin/sh", "-c", "bin/bundle exec bin/delayed_job run -n 1"], + "enable_logit": true } diff --git a/terraform/application/config/review_app_env.yml b/terraform/application/config/review_app_env.yml index 1376e72ede..0c3804dd1c 100644 --- a/terraform/application/config/review_app_env.yml +++ b/terraform/application/config/review_app_env.yml @@ -19,3 +19,4 @@ SUPPRESS_DFE_ANALYTICS_INIT: true TID_SIGN_IN_API_ENDPOINT: https://preprod.teaching-identity.education.gov.uk:433 TID_SIGN_IN_CLIENT_ID: claim TID_SIGN_IN_ISSUER: https://preprod.teaching-identity.education.gov.uk/ +TID_BASE_URL: https://claim-additional-payments-for-teaching-review-*.test.teacherservices.cloud/additional-payments/claim diff --git a/terraform/application/config/test.tfvars.json b/terraform/application/config/test.tfvars.json index 31970e11c3..2549db46f7 100644 --- a/terraform/application/config/test.tfvars.json +++ b/terraform/application/config/test.tfvars.json @@ -3,8 +3,12 @@ "namespace": "srtl-test", "config": "test", "environment": "test", - "canonical_hostname": "claim-additional-payments-for-teaching-test-web.test.teacherservices.cloud", + "canonical_hostname": "test.claim-additional-teaching-payment.service.gov.uk", "web_replicas": 2, "startup_command": ["/bin/sh", "-c", "bin/rails server -b 0.0.0.0"], - "worker_command": ["/bin/sh", "-c", "bin/bundle exec bin/delayed_job run -n 1"] + "worker_command": ["/bin/sh", "-c", "bin/bundle exec bin/delayed_job run -n 1"], + "enable_monitoring": true, + "statuscake_contact_groups": [195955, 282453], + "external_url": "https://test.claim-additional-teaching-payment.service.gov.uk/healthcheck", + "enable_logit": true } diff --git a/terraform/application/config/test_app_env.yml b/terraform/application/config/test_app_env.yml index 395608fa0f..6d52c73112 100644 --- a/terraform/application/config/test_app_env.yml +++ b/terraform/application/config/test_app_env.yml @@ -3,6 +3,7 @@ DFE_SIGN_IN_API_CLIENT_ID: teacherpayments DFE_SIGN_IN_API_ENDPOINT: https://test-api.signin.education.gov.uk/ DFE_SIGN_IN_IDENTIFIER: teacherpayments DFE_SIGN_IN_ISSUER: https://test-oidc.signin.education.gov.uk:443 +DFE_SIGN_IN_REDIRECT_BASE_URL: https://test.claim-additional-teaching-payment.service.gov.uk DQT_API_URL: https://test.teacher-qualifications-api.education.gov.uk/v1 DQT_BASE_URL: https://test-api-customerengagement.platform.education.gov.uk/dqt-crm/v1/ @@ -14,6 +15,7 @@ ORDNANCE_SURVEY_API_BASE_URL: https://api.os.uk SUPPRESS_DFE_ANALYTICS_INIT: true +TID_BASE_URL: https://test.claim-additional-teaching-payment.service.gov.uk/additional-payments/claim TID_SIGN_IN_API_ENDPOINT: https://preprod.teaching-identity.education.gov.uk:433 TID_SIGN_IN_CLIENT_ID: claim TID_SIGN_IN_ISSUER: https://preprod.teaching-identity.education.gov.uk/ diff --git a/terraform/application/database.tf b/terraform/application/database.tf index 957b6c2b82..1d363336c1 100644 --- a/terraform/application/database.tf +++ b/terraform/application/database.tf @@ -1,16 +1,19 @@ module "postgres" { source = "./vendor/modules/aks//aks/postgres" - namespace = var.namespace - environment = var.environment - azure_resource_prefix = var.azure_resource_prefix - service_name = var.service_name - service_short = var.service_short - config_short = var.config_short - cluster_configuration_map = module.cluster_data.configuration_map - use_azure = var.deploy_azure_backing_services - azure_enable_monitoring = var.enable_monitoring - azure_enable_backup_storage = var.enable_postgres_backup_storage - azure_extensions = ["pg_trgm", "pgcrypto", "plpgsql"] - server_version = "16" + namespace = var.namespace + environment = var.environment + azure_resource_prefix = var.azure_resource_prefix + service_name = var.service_name + service_short = var.service_short + config_short = var.config_short + cluster_configuration_map = module.cluster_data.configuration_map + use_azure = var.deploy_azure_backing_services + azure_enable_monitoring = var.enable_monitoring + azure_enable_backup_storage = var.enable_postgres_backup_storage + azure_extensions = ["pg_trgm", "pgcrypto", "plpgsql"] + server_version = "16" + azure_sku_name = var.postgres_flexible_server_sku + azure_enable_high_availability = var.postgres_enable_high_availability + azure_maintenance_window = var.azure_maintenance_window } diff --git a/terraform/application/statuscake.tf b/terraform/application/statuscake.tf index 840f7a8ad6..be1b3f03ef 100644 --- a/terraform/application/statuscake.tf +++ b/terraform/application/statuscake.tf @@ -1,12 +1,10 @@ -# TODO: Uncomment when needed then follow these steps: https://github.com/DFE-Digital/teacher-services-cloud/blob/main/documentation/onboard-service.md#configure-statuscake-credentials +module "statuscake" { + count = var.enable_monitoring ? 1 : 0 -# module "statuscake" { -# count = var.enable_monitoring ? 1 : 0 + source = "./vendor/modules/aks//monitoring/statuscake" -# source = "./vendor/modules/aks//monitoring/statuscake" + uptime_urls = compact([module.web_application.probe_url, var.external_url]) + ssl_urls = compact([var.external_url]) -# uptime_urls = compact([module.web_application.probe_url, var.external_url]) -# ssl_urls = compact([var.external_url]) - -# contact_groups = var.statuscake_contact_groups -# } + contact_groups = var.statuscake_contact_groups +} diff --git a/terraform/application/variables.tf b/terraform/application/variables.tf index d2e6ae8677..4453323375 100644 --- a/terraform/application/variables.tf +++ b/terraform/application/variables.tf @@ -62,12 +62,31 @@ variable "canonical_hostname" { } variable "web_replicas" { description = "Number of replicas of the web app" - default = 1 + default = 1 +} +variable "worker_replicas" { + description = "Number of replicas of the worker" + default = 1 +} +variable "azure_maintenance_window" { + default = null +} +variable "postgres_flexible_server_sku" { + default = "B_Standard_B1ms" +} +variable "postgres_enable_high_availability" { + default = false +} +variable "enable_logit" { + type = bool + default = false + description = "A boolean to indicate whether to enable sending container logs to logit.io" + nullable = false } locals { - postgres_ssl_mode = var.enable_postgres_ssl ? "require" : "disable" - canonical_hostname = var.canonical_hostname != null ? var.canonical_hostname : "${var.service_name}-${var.environment}-web.test.teacherservices.cloud" + postgres_ssl_mode = var.enable_postgres_ssl ? "require" : "disable" + canonical_hostname = var.canonical_hostname != null ? var.canonical_hostname : "${var.service_name}-${var.environment}-web.test.teacherservices.cloud" app_env_values_from_yml = yamldecode(file("${path.module}/config/${var.config}_app_env.yml")) - app_env_values = merge(local.app_env_values_from_yml) + app_env_values = merge(local.app_env_values_from_yml) } diff --git a/terraform/domains/environment_domains/config/production.tfvars.json b/terraform/domains/environment_domains/config/production.tfvars.json index b752b31c6d..af1d6fcfe0 100644 --- a/terraform/domains/environment_domains/config/production.tfvars.json +++ b/terraform/domains/environment_domains/config/production.tfvars.json @@ -11,7 +11,7 @@ "/assets/*" ], "environment_short": "pd", - "origin_hostname": "s118p01-app-as.azurewebsites.net", + "origin_hostname": "claim-additional-payments-for-teaching-production-web.teacherservices.cloud", "redirect_rules": [{ "from-domain": "apex", "to-domain": "www.claim-additional-teaching-payment.service.gov.uk" diff --git a/terraform/domains/environment_domains/config/test.tfvars.json b/terraform/domains/environment_domains/config/test.tfvars.json index 80327c3c91..9d3590b839 100644 --- a/terraform/domains/environment_domains/config/test.tfvars.json +++ b/terraform/domains/environment_domains/config/test.tfvars.json @@ -10,7 +10,7 @@ "/assets/*" ], "environment_short": "ts", - "origin_hostname": "s118t01-app-as.azurewebsites.net" + "origin_hostname": "claim-additional-payments-for-teaching-test-web.test.teacherservices.cloud" } } } diff --git a/yarn.lock b/yarn.lock index 059a348176..ff1ad66687 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,7 +24,7 @@ govuk-frontend@^5.4.0: resolved "https://registry.yarnpkg.com/govuk-frontend/-/govuk-frontend-5.4.0.tgz#8f2e0b55ef7c7552a1efe68c7b40ff1b4a393e72" integrity sha512-F3YwQYrYQqIPfNxsoph6O78Ey1unCB6cy6omx8KeWY9G504lWZFBSIaiUCma1jNLw9bOUU7Ui+tXG09jjqy0Mw== -prettier@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.2.tgz#03ff86dc7c835f2d2559ee76876a3914cec4a90a" - integrity sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA== +prettier@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" + integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==