From d41156b95cd50f54c6aee148964305cf9b35d8c5 Mon Sep 17 00:00:00 2001 From: Paul Robert Lloyd Date: Wed, 6 Oct 2021 17:38:27 +0100 Subject: [PATCH 1/3] Update README.md Update installation instructions and tweak content --- README.md | 135 +++++++++++++++++++++++++++--------------------------- 1 file changed, 67 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 5902e08a2..5028acab2 100644 --- a/README.md +++ b/README.md @@ -1,116 +1,116 @@ [![CI/CD Pipeline](https://github.com/communitiesuk/mhclg-data-collection-beta/actions/workflows/pipeline.yml/badge.svg?branch=main&event=push)](https://github.com/communitiesuk/mhclg-data-collection-beta/actions/workflows/pipeline.yml) # Data Collection App -This is the codebase for the Ruby/Rails app that will handle the submission of Lettings and Sales of Social Housing in England data. + +This is the codebase for the Ruby on Rails app that will handle the submission of Lettings and Sales of Social Housing in England data. ## Required Setup -Pre-requisites +Pre-requisites: - Ruby - Rails - Postgres +### Quick start -### Setup Quickstart +1. Copy the `.env.example` to `.env` and replace the database credentials with your local postgres user credentials. -Copy the `.env.example` to `.env` and replace the database credentials with your local postgres user credentials. +2. Install the dependencies:\ + `bundle install` -Install the dependencies -`bundle install` +3. Create the database:\ + `rake db:create` -Create the database -`rake db:create` +4. Run the database migrations:\ + `rake db:migrate` -Run the database migrations -`rake db:migrate` +5. Install the frontend depenencies:\ + `yarn install` -Start the rails server -``` -rails s -``` -This starts the rails server on localhost:3000 +6. Start the Rails server:\ + `bundle exec rails s` -or using Docker +The Rails server will start on . -``` +### Using Docker + +```sh docker-compose build docker-compose run --rm app rails db:create docker-compose up ``` -This exposes the rails server on localhost:8080. +The Rails server will start on . -Note docker-compose runs the production docker image (RAILS_ENV=production) as the Dockerfile doesn't include development gems to keep the image size down. +Note `docker-compose` runs the production docker image (`RAILS_ENV=production`) as the Dockerfile doesn’t include development gems to keep the image size down. +## Infrastructure -### Infrastructure +This application is running on [GOV.UK PaaS](https://www.cloud.service.gov.uk/). To deploy you need to: -This application is running on [Gov PaaS](https://www.cloud.service.gov.uk/). To deploy you need to: +1. Contact your organisation manager to get an account in `dluhc-core` organization and in the relevant spaces (sandbox/production). -- Contact your organisation manager to get an account in `dluhc-core` organization and in the relevant spaces (sandbox/production). -- Install the cloudfoundry cli https://docs.cloudfoundry.org/cf-cli/install-go-cli.html +2. [Install the Cloud Foundry CLI](https://docs.cloudfoundry.org/cf-cli/install-go-cli.html) -- Login
+3. Login:\ `cf login -a api.london.cloud.service.gov.uk -u ` -- Set your deployment target (sandbox/production)
+4. Set your deployment target (sandbox/production):\ `cf target -o dluhc-core -s ` -- Deploy
+5. Deploy:\ `cf push dluhc-core --strategy rolling`. This will use the [manifest file](manifest.yml) Once the app is deployed: -- Get a rails console
+1. Get a Rails console:\ `cf ssh dluhc-core -t -c "/tmp/lifecycle/launcher /home/vcap/app 'rails console' ''"` -- Check logs
+2. Check logs:\ `cf logs dluhc-core --recent` +## CI/CD -### CI/CD +When a commit is made to `main` the following GitHub action jobs are triggered: -When a commit is made to `main` the following Github action jobs are triggered: +1. **Test**: RSpec runs our test suite +2. **Deploy**: If the Test stage passes, this job will deploy the app to our GOV.UK PaaS account using the Cloud Foundry CLI -1. Test - RSpec runs our test suite -2. Deploy - If the Test stage passes, this deploys the app to our Gov PaaS account using the cloudfoundry cli +When a pull request is opened to `main` only the Test stage runs. -When a pull request is opened to `main` only the test stage runs. +## Single log submission - -### Single log submission - -The form for this is driven by a json file in `/config/forms/{start_year}_{end_year}.json` +The form for this is driven by a JSON file in `/config/forms/{start_year}_{end_year}.json` The JSON should follow the structure: -``` +```jsonc { - form_type: [lettings/sales] - start_year: yyyy - end_year: yyyy - sections: { - snake case section name string: { - label: string, - subsections: { - snake case subsection name string: { - label: string, - pages: { - snake case page name string: { - header: string, - description: string, - questions: { - snake case question name string: { - header: string, - hint_text: string, - type: [text / numeric / radio / checkbox / date ], - min: integer, (numeric only), - max: integer, (numeric only), - step: integer (numeric only), - answer_options: { (checkbox and radio only) - "0": string, - "1": string + "form_type": "lettings" / "sales", + "start_year": Integer, // i.e. 2020 + "end_year": Integer, // i.e. 2021 + "sections": { + "[snake_case_section_name_string]": { + "label": String, + "subsections": { + "[snake_case_subsection_name_string]": { + "label": String, + "pages": { + "[snake_case_page_name_string]": { + "header": String, + "description": String, + "questions": { + "[snake_case_question_name_string]": { + "header": String, + "hint_text": String, + "type": "text" / "numeric" / "radio" / "checkbox" / "date", + "min": Integer, // numeric only + "max": Integer, // numeric only + "step": Integer, // numeric only + "answer_options": { // checkbox and radio only + "0": String, + "1": String } } } @@ -132,19 +132,18 @@ Assumptions made by the format: - The ActiveRecord case log model has a field for each question name (must match) - Text not required by a page/question such as a header or hint text should be passed as an empty string +## Useful documentation (external dependencies) -### Useful documentation (external dependencies) - -##### DfE Form Builder Gem +### GOV.UK Design System Form Builder for Rails - [Examples](https://govuk-form-builder.netlify.app/) -- [Technical Docs](https://www.rubydoc.info/gems/govuk_design_system_formbuilder/) +- [Technical docs](https://www.rubydoc.info/gems/govuk_design_system_formbuilder/) - [GitHub repository](https://github.com/DFE-Digital/govuk-formbuilder) -##### Alpha Gov UK frontend gem +### GOV.UK Frontend - [GitHub repository](https://github.com/alphagov/govuk-frontend) -##### Hotwire (Turbo/Stimulus) +### Hotwire (Turbo/Stimulus) - [Docs](https://turbo.hotwired.dev/) From 5e201d35534a3f050bd733c14225f6b42fdcdabb Mon Sep 17 00:00:00 2001 From: Daniel Baark <5101747+baarkerlounger@users.noreply.github.com> Date: Thu, 7 Oct 2021 09:16:00 +0100 Subject: [PATCH 2/3] CLDC-344: Validations (#36) * Form with model so that we can validate (hypothetically) * Put turbo frame back * Turbo can update form errors if submitting returns 422 * Refactor and fix specs * String interpolation over concatenation --- Gemfile.lock | 10 ++--- app/controllers/case_logs_controller.rb | 27 ++++++------ app/helpers/conditional_questions_helper.rb | 6 +-- .../conditional_question_controller.js | 2 +- app/models/case_log.rb | 2 + app/models/form.rb | 10 +++++ app/views/form/page.html.erb | 9 ++-- config/routes.rb | 3 +- spec/features/case_log_spec.rb | 42 +++++++++---------- 9 files changed, 58 insertions(+), 53 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1e4ad2c71..b21879881 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,7 +26,7 @@ GIT GIT remote: https://github.com/rspec/rspec-rails.git - revision: 211d7d990e9762e229d8a86249b88c2a7604e8b0 + revision: fdcd1df0b13f9b6547336b4d37dffb66f70f7228 branch: main specs: rspec-rails (5.1.0.pre) @@ -143,7 +143,7 @@ GEM ffi (1.15.4) globalid (0.5.2) activesupport (>= 5.0) - govuk-components (2.1.1) + govuk-components (2.1.2) activemodel (>= 6.0) railties (>= 6.0) view_component (~> 2.39.0) @@ -175,9 +175,9 @@ GEM minitest (5.14.4) msgpack (1.4.2) nio4r (2.5.8) - nokogiri (1.12.4-x86_64-darwin) + nokogiri (1.12.5-x86_64-darwin) racc (~> 1.4) - nokogiri (1.12.4-x86_64-linux) + nokogiri (1.12.5-x86_64-linux) racc (~> 1.4) overcommit (0.58.0) childprocess (>= 0.6.3, < 5) @@ -294,7 +294,7 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - stimulus-rails (0.6.0) + stimulus-rails (0.6.1) rails (>= 6.0.0) thor (1.1.0) turbo-rails (0.8.1) diff --git a/app/controllers/case_logs_controller.rb b/app/controllers/case_logs_controller.rb index d84e6187e..45bc05ee4 100644 --- a/app/controllers/case_logs_controller.rb +++ b/app/controllers/case_logs_controller.rb @@ -20,22 +20,19 @@ class CaseLogsController < ApplicationController render :edit end - def next_page + def submit_form form = Form.new(2021, 2022) - @case_log = CaseLog.find(params[:case_log_id]) - previous_page = params[:previous_page] + @case_log = CaseLog.find(params[:id]) + previous_page = params[:case_log][:previous_page] questions_for_page = form.questions_for_page(previous_page).keys answers_for_page = page_params(questions_for_page).select { |k, _v| questions_for_page.include?(k) } - @case_log.update!(answers_for_page) - next_page = form.next_page(previous_page) - redirect_path = if next_page == :check_answers - subsection = form.subsection_for_page(previous_page) - "case_log_#{subsection}_check_answers_path" - else - "case_log_#{next_page}_path" - end - - redirect_to(send(redirect_path, @case_log)) + if @case_log.update(answers_for_page) + redirect_path = form.next_page_redirect_path(previous_page) + redirect_to(send(redirect_path, @case_log)) + else + page_info = form.all_pages[previous_page] + render "form/page", locals: { form: form, page_key: previous_page, page_info: page_info }, status: :unprocessable_entity + end end def check_answers @@ -51,13 +48,13 @@ class CaseLogsController < ApplicationController form.all_pages.map do |page_key, page_info| define_method(page_key) do @case_log = CaseLog.find(params[:case_log_id]) - render "form/page", locals: { case_log_id: @case_log.id, form: form, page_key: page_key, page_info: page_info } + render "form/page", locals: { form: form, page_key: page_key, page_info: page_info } end end private def page_params(questions_for_page) - params.permit(questions_for_page) + params.require(:case_log).permit(questions_for_page) end end diff --git a/app/helpers/conditional_questions_helper.rb b/app/helpers/conditional_questions_helper.rb index 8967207f4..c77119243 100644 --- a/app/helpers/conditional_questions_helper.rb +++ b/app/helpers/conditional_questions_helper.rb @@ -6,10 +6,6 @@ module ConditionalQuestionsHelper end def display_question_key_div(page_info, question_key) - if conditional_questions_for_page(page_info).include?(question_key) - "