diff --git a/README.md b/README.md index 844ffa88d..5af61d33e 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,12 @@ 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. + +## API documentation + +API documentation can be found here: https://communitiesuk.github.io/mhclg-data-collection-beta/. This is driven by [OpenAPI docs](docs/api/DLUHC-CORE-Data.v1.json) + + ## Required Setup Pre-requisites: diff --git a/app/controllers/case_logs_controller.rb b/app/controllers/case_logs_controller.rb index f3753058e..85f1ae1b1 100644 --- a/app/controllers/case_logs_controller.rb +++ b/app/controllers/case_logs_controller.rb @@ -33,9 +33,18 @@ class CaseLogsController < ApplicationController end end - # We don't have a dedicated non-editable show view def show - edit + respond_to do |format| + # We don't have a dedicated non-editable show view + format.html { edit } + format.json do + if (case_log = CaseLog.find_by(id: params[:id])) + render json: case_log, status: :ok + else + render json: { error: "Case Log #{params[:id]} not found" }, status: :not_found + end + end + end end def edit @@ -90,7 +99,7 @@ class CaseLogsController < ApplicationController private - API_ACTIONS = %w[create update destroy].freeze + API_ACTIONS = %w[create show update destroy].freeze def question_responses(questions_for_page) questions_for_page.each_with_object({}) do |(question_key, question_info), result| diff --git a/app/models/case_log.rb b/app/models/case_log.rb index 5a390976b..991745b83 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -28,6 +28,16 @@ class CaseLogValidator < ActiveModel::Validator end end end + + def validate_other_reason_for_leaving_last_settled_home(record) + if record.reason_for_leaving_last_settled_home == "Other" && record.other_reason_for_leaving_last_settled_home.blank? + record.errors.add :other_reason_for_leaving_last_settled_home, "If reason for leaving settled home is other then the other reason must be provided" + end + + if record.reason_for_leaving_last_settled_home != "Other" && record.other_reason_for_leaving_last_settled_home.present? + record.errors.add :other_reason_for_leaving_last_settled_home, "The other reason must not be provided if the reason for leaving settled home was not other" + end + end def validate(record) # If we've come from the form UI we only want to validate the specific fields @@ -103,6 +113,14 @@ private end def mandatory_fields - attributes.except(*AUTOGENERATED_FIELDS) + required = attributes.except(*AUTOGENERATED_FIELDS) + + dynamically_not_required = [] + + if reason_for_leaving_last_settled_home != "Other" + dynamically_not_required << "other_reason_for_leaving_last_settled_home" + end + + required.delete_if { |key, _value| dynamically_not_required.include?(key) } end end diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 8bed823cf..47378e9f0 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -31,7 +31,7 @@ "hint_text": "", "type": "numeric", "min": 0, - "max": 150, + "max": 120, "step": 1 } } diff --git a/db/migrate/20211015090040_update_property_number_of_times_relet_type.rb b/db/migrate/20211015090040_update_property_number_of_times_relet_type.rb index cf4958044..5fa030571 100644 --- a/db/migrate/20211015090040_update_property_number_of_times_relet_type.rb +++ b/db/migrate/20211015090040_update_property_number_of_times_relet_type.rb @@ -1,6 +1,9 @@ class UpdatePropertyNumberOfTimesReletType < ActiveRecord::Migration[6.1] - def change - remove_column :case_logs, :property_number_of_times_relet, :string - add_column :case_logs, :property_number_of_times_relet, :integer + def up + change_column :case_logs, :property_number_of_times_relet, "integer USING CAST(property_number_of_times_relet AS integer)" + end + + def down + change_column :case_logs, :property_number_of_times_relet, :string end end diff --git a/doc/adr/adr-001-initial-architecture-decisions.md b/docs/adr/adr-001-initial-architecture-decisions.md similarity index 100% rename from doc/adr/adr-001-initial-architecture-decisions.md rename to docs/adr/adr-001-initial-architecture-decisions.md diff --git a/doc/adr/adr-002-repositories.md b/docs/adr/adr-002-repositories.md similarity index 100% rename from doc/adr/adr-002-repositories.md rename to docs/adr/adr-002-repositories.md diff --git a/doc/adr/adr-003-form-submission-flow.md b/docs/adr/adr-003-form-submission-flow.md similarity index 100% rename from doc/adr/adr-003-form-submission-flow.md rename to docs/adr/adr-003-form-submission-flow.md diff --git a/doc/adr/adr-004-gov-paas.md b/docs/adr/adr-004-gov-paas.md similarity index 100% rename from doc/adr/adr-004-gov-paas.md rename to docs/adr/adr-004-gov-paas.md diff --git a/doc/adr/adr-005-form-definition.md b/docs/adr/adr-005-form-definition.md similarity index 100% rename from doc/adr/adr-005-form-definition.md rename to docs/adr/adr-005-form-definition.md diff --git a/doc/adr/adr-006-saving-values.md b/docs/adr/adr-006-saving-values.md similarity index 100% rename from doc/adr/adr-006-saving-values.md rename to docs/adr/adr-006-saving-values.md diff --git a/doc/adr/adr-007-data-validations.md b/docs/adr/adr-007-data-validations.md similarity index 100% rename from doc/adr/adr-007-data-validations.md rename to docs/adr/adr-007-data-validations.md diff --git a/docs/api/DLUHC-CORE-Data.v1.json b/docs/api/DLUHC-CORE-Data.v1.json new file mode 100644 index 000000000..8a2b02fc7 --- /dev/null +++ b/docs/api/DLUHC-CORE-Data.v1.json @@ -0,0 +1,1154 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "DLUHC CORE Data", + "version": "1.0", + "description": "Submit or Update CORE Case Log Data on Lettings and Sales of Social Housing in England" + }, + "servers": [ + { + "url": "https://dluhc-core.london.cloudapps.digital", + "description": "Sandbox" + } + ], + "paths": { + "/case_logs/:id": { + "parameters": [], + "get": { + "summary": "Get Case Log Info by Case Log ID", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Case-Log" + }, + "examples": {} + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": {} + }, + "examples": { + "Not found": { + "value": { + "error": "Case Log 67 not found" + } + } + } + } + } + } + }, + "operationId": "get-case_logs-case_logs-:id", + "description": "Retrieve data for a specific case log", + "parameters": [ + { + "schema": { + "type": "string", + "enum": [ + "application/json" + ] + }, + "in": "header", + "name": "Accept", + "required": true + } + ] + }, + "patch": { + "summary": "Update Case Log Information", + "operationId": "patch-case_logs-case_logs-:id", + "responses": { + "200": { + "description": "Case Log Updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Case-Log" + }, + "examples": {} + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": {} + }, + "examples": { + "Not found": { + "value": { + "error": "Case Log 67 not found" + } + } + } + } + } + }, + "422": { + "description": "Unprocessable Entity ", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": {} + }, + "examples": { + "Invalid Age": { + "value": { + "errors": [ + "Tenant age must be between 0 and 120" + ] + } + } + } + } + } + } + }, + "description": "Update the information of an existing case log", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Case-Log" + }, + "examples": {} + } + }, + "description": "Patch case log properties to update." + }, + "parameters": [ + { + "schema": { + "type": "string", + "enum": [ + "application/json" + ] + }, + "in": "header", + "name": "Accept", + "required": true + } + ] + }, + "delete": { + "summary": "Delete a Case Log by Case Log ID", + "operationId": "delete-case_logs-:id", + "responses": { + "204": { + "description": "No Content" + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": {} + }, + "examples": { + "Not found": { + "value": { + "error": "Case Log 67 not found" + } + } + } + } + } + } + }, + "description": "Delete a case log", + "parameters": [ + { + "schema": { + "type": "string", + "enum": [ + "application/json" + ] + }, + "in": "header", + "name": "Accept", + "required": true + } + ] + } + }, + "/case_logs": { + "post": { + "summary": "Create New Case Log", + "operationId": "post-caselog", + "responses": { + "200": { + "description": "Case Log Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Case-Log" + }, + "examples": {} + } + } + }, + "422": { + "description": "Unprocessable Entity ", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": {} + }, + "examples": { + "Invalid Age": { + "value": { + "errors": [ + "Tenant age must be between 0 and 120" + ] + } + } + } + } + } + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Case-Log" + }, + "examples": {} + } + }, + "description": "Post the necessary fields for the API to create a new case log." + }, + "description": "Create a new case log.", + "parameters": [ + { + "schema": { + "type": "string", + "pattern": "application/json", + "enum": [ + "application/json" + ] + }, + "in": "header", + "name": "Accept", + "required": true + } + ] + }, + "parameters": [] + } + }, + "components": { + "schemas": { + "Case-Log": { + "description": "", + "type": "object", + "x-examples": { + "example-1": { + "tenant_code": "T657", + "tenant_age": 35, + "tenant_gender": "Female", + "tenant_ethnic_group": "White: English/Scottish/Welsh/Northern Irish/British", + "tenant_nationality": "UK national resident in UK", + "previous_housing_situation": "Private sector tenancy", + "armed_forces": "Yes - a regular", + "tenant_economic_status": "Full-time - 30 hours or more", + "household_number_of_other_members": 7, + "person_2_relationship": "Partner", + "person_2_age": 32, + "person_2_gender": "Male", + "person_2_economic_status": "Not seeking work", + "person_3_relationship": "Child - includes young adult and grown-up", + "person_3_age": 12, + "person_3_gender": "Male", + "person_3_economic_status": "Child under 16", + "person_4_relationship": "Child - includes young adult and grown-up", + "person_4_age": 12, + "person_4_gender": "Female", + "person_4_economic_status": "Child under 16", + "person_5_relationship": "Child - includes young adult and grown-up", + "person_5_age": 10, + "person_5_gender": "Non-binary", + "person_5_economic_status": "Child under 16", + "person_6_relationship": "Child - includes young adult and grown-up", + "person_6_age": 5, + "person_6_gender": "Prefer not to say", + "person_6_economic_status": "Child under 16", + "person_7_relationship": "Child - includes young adult and grown-up", + "person_7_age": 5, + "person_7_gender": "Prefer not to say", + "person_7_economic_status": "Child under 16", + "person_8_relationship": "Child - includes young adult and grown-up", + "person_8_age": 2, + "person_8_gender": "Prefer not to say", + "person_8_economic_status": "Child under 16", + "homelessness": "No", + "reason_for_leaving_last_settled_home": "Other problems with neighbours", + "benefit_cap_spare_room_subsidy": "No", + "armed_forces_active": "No", + "armed_forces_injured": "No", + "armed_forces_partner": "No", + "medical_conditions": "Yes", + "pregnancy": "No", + "accessibility_requirements": "No", + "condition_effects": "dummy", + "tenancy_code": "BZ757", + "tenancy_start_date": "12/03/2019", + "starter_tenancy": "No", + "fixed_term_tenancy": "No", + "tenancy_type": "Fixed term – Secure", + "letting_type": "Affordable Rent - General Needs", + "letting_provider": "This landlord", + "property_location": "Barnet", + "previous_postcode": "NW1 5TY", + "property_relet": "No", + "property_vacancy_reason": "Relet - tenant abandoned property", + "property_reference": "P9876", + "property_unit_type": "House", + "property_building_type": "dummy", + "property_number_of_bedrooms": 3, + "property_void_date": "03/11/2019", + "property_major_repairs": "Yes", + "property_major_repairs_date": "05/05/2020", + "property_number_of_times_relet": 2, + "property_wheelchair_accessible": true, + "net_income": 1000, + "net_income_frequency": "Monthly", + "net_income_uc_proportion": "Some", + "housing_benefit": "Universal Credit with housing element, but not Housing Benefit", + "rent_frequency": "Weekly", + "basic_rent": 200, + "service_charge": 50, + "personal_service_charge": 40, + "support_charge": 35, + "total_charge": 325, + "outstanding_amount": "Yes", + "time_lived_in_la": "1 to 2 years", + "time_on_la_waiting_list": "Less than 1 year", + "previous_la": "Ashford", + "property_postcode": "SE2 6RT", + "reasonable_preference": "Yes", + "reasonable_preference_reason": "dummy", + "cbl_letting": true, + "chr_letting": false, + "cap_letting": false, + "outstanding_rent_or_charges": 25, + "other_reason_for_leaving_last_settled_home": "Other reason", + "accessibility_requirements_fully_wheelchair_accessible_housing": true, + "accessibility_requirements_wheelchair_access_to_essential_rooms": false, + "accessibility_requirements_level_access_housing": false, + "accessibility_requirements_other_disability_requirements": false, + "accessibility_requirements_no_disability_requirements": false, + "accessibility_requirements_do_not_know": false, + "accessibility_requirements_prefer_not_to_say": false, + "condition_effects_vision": false, + "condition_effects_hearing": true, + "condition_effects_mobility": false, + "condition_effects_dexterity": false, + "condition_effects_stamina": false, + "condition_effects_learning": false, + "condition_effects_memory": false, + "condition_effects_mental_health": false, + "condition_effects_social_or_behavioral": false, + "condition_effects_other": false, + "condition_effects_prefer_not_to_say": false, + "reasonable_preference_reason_homeless": false, + "reasonable_preference_reason_unsatisfactory_housing": false, + "reasonable_preference_reason_medical_grounds": false, + "reasonable_preference_reason_avoid_hardship": false, + "reasonable_preference_reason_do_not_know": true + } + }, + "title": "Case Log", + "x-internal": false, + "properties": { + "tenant_code": { + "type": "string", + "minLength": 1 + }, + "tenant_age": { + "type": "number", + "description": "The age of the lead tenant", + "maximum": 120, + "minimum": 0 + }, + "tenant_gender": { + "type": "string", + "minLength": 1, + "enum": [ + "Female", + "Male", + "Non-binary", + "Prefer not to say" + ] + }, + "tenant_ethnic_group": { + "type": "string", + "minLength": 1, + "enum": [ + "White: English/Scottish/Welsh/Northern Irish/British", + "White: Irish", + "White: Gypsy/Irish Traveller", + "White: Other", + "Mixed: White & Black Caribbean", + "Mixed: White & Black African", + "Mixed: White & Asian", + "Mixed: Other", + "Asian or Asian British: Indian", + "Asian or Asian British: Pakistani", + "Asian or Asian British: Bangladeshi", + "Asian or Asian British: Chinese", + "Asian or Asian British: Other", + "Black: Caribbean", + "Black: African", + "Black: Other", + "Other Ethnic Group: Arab", + "Other Ethnic Group: Other", + "Prefer not to say" + ] + }, + "tenant_nationality": { + "type": "string", + "minLength": 1, + "enum": [ + "UK national resident in UK", + "A current or former reserve in the UK Armed Forces (exc. National Service)", + "UK national returning from residence overseas", + "Czech Republic", + "Estonia", + "Hungary", + "Latvia", + "Lithuania", + "Poland", + "Slovakia", + "Bulgaria", + "Romania", + "Ireland", + "Other EU Economic Area (EEA country)", + "Any other country", + "Prefer not to say" + ] + }, + "previous_housing_situation": { + "type": "string", + "minLength": 1 + }, + "armed_forces": { + "type": "string", + "minLength": 1 + }, + "tenant_economic_status": { + "type": "string", + "minLength": 1, + "enum": [ + "Part-time - Less than 30 hours", + "Full-time - 30 hours or more", + "In government training into work, such as New Deal", + "Jobseeker", + "Retired", + "Not seeking work", + "Full-time student", + "Unable to work because of long term sick or disability", + "Child under 16", + "Other", + "Prefer not to say" + ] + }, + "household_number_of_other_members": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "person_2_relationship": { + "type": "string", + "minLength": 1, + "enum": [ + "Partner", + "Child - includes young adult and grown-up", + "Other", + "Prefer not to say" + ] + }, + "person_2_age": { + "type": "number", + "maximum": 120, + "minimum": 0 + }, + "person_2_gender": { + "type": "string", + "minLength": 1, + "enum": [ + "Female", + "Male", + "Non-binary", + "Prefer not to say" + ] + }, + "person_2_economic_status": { + "type": "string", + "minLength": 1, + "enum": [ + "Part-time - Less than 30 hours", + "Full-time - 30 hours or more", + "In government training into work, such as New Deal", + "Jobseeker", + "Retired", + "Not seeking work", + "Full-time student", + "Unable to work because of long term sick or disability", + "Child under 16", + "Other", + "Prefer not to say" + ] + }, + "person_3_relationship": { + "type": "string", + "minLength": 1, + "enum": [ + "Partner", + "Child - includes young adult and grown-up", + "Other", + "Prefer not to say" + ] + }, + "person_3_age": { + "type": "number", + "maximum": 120, + "minimum": 0 + }, + "person_3_gender": { + "type": "string", + "minLength": 1, + "enum": [ + "Female", + "Male", + "Non-binary", + "Prefer not to say" + ] + }, + "person_3_economic_status": { + "type": "string", + "minLength": 1, + "enum": [ + "Part-time - Less than 30 hours", + "Full-time - 30 hours or more", + "In government training into work, such as New Deal", + "Jobseeker", + "Retired", + "Not seeking work", + "Full-time student", + "Unable to work because of long term sick or disability", + "Child under 16", + "Other", + "Prefer not to say" + ] + }, + "person_4_relationship": { + "type": "string", + "minLength": 1, + "enum": [ + "Partner", + "Child - includes young adult and grown-up", + "Other", + "Prefer not to say" + ] + }, + "person_4_age": { + "type": "number", + "maximum": 120, + "minimum": 0 + }, + "person_4_gender": { + "type": "string", + "minLength": 1, + "enum": [ + "Female", + "Male", + "Non-binary", + "Prefer not to say" + ] + }, + "person_4_economic_status": { + "type": "string", + "minLength": 1, + "enum": [ + "Part-time - Less than 30 hours", + "Full-time - 30 hours or more", + "In government training into work, such as New Deal", + "Jobseeker", + "Retired", + "Not seeking work", + "Full-time student", + "Unable to work because of long term sick or disability", + "Child under 16", + "Other", + "Prefer not to say" + ] + }, + "person_5_relationship": { + "type": "string", + "minLength": 1, + "enum": [ + "Partner", + "Child - includes young adult and grown-up", + "Other", + "Prefer not to say" + ] + }, + "person_5_age": { + "type": "number", + "maximum": 120, + "minimum": 0 + }, + "person_5_gender": { + "type": "string", + "minLength": 1, + "enum": [ + "Female", + "Male", + "Non-binary", + "Prefer not to say" + ] + }, + "person_5_economic_status": { + "type": "string", + "minLength": 1, + "enum": [ + "Part-time - Less than 30 hours", + "Full-time - 30 hours or more", + "In government training into work, such as New Deal", + "Jobseeker", + "Retired", + "Not seeking work", + "Full-time student", + "Unable to work because of long term sick or disability", + "Child under 16", + "Other", + "Prefer not to say" + ] + }, + "person_6_relationship": { + "type": "string", + "minLength": 1, + "enum": [ + "Partner", + "Child - includes young adult and grown-up", + "Other", + "Prefer not to say" + ] + }, + "person_6_age": { + "type": "number", + "maximum": 120, + "minimum": 0 + }, + "person_6_gender": { + "type": "string", + "minLength": 1, + "enum": [ + "Female", + "Male", + "Non-binary", + "Prefer not to say" + ] + }, + "person_6_economic_status": { + "type": "string", + "minLength": 1, + "enum": [ + "Part-time - Less than 30 hours", + "Full-time - 30 hours or more", + "In government training into work, such as New Deal", + "Jobseeker", + "Retired", + "Not seeking work", + "Full-time student", + "Unable to work because of long term sick or disability", + "Child under 16", + "Other", + "Prefer not to say" + ] + }, + "person_7_relationship": { + "type": "string", + "minLength": 1, + "enum": [ + "Partner", + "Child - includes young adult and grown-up", + "Other", + "Prefer not to say" + ] + }, + "person_7_age": { + "type": "number", + "maximum": 120, + "minimum": 0 + }, + "person_7_gender": { + "type": "string", + "minLength": 1, + "enum": [ + "Female", + "Male", + "Non-binary", + "Prefer not to say" + ] + }, + "person_7_economic_status": { + "type": "string", + "minLength": 1, + "enum": [ + "Part-time - Less than 30 hours", + "Full-time - 30 hours or more", + "In government training into work, such as New Deal", + "Jobseeker", + "Retired", + "Not seeking work", + "Full-time student", + "Unable to work because of long term sick or disability", + "Child under 16", + "Other", + "Prefer not to say" + ] + }, + "person_8_relationship": { + "type": "string", + "minLength": 1, + "enum": [ + "Partner", + "Child - includes young adult and grown-up", + "Other", + "Prefer not to say" + ] + }, + "person_8_age": { + "type": "number", + "maximum": 120, + "minimum": 0 + }, + "person_8_gender": { + "type": "string", + "minLength": 1, + "enum": [ + "Female", + "Male", + "Non-binary", + "Prefer not to say" + ] + }, + "person_8_economic_status": { + "type": "string", + "minLength": 1, + "enum": [ + "Part-time - Less than 30 hours", + "Full-time - 30 hours or more", + "In government training into work, such as New Deal", + "Jobseeker", + "Retired", + "Not seeking work", + "Full-time student", + "Unable to work because of long term sick or disability", + "Child under 16", + "Other", + "Prefer not to say" + ] + }, + "homelessness": { + "type": "string", + "minLength": 1 + }, + "reason_for_leaving_last_settled_home": { + "type": "string", + "minLength": 1 + }, + "benefit_cap_spare_room_subsidy": { + "type": "string", + "minLength": 1 + }, + "armed_forces_active": { + "type": "string", + "minLength": 1 + }, + "armed_forces_injured": { + "type": "string", + "minLength": 1 + }, + "armed_forces_partner": { + "type": "string", + "minLength": 1 + }, + "medical_conditions": { + "type": "string", + "minLength": 1 + }, + "pregnancy": { + "type": "string", + "minLength": 1 + }, + "accessibility_requirements": { + "type": "string", + "minLength": 1 + }, + "condition_effects": { + "type": "string", + "minLength": 1 + }, + "tenancy_code": { + "type": "string", + "minLength": 1 + }, + "tenancy_start_date": { + "type": "string", + "minLength": 1 + }, + "starter_tenancy": { + "type": "string", + "minLength": 1 + }, + "fixed_term_tenancy": { + "type": "string", + "minLength": 1 + }, + "tenancy_type": { + "type": "string", + "minLength": 1 + }, + "letting_type": { + "type": "string", + "minLength": 1 + }, + "letting_provider": { + "type": "string", + "minLength": 1 + }, + "property_location": { + "type": "string", + "minLength": 1 + }, + "previous_postcode": { + "type": "string", + "minLength": 1 + }, + "property_relet": { + "type": "string", + "minLength": 1 + }, + "property_vacancy_reason": { + "type": "string", + "minLength": 1 + }, + "property_reference": { + "type": "string", + "minLength": 1 + }, + "property_unit_type": { + "type": "string", + "minLength": 1 + }, + "property_building_type": { + "type": "string", + "minLength": 1 + }, + "property_number_of_bedrooms": { + "type": "number" + }, + "property_void_date": { + "type": "string", + "minLength": 1 + }, + "property_major_repairs": { + "type": "string", + "minLength": 1 + }, + "property_major_repairs_date": { + "type": "string", + "minLength": 1 + }, + "property_number_of_times_relet": { + "type": "number" + }, + "property_wheelchair_accessible": { + "type": "boolean" + }, + "net_income": { + "type": "number" + }, + "net_income_frequency": { + "type": "string", + "minLength": 1 + }, + "net_income_uc_proportion": { + "type": "string", + "minLength": 1 + }, + "housing_benefit": { + "type": "string", + "minLength": 1 + }, + "rent_frequency": { + "type": "string", + "minLength": 1 + }, + "basic_rent": { + "type": "number" + }, + "service_charge": { + "type": "number" + }, + "personal_service_charge": { + "type": "number" + }, + "support_charge": { + "type": "number" + }, + "total_charge": { + "type": "number" + }, + "outstanding_amount": { + "type": "string", + "minLength": 1 + }, + "time_lived_in_la": { + "type": "string", + "minLength": 1 + }, + "time_on_la_waiting_list": { + "type": "string", + "minLength": 1 + }, + "previous_la": { + "type": "string", + "minLength": 1 + }, + "property_postcode": { + "type": "string", + "minLength": 1 + }, + "reasonable_preference": { + "type": "string", + "minLength": 1 + }, + "reasonable_preference_reason": { + "type": "string", + "minLength": 1 + }, + "cbl_letting": { + "type": "boolean" + }, + "chr_letting": { + "type": "boolean" + }, + "cap_letting": { + "type": "boolean" + }, + "outstanding_rent_or_charges": { + "type": "number" + }, + "other_reason_for_leaving_last_settled_home": { + "type": "string", + "minLength": 1 + }, + "accessibility_requirements_fully_wheelchair_accessible_housing": { + "type": "boolean" + }, + "accessibility_requirements_wheelchair_access_to_essential_rooms": { + "type": "boolean" + }, + "accessibility_requirements_level_access_housing": { + "type": "boolean" + }, + "accessibility_requirements_other_disability_requirements": { + "type": "boolean" + }, + "accessibility_requirements_no_disability_requirements": { + "type": "boolean" + }, + "accessibility_requirements_do_not_know": { + "type": "boolean" + }, + "accessibility_requirements_prefer_not_to_say": { + "type": "boolean" + }, + "condition_effects_vision": { + "type": "boolean" + }, + "condition_effects_hearing": { + "type": "boolean" + }, + "condition_effects_mobility": { + "type": "boolean" + }, + "condition_effects_dexterity": { + "type": "boolean" + }, + "condition_effects_stamina": { + "type": "boolean" + }, + "condition_effects_learning": { + "type": "boolean" + }, + "condition_effects_memory": { + "type": "boolean" + }, + "condition_effects_mental_health": { + "type": "boolean" + }, + "condition_effects_social_or_behavioral": { + "type": "boolean" + }, + "condition_effects_other": { + "type": "boolean" + }, + "condition_effects_prefer_not_to_say": { + "type": "boolean" + }, + "reasonable_preference_reason_homeless": { + "type": "boolean" + }, + "reasonable_preference_reason_unsatisfactory_housing": { + "type": "boolean" + }, + "reasonable_preference_reason_medical_grounds": { + "type": "boolean" + }, + "reasonable_preference_reason_avoid_hardship": { + "type": "boolean" + }, + "reasonable_preference_reason_do_not_know": { + "type": "boolean" + } + }, + "required": [ + "tenant_code", + "tenant_age", + "tenant_gender", + "tenant_ethnic_group", + "tenant_nationality", + "previous_housing_situation", + "armed_forces", + "tenant_economic_status", + "household_number_of_other_members", + "person_2_relationship", + "person_2_age", + "person_2_gender", + "person_2_economic_status", + "person_3_relationship", + "person_3_age", + "person_3_gender", + "person_3_economic_status", + "person_4_relationship", + "person_4_age", + "person_4_gender", + "person_4_economic_status", + "person_5_relationship", + "person_5_age", + "person_5_gender", + "person_5_economic_status", + "person_6_relationship", + "person_6_age", + "person_6_gender", + "person_6_economic_status", + "person_7_relationship", + "person_7_age", + "person_7_gender", + "person_7_economic_status", + "person_8_relationship", + "person_8_age", + "person_8_gender", + "person_8_economic_status", + "homelessness", + "reason_for_leaving_last_settled_home", + "benefit_cap_spare_room_subsidy", + "armed_forces_active", + "armed_forces_injured", + "armed_forces_partner", + "medical_conditions", + "pregnancy", + "accessibility_requirements", + "condition_effects", + "tenancy_code", + "tenancy_start_date", + "starter_tenancy", + "fixed_term_tenancy", + "tenancy_type", + "letting_type", + "letting_provider", + "property_location", + "previous_postcode", + "property_relet", + "property_vacancy_reason", + "property_reference", + "property_unit_type", + "property_building_type", + "property_number_of_bedrooms", + "property_void_date", + "property_major_repairs", + "property_major_repairs_date", + "property_number_of_times_relet", + "property_wheelchair_accessible", + "net_income", + "net_income_frequency", + "net_income_uc_proportion", + "housing_benefit", + "rent_frequency", + "basic_rent", + "service_charge", + "personal_service_charge", + "support_charge", + "total_charge", + "outstanding_amount", + "time_lived_in_la", + "time_on_la_waiting_list", + "previous_la", + "property_postcode", + "reasonable_preference", + "reasonable_preference_reason", + "cbl_letting", + "chr_letting", + "cap_letting", + "outstanding_rent_or_charges", + "other_reason_for_leaving_last_settled_home", + "accessibility_requirements_fully_wheelchair_accessible_housing", + "accessibility_requirements_wheelchair_access_to_essential_rooms", + "accessibility_requirements_level_access_housing", + "accessibility_requirements_other_disability_requirements", + "accessibility_requirements_no_disability_requirements", + "accessibility_requirements_do_not_know", + "accessibility_requirements_prefer_not_to_say", + "condition_effects_vision", + "condition_effects_hearing", + "condition_effects_mobility", + "condition_effects_dexterity", + "condition_effects_stamina", + "condition_effects_learning", + "condition_effects_memory", + "condition_effects_mental_health", + "condition_effects_social_or_behavioral", + "condition_effects_other", + "condition_effects_prefer_not_to_say", + "reasonable_preference_reason_homeless", + "reasonable_preference_reason_unsatisfactory_housing", + "reasonable_preference_reason_medical_grounds", + "reasonable_preference_reason_avoid_hardship", + "reasonable_preference_reason_do_not_know" + ] + } + }, + "securitySchemes": {} + } +} diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 000000000..1f0ae16fa --- /dev/null +++ b/docs/index.html @@ -0,0 +1,17 @@ + + + + + + +OpenAPI DLUHC CORE Data Collection +
+ + diff --git a/spec/fixtures/complete_case_log.json b/spec/fixtures/complete_case_log.json index 4cf667b6a..c0aa35be7 100644 --- a/spec/fixtures/complete_case_log.json +++ b/spec/fixtures/complete_case_log.json @@ -89,7 +89,7 @@ "chr_letting": false, "cap_letting": false, "outstanding_rent_or_charges": 25, - "other_reason_for_leaving_last_settled_home": "Other reason", + "other_reason_for_leaving_last_settled_home": null, "accessibility_requirements_fully_wheelchair_accessible_housing": true, "accessibility_requirements_wheelchair_access_to_essential_rooms": false, "accessibility_requirements_level_access_housing": false, diff --git a/spec/models/case_log_spec.rb b/spec/models/case_log_spec.rb index b27b0594e..6b1124241 100644 --- a/spec/models/case_log_spec.rb +++ b/spec/models/case_log_spec.rb @@ -54,7 +54,22 @@ RSpec.describe Form, type: :model do homelessness: "Yes", reasonable_preference: "No", reasonable_preference_reason_homeless: true - ) + ) + }.to raise_error(ActiveRecord::RecordInvalid) + end + end + context "other reason for leaving last settled home validation" do + it "must be provided if main reason for leaving last settled home was given as other" do + expect { + CaseLog.create!(reason_for_leaving_last_settled_home: "Other", + other_reason_for_leaving_last_settled_home: nil) + }.to raise_error(ActiveRecord::RecordInvalid) + end + + it "must not be provided if the main reason for leaving settled home is not other" do + expect { + CaseLog.create!(reason_for_leaving_last_settled_home: "Repossession", + other_reason_for_leaving_last_settled_home: "the other reason provided") }.to raise_error(ActiveRecord::RecordInvalid) end end diff --git a/spec/requests/case_log_controller_spec.rb b/spec/requests/case_log_controller_spec.rb index 9dab538b0..dc67b76e1 100644 --- a/spec/requests/case_log_controller_spec.rb +++ b/spec/requests/case_log_controller_spec.rb @@ -99,6 +99,24 @@ RSpec.describe CaseLogsController, type: :request do end end + describe "GET" do + let(:case_log) { FactoryBot.create(:case_log, :completed) } + let(:id) { case_log.id } + + before do + get "/case_logs/#{id}", headers: headers + end + + it "returns http success" do + expect(response).to have_http_status(:success) + end + + it "returns a serialized Case Log" do + json_response = JSON.parse(response.body) + expect(json_response["status"]).to eq(case_log.status) + end + end + describe "PATCH" do let(:case_log) do FactoryBot.create(:case_log, :in_progress, tenant_code: "Old Value", property_postcode: "Old Value")